# Reported issues for rag-rat

Pod holds 23 of 75 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [rag-rat](/mcp/rag-rat).

## Most discussed

### rag-rat VS Code lens: WS-backed extension (+ optional bundled web-VS-Code appliance)

## Idea (north-star)

A read-only **VS Code lens** over the rag-rat index: a familiar editor with flamegraph/heat-style overlays for duplication, hotspots, and fan-in/out, plus a guided branch-review mode. Not an IDE you edit in — "Google Maps for the repo."

**Architecture decision (supersedes the earlier "custom Monaco app" framing):** ship a **VS Code extension**, not a hand-built editor. Monaco is only the editor *widget*; a web VS Code is the whole shell for free (file tree, search, git, na

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/216) · 2026-06-18 · closed · 4 comments

### SCIP oracle epic — live LSP hardening and additional backends remaining

## Tracking — decomposed into sub-issues

This issue is now the **epic**; the design below is the reference. Slices, in dependency order:

- [x] #67 — Prerequisite: persist callee-identifier byte range on edges (additive, byte-identical; unblocks everything)
- [x] #68 — Phase 1: SCIP protobuf reader + heuristic precision/recall eval *(depends #67)*
- [x] #69 — Phase 2: `oracle run` for Rust — `Compiler` tier, `resolved-external`, `compare_graph_to_scip` *(depends #68)*
- [x] #70 — Phase 3: monik

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/61) · 2026-06-11 · open · 4 comments

### opencode plugin bundle (MCP + hooks)

## Context

The repo ships a shared plugin bundle under `plugin/` that serves **Claude Code** (`.claude-plugin/plugin.json` + `hooks/hooks.json`) and **Codex** (`.codex-plugin/plugin.json` + `.mcp.json`), with a single shared launcher (`plugin/scripts/launch.js`), shared skills (`plugin/skills/`), and the harness-neutral `rag-rat agent-hook` stdin/stdout handler. Both harnesses use the same hook contract: stdin JSON `hook_event_name` / `tool_name` / `tool_input` → stdout `hookSpecificOutput.addi

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/784) · 2026-07-19 · closed · 3 comments

### chunk_fts (contentless FTS5) docsize corruption is invisible to every integrity check and breaks memory_search via bm25; needs detection + self-heal

### Symptom

The `repo_memory_fts` FTS5 index (memory search) got corrupted on the shared/consolidated DB. `memory_search` (MCP) returned `MCP error -32603: database disk image is malformed` on every call, while `index_status` (MCP) and `rag-rat memory list` (CLI, fresh connection) worked fine.

The on-disk DB was **not** structurally corrupt — only the FTS5 shadow index was, which `PRAGMA integrity_check` doesn't fully validate.

### What fixed the disk, and what didn't fix the server

Repairin

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/582) · 2026-07-10 · closed · 3 comments

### fleet hot-upgrade: CLI-won worktree election must carry fleet_bin (auto-trigger shipped in #510)

Observed live: after `cargo install --path crates/rag-rat-cli` replaced the installed binary (new inode confirmed), two armed long-lived `rag-rat mcp` servers (RAG_RAT_UPGRADE_BIN present in environ) were never signaled — well past FLEET_DEBOUNCE/FLEET_MAX_LATENCY (0.5s/2s) and across multiple request boundaries. A manual `kill -USR1` re-exec'd both immediately, so the arming and the re-exec path work; the trigger side didn't fire.

Likely cause to verify: the per-worktree watcher election can b

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/499) · 2026-07-08 · open · 3 comments

### sync: add the node_anchors/1 content op carrying portable binding facts

The carrier for cross-account anchor replication (#1180): a new `/3` op kind snapshotting a memory's portable binding facts.

`MemoryOp::NodeAnchors { node_id, anchors }`, where each anchor carries exactly the `/5` portable column set — `binding_kind`, `binding_id`, `path`, `start_line`, `end_line`, `commit_hash`, `tracker`, `project`, `item_key`, `created_at_ms`, `symbol_kind`, `signature_hash`, `moniker_tool`, `moniker_tool_version`. Checkout-local resolution state (`logical_symbol_id`, `symbo

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1208) · 2026-08-18 · closed · 2 comments

### Point `rag-rat init` MCP hint at add-mcp (Rust hook config-writer retired; blocked on #545)

Once the plugin + `@rag-rat/setup` land, retire the Rust config-writing so per-agent config no longer lives in the binary.

- **MCP:** point `rag-rat init` at `@rag-rat/setup` / `add-mcp` instead of printing the `claude/codex mcp add` command.
- **Hooks (migration hazard):** existing installs carry `rag-rat claude-hook` entries in `.claude/settings.json`; installing the plugin **without removing them double-fires every hook**. Staged: keep `hooks uninstall --claude` + `hooks status` for a deprec

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/549) · 2026-07-09 · open · 2 comments

### memory_validate 'relocate' leaves stale binding symbol_id/logical_symbol_id (and likely orphan symbol rows after full rebuild)

