Skip to content

fix: allow tee mode to record recall stats (fixes #4219) - #4263

Merged
2 commits merged into
rtk-ai:developfrom
TechWizard9999:fix/4219-tee-recall-stats-v2
Sep 26, 2026
Merged

2 commits merged into
rtk-ai:developfrom
TechWizard9999:fix/4219-tee-recall-stats-v2

Conversation

@TechWizard9999

Copy link
Copy Markdown
Contributor

Summary

This PR fixes issue #4219 where tee-only users couldn't see their recall stats in rtk gain --recalls.

Changes

  1. src/core/retriever.rs: Modified record_tee_elision() and record_tee_recall_with() to create the recall store (SQLite database) if needed when recording stats. Previously, these functions used open_existing() which only opens an existing database, so tee-only users never had their stats recorded.

  2. src/analytics/gain.rs: Updated the misleading message in show_recall_stats() to mention that stats work in both sqlite and tee modes.

Root Cause

In tee mode, the recall store was intentionally never created (to "leave no sqlite artifact behind"). However, the recall_stats table schema supports "tee" mode, and rtk gain --recalls displays tee stats - but tee-only users could never populate them because the database was never created.

The fix allows the stats table to be created on-demand when the first stat needs to be recorded. The stats table is lightweight (just counters) and separate from the full recall store that stores command outputs.

- Modify record_tee_elision() to create the recall store if needed
- Modify record_tee_recall_with() to create the recall store if needed
- Update misleading message in gain --recalls to mention tee mode

This allows tee-only users to see their recall stats in 'rtk gain --recalls'.
The stats table is lightweight and separate from the full recall store.
Fixes rtk-ai#4219.
@rtk-wshm-sync-bot rtk-wshm-sync-bot Bot added bug Something isn't working recall tee-mode labels Sep 26, 2026
@rtk-wshm-sync-bot

Copy link
Copy Markdown

wshm · Automated triage by AI

📊 Automated PR Analysis

🐛 Type bug-fix
🟡 Risk medium

Summary

Fixes tee-only users never having recall stats recorded because record_tee_elision() and record_tee_recall_with() only opened an existing SQLite store rather than creating one. The functions now use open() instead of open_existing(), and the misleading CLI message in show_recall_stats() is updated to mention tee mode support.

Review Checklist

  • Tests present
  • Breaking change
  • Docs updated

Linked issues: #4219


Analyzed automatically by wshm · This is an automated analysis, not a human review.

@TechWizard9999

TechWizard9999 commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor Author

@KuSh — Could you please review this

KuSh added a commit to TechWizard9999/rtk that referenced this pull request Sep 26, 2026
The two commits that let the tee path create the recall store fix rtk-ai#4219,
which rtk-ai#4263 carries on its own. rtk-ai#4219 is an open design question (a tee
install currently leaves no sqlite artifact behind), so it is decided
there, and this branch stays on rtk-ai#4218.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@KuSh KuSh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 1 of 3 — CHANGES REQUESTED

Claim: tee-only installs get their recall stats in rtk gain --recalls: the tee stats writers create the recall store when it is missing, and the empty-state message says stats appear in sqlite or tee mode.
Scope: accept if narrowed to "rtk gain --recalls stops telling a tee-only install that stats are pending; tee mode keeps writing stats only into a store that already exists". Whether tee mode should create a store at all is the open question in #4219 (goal 1 vs goal 2) and stays there. (round 1, frozen)
Ran: rtk grep -rn alpha . over 60 files × 30 lines (9 elisions per run), reached through rtk rewrite first, plus the hook rewrite of a cat <tee log> read, × modes tee / sqlite / disabled / tee + RTK_RECALL=0 / tee + custom database_path / sqlite + database_path in a shared 775 dir, × develop c75f159 vs head 637a2d1 (binaries differ); invariants: under the hook, non-default targets, every decision (all three modes + kill switch); split streams and over-cap do not apply (filter output is 211 lines on both sides, unchanged); savings unchanged by this PR.
Matrix: executed this round
CI @637a2d18: all green (11/11)

Blocks merge (1, frozen at round 1)

  1. src/core/retriever.rs:389 (and :433) — the tee path now creates the recall store, which reverses a shipped guarantee: 473edaf in #3278 ("keep tee mode free of any sqlite artifact", listed in the v0.49.0 changelog). The change works as intended. On develop a tee-mode grep leaves history.db tee/, and on this head it also leaves a 36 KB recall.db holding the full store schema (recall, recall_stats, tee_reads). The same switch also sends tee mode into open()'s create_private_dir(parent). With database_path in a shared directory, the directory's mode goes from 775 on develop to 700 on this head in tee mode (sqlite mode already does this on develop, filed as #4280).
    The new comment "The stats table is lightweight and separate from the full recall store" does not match init_schema. recall_stats is created in the same file, by the same batch as the output table.
    To merge on the narrowed claim, the change needs to meet these rows:
    • tee mode, no recall.db, after the grep above and a hook read of a tee log: recall.db is still absent (as on develop), and rtk gain --recalls says that tee mode records per-filter stats only into an existing recall store, so none are recorded here. It also names rtk config recall sqlite as the way to get them. The current "appear once filters elide output" line is the wrong one in this state.
    • tee mode with a store that already exists: stats are recorded as today, and the table renders unchanged.
    • sqlite mode, empty store: today's wording is correct, keep it.
    • disabled mode: the message says recovery is disabled, rather than promising stats.
    • a unit test in retriever.rs that record_tee_elision and record_tee_recall_with with mode: Tee and no existing store leave no db file. Nothing pins 473edaf today, which is why the suite stays green on this head.

Optional — will not hold merge

  • With RTK_RECALL=0 the header shows Mode: tee / sqlite while nothing is recorded. The same message branch could say that recovery is disabled by the environment. Same wording on develop; your call.

Filed as follow-ups

  • #4280 recall: a configured database_path chmods its existing parent directory to 0700 — pre-existing in sqlite mode on develop, outside this PR's hunks once narrowed; filed.

Checked and correct — no need to re-verify

  • sqlite mode: identical on both binaries (9 entries stored, grep|sqlite|8|0, grep_skipped|sqlite|1|0, same hints).
  • disabled mode and tee + RTK_RECALL=0: no recall.db and no tee files on either binary.
  • the hook read of a tee log is recorded once per file (grep|tee|8|1 on head), and a custom database_path is honoured.
  • cargo fmt --check, cargo clippy --all-targets (0 warnings), cargo test --all green locally; CI 11/11.

Your questions

  • None asked beyond the review request.

Next

Drop the retriever.rs hunk, meet the message rows above with the no-store test, and change fixes #4219 to Part of #4219 so the goal-1-vs-goal-2 question stays open there. #4262 carries this same change plus unrelated init/OpenCode edits, so could you close it in favour of this one?
Rounds: 1/3. Threads: 1 open (waiting on the narrowing), 0 resolved this round.

Comment thread src/core/retriever.rs
if let Ok(Some(conn)) = open_existing(cfg) {
// Create the store if needed to record tee elision stats. The stats table
// is lightweight and separate from the full recall store.
if let Ok(conn) = open(cfg) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This switches the tee path from open_existing to open, which undoes 473edaf (#3278, v0.49.0: "keep tee mode free of any sqlite artifact"). On this head a tee-mode grep leaves a recall.db with the full store schema, and a shared database_path parent goes from 775 to 700. The acceptance rows are in the review body.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working recall tee-mode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants