Skip to content

Re-ingest changed sessions; keep cross-midnight sessions whole - #27

Open
nnunley wants to merge 2 commits into
prime-radiant-inc:mainfrom
nnunley:fix/ingest-and-session-grouping
Open

nnunley wants to merge 2 commits into
prime-radiant-inc:mainfrom
nnunley:fix/ingest-and-session-grouping

Conversation

@nnunley

@nnunley nnunley commented Aug 13, 2026

Copy link
Copy Markdown

Problem

Two ingest/grouping defects cause journal entries to go stale or to be skipped as "no engineering work."

  1. Changed session files are never re-ingested. ingestSessions skipped any session already present in the DB, so a session that Claude/Codex later appended to kept its truncated transcript forever. Any journal entry already generated for that (date, project) also stayed stale.

  2. Cross-midnight sessions were split into slivers. groupSessionsByDateAndProject used per-message logical dates, so a session started at 22:00 contributed a few morning messages to the next day as a separate group. Those tail slivers lack context and the model consistently rejects them. Skip-pattern analysis over 8 recent skips found every skipped group had tiny day-scoped content (<2KB, smallest was 389 chars of /exit boilerplate); the most recoverable false negatives were exactly these midnight slivers.

Approach

Re-ingest on change. Sessions record source file size and mtime. Ingest re-parses a session when either differs, and invalidates journal entries for the affected (date, project) so the next summarize regenerates them. Unchanged files still short-circuit, so repeat ingests stay cheap.

Sessions are atomic. Each session is attributed wholly to the logical date of its started_at (adjusted by day_start_hour). A session that begins late and runs past midnight contributes its full content to the start date. splitConversationByDay remains exported for external tools that want per-message attribution; the orchestrator no longer calls it.

How to test

bun test
bun run typecheck

New coverage: re-ingest when a source file grows, skip when size and mtime both match, journal invalidation on re-ingest, atomic attribution of a midnight-spanning session (one group, all six messages on the start date), and filterDate matching the start date rather than the message date.

Baseline on main is 92 passing; this branch is 95 passing, 0 failing, typecheck clean.

Limitations

Change detection uses size and mtime, not a content hash. A file edited in place to exactly the same size within the same mtime granularity will not be detected. That does not occur with append-only agent transcripts.

Invalidation is per (date, project), so re-ingesting one session regenerates the whole day's entry for that project.

Previously, sessions whose messages spanned midnight were split across
two date buckets using per-message logical dates. In practice this
created thin tail slivers on the next day — a few morning messages from
a session that started the prior evening — that the LLM consistently
rejected as "no engineering work" because the slivers lacked context.

Skip-pattern analysis (2026-05-13, 8 recent skips) found that all
skipped groups had tiny day-scoped content (<2KB; smallest 389 chars
literal `/exit` boilerplate). The most recoverable false-negatives
were these midnight-split slivers where substantive work happened on
the start side of midnight but the tail got rejected in isolation.

Fix: each session is now atomic and attributed to its `started_at`
logical date (the date adjusted by `day_start_hour`). A session that
begins late one night and continues past midnight contributes its full
content to the start date.

`splitConversationByDay` is kept as an exported helper for external
tools that want per-message day attribution, but the orchestrator no
longer uses it.

Tests updated: the midnight-spanning suite now verifies atomic
attribution (one group, all 6 messages on Feb 20) and that
`filterDate("2026-02-21")` returns nothing for a session that started
on Feb 20 even when some messages are timestamped Feb 21.
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.

1 participant