## Symptom

After `memory_validate` (which reported `relocated: 1`), a symbol-bound memory still carries **stale** ids in its binding. In a single `find_callers` response for `install_path`:

- live symbol resolves to `symbol_id: 37112`, `logical_symbol_id: 9128717097963335254`
- the bound memory (`mem_19eae08c32d_6d77d453c833`) binding shows `symbol_id: 221740`, `logical_symbol_id: 8973413979112100636`, `chunk_id: 283741`, `anchor_status: "relocated"`

Both come from the same DB read, so this i

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/50) · 2026-06-09 · closed · 2 comments

## Most recent

### sync: demote stale synced anchors in memories_for_* surfaces

The staleness rider for #1180, separable from the rest of the train and shippable independently.

`source_text_hash` rides the `node_anchors` op; the drain stamps it onto the synced `repo_memories` row, which is inserted NULL today. On this carrier neither an `anchors/1` spec bump nor its backfill is needed — the two costs the `/5` route would have incurred.

**Policy, settled:** on hash divergence, demote to a marked stale-style presentation, **never hide**. Exact-text hashing cannot distinguis

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1213) · 2026-08-18 · open · 1 comment

### feat(mcp): declare the per-request worktree parameter in tool schemas

Per-request worktree scoping is implemented but undiscoverable. `call_tool_for_config` (`crates/rag-rat-mcp/src/tools/mod.rs`) reads a common `worktree` field from the request and calls `use_worktree_scope`; the fallback (`worktree_arg`) is the MCP server process's own cwd. But `worktree` is declared in no tool's JSON schema — the schemas are generated from the per-tool arg structs, none of which carry it — so a client scoping reads to a linked worktree has no way to learn the parameter exists, 

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1201) · 2026-08-18 · closed · 0 comments

### is_pascal_case treats a SCREAMING_CONST with a method chain as PascalCase, so classify_call returns Wrapper

## Description

`is_pascal_case` cannot distinguish a `SCREAMING_CONST` followed by a method chain from a genuine `PascalCase` variant, so `classify_call` returns `Wrapper` for a call whose head is a constant.

Concrete case, at `crates/rag-rat-mcp/src/server/service.rs:43`:

```rust
crate::tools::TOOL_NAMES.iter().map(|name| { … })
```

The head segment here is `TOOL_NAMES.iter().map(…)`. `is_pascal_case` sees a leading `T` plus the lowercase characters contributed by the appended method names 

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1124) · 2026-08-02 · closed · outside contributor · 0 comments

### sync: /5 table-stream transport with bounded scoped manifest

## Goal

Expose the transport-independent table-sync engine over iroh without registering a production table yet.

Part of #892. Follows #1049 / #1095.

## Scope

- add a dedicated table-sync ALPN and endpoint dispatch alongside account and content sync;
- exchange a bounded canonical manifest of supported `(repo_id, incarnation_ref, scope_id, stream_id)` streams after mutual account authorization;
- derive and verify each advertised stream against local current-incarnation authority; the manife

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1096) · 2026-08-01 · closed · 0 comments

### Rotate the discovery tag so a removed device cannot enumerate hosts

Split out of #1080, which now covers sealing announcement payloads and the service-side eviction change. This issue is the half those do not close.

## The gap

The discovery tag is `sha256(domain || account genesis entry hash)`. The genesis hash is immutable and already sits in every enrolled device's database, so a device removed from the roster can compute the tag forever. Sealing the payloads (#1080) stops it reading the node ids of hosts that begin advertising after its removal, but it can 

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1081) · 2026-07-31 · open · 0 comments

### Skill sources and their shipped plugin copies can drift silently

`.agents/skills/<name>/SKILL.md` and `plugin/skills/<name>/SKILL.md` are byte-identical copies of the same document, and nothing checks that they stay that way.

`.claude/skills/` and `.codex/skills/` are symlinks to the `.agents` source, so those three always agree. The `plugin/` copy is a real file — it is what ships to users who install the plugin — and it is maintained by hand. Editing one and not the other produces no build failure, no test failure, and no lint: the repo's guidance and the 

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1075) · 2026-07-30 · closed · 0 comments

### Upgrade rmcp to 3.0 (MCP 2026-07-28 support)

rmcp 3.0 is out and adds support for MCP protocol version 2026-07-28. The MCP server currently pins rmcp 2.2.

## What the major bump requires

- `ServerHandler::call_tool` now returns the MRTR-aware `CallToolResponse` (`Complete` | `InputRequired` | `Task`) instead of `CallToolResult`. Every rag-rat tool answers in one round trip, so the handler always returns the `Complete` arm.
- Paginated results (`ListToolsResult`) gained `result_type`, `ttl_ms`, and `cache_scope` fields (SEP-2322 / SEP-254

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1070) · 2026-07-30 · closed · 0 comments

### Lens hop endpoints resolve by qualified name, collapsing overloads

Follow-up from #216.

`IndexDatabase::lens_symbol_callers` and `lens_symbol_callees`
(`crates/rag-rat-core/src/index/query_api/lens/hops.rs`) take a `qualified_name: &str` and hand it
straight to `find_callers_with_options` / `trace_callees_with_options`. Exact traversal expands a
qname to every symbol id that carries it, so for a file with overloads sharing a qualified name,
clicking one overload's CodeLens reports the callers of all of them. `/api/file/graph` has the same
gap on the way in: ea

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1028) · 2026-07-29 · closed · 0 comments

### index: resolve locally-rooted Rust imports to their declaring scope instead of keeping the bare name

Rust receiver-type inference canonicalizes a type mention at its reference site by prefixing the
enclosing inline-`mod` chain. That is correct for a path written out in full, but wrong for a name
introduced by a `use`: the imported item lives at the *use's* path, which the lexical module chain
does not describe.

#976 makes an imported bare name canonicalize to itself — dropping the module prefix rather than
fabricating one. On this repo that removed 8 distinct invented owner paths across 24 cal

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/1007) · 2026-07-29 · open · 0 comments

### Add first-class Cursor hook adapter

Implement a dedicated Cursor hook adapter using Cursor's native lifecycle and payload contract.

Scope:
- Normalize session start, shell execution, file read, and successful file edit events.
- Emit only bounded rag-rat context through Cursor's documented context channel.
- Trigger detached scoped reindexing after edits.
- Enable clone checks only when Cursor provides adequate pre-edit text or diff data.
- Keep malformed input and missing configuration/index/binary fail-silent and non-blocking.

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/987) · 2026-07-28 · closed · 0 comments

### sync: derive peer capability during auth and reject read-only pushes

Part of #930, toward #406.

## Gap

Enrollment now persists a three-level roster role and the content fold rejects unauthorized authoring, but the transport auth phase returns only success/failure. The symmetric session therefore still accepts `Entries` frames from a peer enrolled as read-only and relies solely on the durable ingest/fold backstop.

## Scope

- Return a per-connection peer capability from node authentication.
- Derive read/write capability from the peer's effective roster role: `

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/978) · 2026-07-28 · closed · 0 comments

### Split rag-rat-mcp server runtime, service, dispatch, and tests

## Scope
Decompose `crates/rag-rat-mcp/src/server.rs` into a curated `server/` module:
- `mod.rs`: `RagRatService` and stable exports
- `service.rs`: `ServerHandler` and dormant behavior
- `dispatch.rs`: call adaptation, blocking chokepoint, timeouts, inflight accounting, nudges
- `runtime.rs`: STDIO lifecycle
- `tests.rs`: existing tests

## Invariants
Dormant MCP behavior, tool shapes, worker limits, inflight accounting, read timeouts, write deadlines, and panic conversion remain unchanged. No

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/916) · 2026-07-24 · closed · 0 comments

### sync: serve replicates only the account log — content needs a wire stream discriminator

\`rag-rat sync serve\` (from #905) replicates the **account log** only. The session wire (\`Frame::Hello\`/\`Frame::Auth\`) carries the account id and entry hashes but no discriminator for *which* stream a session moves — the store the caller passes decides the meaning (\`OplogSyncStore\` = account log, \`OplogContentSyncStore\` = /3 content). So an acceptor cannot tell account-vs-content apart from the hello, and a serve peer can replicate exactly one stream type per ALPN.

Serving content (the

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/907) · 2026-07-24 · closed · 0 comments

### distill: surface distilled records in MCP tool docs + the CLI query --json output

Part of #705 (scope item 4 — the final item). The distilled decision records now attach to retrieval + drive-by surfaces (items 1-2), but they are undocumented in the MCP tool descriptions and absent from the CLI.

- **MCP tool docs**: the tool descriptions (`rag-rat-mcp/tools/catalog.rs`) for the surfaces that now carry records — semantic_search, symbol_lookup, impact_surface, read_chunk (drive-by), and papertrail_issue_search / rationale_search (payload) — do not mention the `distilled_records

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/853) · 2026-07-22 · closed · 0 comments

### Watcher never controls WAL checkpoint cadence under churn — default passive autocheckpoint amplifies main-db write-back

## Problem

`maybe_checkpoint_wal` only runs on quiet passes (`crates/rag-rat-core/src/watch/pass.rs:468`; `quiet_pass` at `:351`), and under sustained editing quiet passes almost never happen (67/107 measured passes had `overlays_changed=true`). Checkpoint cadence therefore falls to SQLite's default ~4 MiB passive autocheckpoint, which fires dozens of times mid-pass while ~170 MB/pass streams through the WAL. Long-lived readers keep the WAL from resetting (it plateaus around 20 MB), and each la

[Read the thread](https://github.com/cq27-dev/rag-rat/issues/818) · 2026-07-21 · closed · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/cq27-dev/rag-rat/issues).
