Skip to content

The sessions table is declared in the schema and never used #13

Description

@HackPoint

What

sessions is created by lumen_core::schema::DDL with columns session_id, cwd, model, started_at, source_file. Nothing writes to it and nothing reads its contents. It holds 0 rows while turns holds 66 distinct session_id values, so the data it was meant to hold exists and simply never lands there. Nothing is broken today precisely because nothing reads it — that is the trap. The next person to touch metering finds a table that looks authoritative and either trusts it (and reads zeros) or spends time working out why it is empty.

Two tests do depend on the table existing, so dropping it is not a one-line change: both assert that a freshly created database has exactly four tables, sessions among them.

Evidence

  • sqlite3 "$(cat ~/.lumen_db_path)" "select count(*) from sessions" returns 0.
  • select count(distinct session_id) from turns on the same database returns 66.
  • DDL: crates/lumen-core/src/schema.rs:141 (CREATE TABLE IF NOT EXISTS sessions).
  • git grep -ni "into sessions" and git grep -ni "from sessions" both return nothing: no writer, no reader, in any crate, hook or query.
  • Existence is depended on, contents are not: crates/lumen-core/src/meter.rs:503-517 (connect_db_creates_the_file_and_the_schema) and crates/lumen-core/tests/integration.rs:16-26 (connect_db_creates_all_tables) each assert four tables in sqlite_master for ('turns','sessions','calibration','read_events').
  • What already fills the gap: get_sessions at crates/lumen-stats/src/lib.rs:259 builds one row per session with FROM turns t GROUP BY session_id, including a per-session model.

Acceptance criteria

There is a real decision here, and neither option is clearly right. Session-level metadata would be useful for per-project reporting, which argues for populating it — though model is already derived per session by get_sessions, so cwd is the only column that is genuinely unavailable today. Populating also adds a write to the metering path and a second source of truth for something already derivable from turns. Pick one and record the reason.

  • The commit states which resolution was chosen and why.
  • If populated: sessions is written from the same place turns is written, and count(*) from sessions equals count(distinct session_id) from turns.
  • If populated: cwd and model are non-null for every row.
  • If dropped: sessions is absent from the DDL and from a freshly created database.
  • If dropped: opening an existing database that already has the table does not fail.
  • If dropped: connect_db_creates_the_file_and_the_schema and connect_db_creates_all_tables are updated to expect three tables, and both pass.
  • Grepping for into sessions / from sessions either returns real writer and reader sites, or the table no longer exists.

How to test

DB="$(cat ~/.lumen_db_path)"

# 1. Counts: 0 vs 66 today; equal after the populate fix.
sqlite3 "$DB" "select count(*) from sessions;"
sqlite3 "$DB" "select count(distinct session_id) from turns;"

# 2. Writer/reader search. Empty today. git grep, not grep -r:
#    the working tree carries a multi-gigabyte target/.
git grep -ni "into sessions"
git grep -ni "from sessions"

# 3. Does the table exist? One row today.
sqlite3 "$DB" "select name from sqlite_master
               where type='table' and name='sessions';"

# 4. Fresh database, without touching the live one. Do NOT rm "$DB":
#    it is in WAL mode, so a plain cp is not a complete backup and
#    the -wal/-shm sidecars would be left orphaned. Point LUMEN_DB
#    (first-priority override) at a throwaway path instead, run one
#    Claude Code turn, then repeat step 3 against it.
export LUMEN_DB=/tmp/lumen-fresh.db && rm -f /tmp/lumen-fresh.db*

# The same ground is covered without a live session by the two tests
# that build a fresh database in a temp dir and count its tables:
cargo test -p lumen-core connect_db_creates_the_file_and_the_schema
cargo test -p lumen-core --test integration connect_db_creates_all_tables

Expected after the fix: step 3 returns sessions and step 1 prints two equal numbers, or step 3 returns nothing on both the fresh and the pre-existing database with no migration error and the two table-count tests updated to match.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions