Skip to content

feat(db): optional ignore-filter for sessions by cwd (MONITOR_IGNORE_CWD)#182

Open
MarcoFPO wants to merge 1 commit into
hoangsonww:masterfrom
MarcoFPO:feature/ignore-cwd-filter
Open

feat(db): optional ignore-filter for sessions by cwd (MONITOR_IGNORE_CWD)#182
MarcoFPO wants to merge 1 commit into
hoangsonww:masterfrom
MarcoFPO:feature/ignore-cwd-filter

Conversation

@MarcoFPO

Copy link
Copy Markdown
Contributor

What

Adds an optional, opt-in filter that prevents sessions from being recorded based on their working directory (cwd).

Why

Short-lived helper sessions — e.g. claude --print calls spawned by an API wrapper, all running with cwd=/tmp — can flood the dashboard with thousands of throwaway entries, drowning out real sessions.

How

  • A single guard around stmts.insertSession in server/db.js, so it applies to all insert paths: hooks, the REST POST endpoint, and backfill.
  • Controlled by a new env var MONITOR_IGNORE_CWD.
    • Default: empty → feature is off, no behavioural change for existing users.
    • Set it to a path prefix (e.g. /tmp) to skip matching sessions.

Notes

  • Backwards compatible (off by default).
  • Single-file change (server/db.js, +27 lines).

@MarcoFPO MarcoFPO requested a review from hoangsonww as a code owner June 22, 2026 18:24
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

✅ All contributors have signed the CLA. Thank you!
Posted by the CLA Assistant Lite bot.

…CWD)

Consolidation/probe sessions (e.g. `claude --print` runs with cwd=/tmp)
could flood the dashboard with thousands of entries. This adds a central
guard around stmts.insertSession that covers every insert path (hooks,
REST POST, backfill).

Opt-in via the MONITOR_IGNORE_CWD env var (default empty = disabled);
set it to a path prefix to ignore matching sessions.

Co-Authored-By: Claude <noreply@anthropic.com>
@MarcoFPO MarcoFPO force-pushed the feature/ignore-cwd-filter branch from 6a909b3 to 2d5681d Compare June 22, 2026 18:24
@MarcoFPO

Copy link
Copy Markdown
Contributor Author

recheck

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a mechanism to prevent the persistence of database sessions based on their current working directory (CWD) using the MONITOR_IGNORE_CWD environment variable. The review feedback identifies a critical issue where skipping session insertion will cause foreign key constraint violations in SQLite when related entities (such as agents or events) are subsequently inserted. Additionally, the reviewer points out that replacing stmts.insertSession with a plain object strips other Statement methods, and suggests using a Proxy to safely intercept and skip all related write statements.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread server/db.js
Comment on lines +1300 to +1311
if (IGNORED_SESSION_CWDS.size > 0) {
const _origInsertSession = stmts.insertSession;
stmts.insertSession = {
run: (...args) => {
const cwd = args[3];
if (cwd && IGNORED_SESSION_CWDS.has(cwd)) {
return { changes: 0, lastInsertRowid: 0 };
}
return _origInsertSession.run(...args);
},
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

Critical Correctness Issues

  1. Foreign Key Constraint Violations:
    The database schema enforces foreign key constraints (FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE) on agents, events, token_usage, and workflows tables, and foreign_keys = ON is enabled on line 127. If we skip inserting a session but subsequently attempt to insert agents, events, token usage, or workflows referencing that session ID, SQLite will throw a SqliteError: FOREIGN KEY constraint failed error, crashing the server or hook handler.

  2. Interface Preservation:
    Replacing stmts.insertSession with a plain object { run: ... } strips away all other properties and methods of the Statement object (such as get, all, iterate, etc.). Using a Proxy preserves the Statement prototype and all other methods/properties, ensuring full compatibility.

Solution

Track ignored session IDs in a Set and use a Proxy to intercept all write statements referencing session_id to safely skip execution for ignored sessions.

const IGNORED_SESSION_IDS = new Set();

if (IGNORED_SESSION_CWDS.size > 0) {
  const wrapStatement = (stmt, checkFn) => {
    if (!stmt) return stmt;
    return new Proxy(stmt, {
      get(target, prop, receiver) {
        if (prop === "run") {
          return (...args) => {
            if (checkFn(...args)) {
              return { changes: 0, lastInsertRowid: 0 };
            }
            return target.run(...args);
          };
        }
        const value = Reflect.get(target, prop, receiver);
        return typeof value === "function" ? value.bind(target) : value;
      },
    });
  };

  stmts.insertSession = new Proxy(stmts.insertSession, {
    get(target, prop, receiver) {
      if (prop === "run") {
        return (...args) => {
          const id = args[0];
          const cwd = args[3];
          if (cwd && IGNORED_SESSION_CWDS.has(cwd)) {
            if (id) IGNORED_SESSION_IDS.add(id);
            return { changes: 0, lastInsertRowid: 0 };
          }
          return target.run(...args);
        };
      }
      const value = Reflect.get(target, prop, receiver);
      return typeof value === "function" ? value.bind(target) : value;
    },
  });

  stmts.insertAgent = wrapStatement(stmts.insertAgent, (...args) => IGNORED_SESSION_IDS.has(args[1]));
  stmts.insertEvent = wrapStatement(stmts.insertEvent, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.upsertTokenUsage = wrapStatement(stmts.upsertTokenUsage, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.replaceTokenUsage = wrapStatement(stmts.replaceTokenUsage, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.upsertWorkflow = wrapStatement(stmts.upsertWorkflow, (...args) => IGNORED_SESSION_IDS.has(args[1]));
  stmts.updateSession = wrapStatement(stmts.updateSession, (...args) => IGNORED_SESSION_IDS.has(args[4]));
  stmts.reactivateSession = wrapStatement(stmts.reactivateSession, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.updateSessionModel = wrapStatement(stmts.updateSessionModel, (...args) => IGNORED_SESSION_IDS.has(args[1]));
  stmts.touchSession = wrapStatement(stmts.touchSession, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.setSessionTranscriptPath = wrapStatement(stmts.setSessionTranscriptPath, (...args) => IGNORED_SESSION_IDS.has(args[1]));
  stmts.setSessionAwaitingInput = wrapStatement(stmts.setSessionAwaitingInput, (...args) => IGNORED_SESSION_IDS.has(args[1]));
  stmts.clearSessionAwaitingInput = wrapStatement(stmts.clearSessionAwaitingInput, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.clearSessionAgentsAwaitingInput = wrapStatement(stmts.clearSessionAgentsAwaitingInput, (...args) => IGNORED_SESSION_IDS.has(args[0]));
  stmts.insertAlertEvent = wrapStatement(stmts.insertAlertEvent, (...args) => IGNORED_SESSION_IDS.has(args[3]));
}

@MarcoFPO

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@MarcoFPO

Copy link
Copy Markdown
Contributor Author

recheck

@hoangsonww hoangsonww added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers question Further information is requested labels Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested

Projects

Development

Successfully merging this pull request may close these issues.

2 participants