Skip to content

fix(observability): stop reporting degraded and failed states as fine - #216

Merged
CryptoJones merged 1 commit into
mainfrom
fix/surface-degraded-states
Aug 2, 2026
Merged

fix(observability): stop reporting degraded and failed states as fine#216
CryptoJones merged 1 commit into
mainfrom
fix/surface-degraded-states

Conversation

@CryptoJones

Copy link
Copy Markdown
Owner

Items 3, 4 and 6 of 6 — the last of the follow-up batch. Ships in v8.1.0.

All three are the same bug in different clothes: a real problem that doesn't read as one.

1. doctor gave a green tick to degraded search

[✓] semantic search: off (keyword path) — model2vec not importable

Severity ok. But on the 784-note reference vault, turning that leg on moved recall@1 40% → 60% and MRR 0.42 → 0.64. The tick was reporting "your recall is materially worse than it could be" as healthy — the same shape as an index that silently stopped updating (#210). Now [!], naming the fix.

2. compliance.py swallowed errors with nothing to read

Every failure path returned silently so the guard hook can never raise into the agent. Correct — and it made "the compliance log is being written" and "every write has failed for a week" indistinguishable from outside.

That is precisely how #202 hid for a full release: a PermissionError absorbed by a bare except OSError: return. Failures now leave a labelled breadcrumb in the size-capped hook failure log omind doctor already reads. FileNotFoundError on a fresh machine stays silent, because that isn't a failure.

3. The eval set was too small to detect its own blind spot

Five labelled cases means each is worth 20 percentage points. A change genuinely improving recall by 10% could not register — and didn't: #193 scored identically on five cases while individual ranks moved several places underneath. Five cases cannot tell "no effect" from "an effect this instrument cannot see."

Now 30 cases. Method, since an eval set written by the same author who benefits from it is worth scrutinising:

  • authored from note contents, before measuring anything;
  • phrased the way an agent asks ("may I stop when I reach a natural stopping point");
  • deliberately not echoing target title words, so no case is winnable by literal title matching;
  • drawn from the 722 durable notes only — journals and worklogs excluded.

Baseline: recall@1 60.0%, recall@5 83.3%, MRR 0.704.

Note recall@5 is far higher than the 5-case set implied (60%). The old number wasn't measuring quality so much as sampling noise — the underpowering, made visible.

Two misses kept on purpose

query why
"sign in to Claude Code with a Max subscription" a near-duplicate note outranks the labelled target — a vault problem, which consolidate and graph frontier exist to find
"what quality bar must the code I write meet" genuine gap: the note says "production-grade, hardened, fault-tolerant", the query says "quality bar". No lexical overlap; the semantic leg doesn't bridge it

Relabelling either would make the number prettier and the instrument worse.

Gates

ruff check . · mypy src (strict) · pytest (891 passed) · pip-audit — green locally.

🤖 Generated with Claude Code

Three things that were quietly invisible.

doctor reported `semantic search: off` as severity "ok" — a green tick. On the
784-note reference vault, turning the semantic leg on moved recall@1 from 40%
to 60% and MRR from 0.42 to 0.64, so the tick was calling "materially worse
recall than you could have" healthy. Now a warning that names the fix.

compliance.py swallowed every OSError with a bare `return`, so "the log is
being written" and "every write has failed for a week" looked identical from
outside. That is how the Windows rotation bug (#202) hid for a full release.
Failures now leave a labelled breadcrumb in the hook failure log doctor already
reads. A missing log on a fresh machine stays silent — that is not a failure.

The retrieval eval set goes from 5 labelled cases to 30. Five sounds adequate
until you notice each case is worth 20 percentage points: a real 10% gain could
not register, and did not — #193 scored identically on five cases while
individual ranks moved underneath it. Queries are phrased the way an agent
asks, avoid echoing their target's title words, and were authored from note
contents before anything was measured. Baseline: recall@1 60.0%, recall@5
83.3%, MRR 0.704 — recall@5 far above what the 5-case set implied, which is the
underpowering made visible.

Two known misses are kept rather than relabelled: a near-duplicate note
outranking its target (a vault problem for consolidate/frontier), and a genuine
gap where the note says "production-grade, hardened" and the query says
"quality bar".

Co-Authored-By: Claude Opus 5 <[email protected]>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@CryptoJones, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 030bebde-08e6-4d94-8ead-1c887f78a194

📥 Commits

Reviewing files that changed from the base of the PR and between bcba912 and 234542e.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • src/omind/bench.py
  • src/omind/cli.py
  • src/omind/compliance.py
  • tests/test_cli.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/omind/compliance.py
place `omind doctor` looks. Imported lazily: hooks imports this module.
"""
try:
from omind.hooks import _record_failure
@CryptoJones
CryptoJones merged commit c079db2 into main Aug 2, 2026
16 checks passed
@CryptoJones
CryptoJones deleted the fix/surface-degraded-states branch August 2, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants