Skip to content

[claude/hotfix] fix(store): drop duplicate physical sources for the same logical session#39

Open
div0-space wants to merge 1 commit into
developfrom
fix/store-drop-duplicate-sources
Open

[claude/hotfix] fix(store): drop duplicate physical sources for the same logical session#39
div0-space wants to merge 1 commit into
developfrom
fix/store-drop-duplicate-sources

Conversation

@div0-space

Copy link
Copy Markdown
Contributor

This pull request improves how duplicate physical sources for the same logical session are handled during session extraction. It ensures that only the freshest copy is processed, tracks and reports dropped duplicates, and adds tests for the new ordering logic.

Session extraction improvements:

  • Added a duplicate_sources field to SessionExtractionBatch to count extra physical sources for already-ingested logical sessions within a batch. These are dropped to avoid reprocessing the same session from multiple files.
  • In extract_agent_sessions, sources are now sorted so that the freshest (most recently modified) copy is parsed first. Older duplicates are detected and counted using the new duplicate_sources field, and are not ingested. [1] [2] [3]

Testing and reporting:

  • Added the order_sources_freshest_first function and a test (duplicate_session_sources_are_ordered_freshest_first) to verify that sources are correctly ordered by modification time.
  • Updated session batch summary output to include the count of duplicate sources when present. [1] [2]…gical session — freshest copy wins
  • aicx all -H 30 na żywym korpusie padoł na końcu biegu: 'duplicate canonical card id: card3:1980d570c88bce990c7e30e8' — ta samo logiczno sesjo odkryto z dwóch ścieżek fizycznych (np. live rollout + zarchiwizowano kopia)
  • root cause: ingested_session_ids (BTreeSet) dubla nie wstawiał, ale canonical_cards.extend() szedł per-źródło -> dwa komplety kart o identycznych content-derived id w projekcji
  • fix: order_sources_freshest_first (mtime desc, sort stabilny) + strażnik per-batch: druga kopia już-ingestowanej sesji -> drop liczony w duplicate_sources (NIE skip: nie trzymie watermarku, nie triggeruje retry)
  • summary raportuje duplicate_sources=N tylko gdy N>0
  • test: duplicate_session_sources_are_ordered_freshest_first

Authored-By: claude agents@vetcoders.io
session_id: 49a84e4c-f24d-4167-9f55-ae0f8123a66f
timestamp: 2026_0715_1540_CEST
runtime: claude-code-interactive

…gical session — freshest copy wins

- aicx all -H 30 na żywym korpusie padoł na końcu biegu:
  'duplicate canonical card id: card3:1980d570c88bce990c7e30e8' —
  ta samo logiczno sesjo odkryto z dwóch ścieżek fizycznych
  (np. live rollout + zarchiwizowano kopia)
- root cause: ingested_session_ids (BTreeSet) dubla nie wstawiał,
  ale canonical_cards.extend() szedł per-źródło -> dwa komplety kart
  o identycznych content-derived id w projekcji
- fix: order_sources_freshest_first (mtime desc, sort stabilny) +
  strażnik per-batch: druga kopia już-ingestowanej sesji -> drop
  liczony w duplicate_sources (NIE skip: nie trzymie watermarku,
  nie triggeruje retry)
- summary raportuje duplicate_sources=N tylko gdy N>0
- test: duplicate_session_sources_are_ordered_freshest_first

Authored-By: claude <agents@vetcoders.io>
session_id: 49a84e4c-f24d-4167-9f55-ae0f8123a66f
timestamp: 2026_0715_1540_CEST
runtime: claude-code-interactive

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

Copy link
Copy Markdown

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 handle duplicate session sources by sorting them freshest first based on their modification timestamp. This ensures that the most recent copy of a logical session is parsed first, and subsequent older duplicates are dropped and tracked via a new duplicate_sources counter. A unit test was added to verify the sorting order, and the session ingest summary output was updated to display duplicate sources when present. The reviewer suggested using sort_unstable_by instead of sort_by to improve sorting efficiency.

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 src/extraction/mod.rs
Comment on lines +95 to +102
fn order_sources_freshest_first(sources: &mut [crate::session_catalog::CatalogSource]) {
sources.sort_by(|left, right| {
right
.fingerprint
.modified_unix_nanos
.cmp(&left.fingerprint.modified_unix_nanos)
});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since stability is not required when sorting sources by modification time, we can use sort_unstable_by instead of sort_by. This is more efficient as it avoids allocating temporary memory and is generally faster.

Suggested change
fn order_sources_freshest_first(sources: &mut [crate::session_catalog::CatalogSource]) {
sources.sort_by(|left, right| {
right
.fingerprint
.modified_unix_nanos
.cmp(&left.fingerprint.modified_unix_nanos)
});
}
fn order_sources_freshest_first(sources: &mut [crate::session_catalog::CatalogSource]) {
sources.sort_unstable_by(|left, right| {
right
.fingerprint
.modified_unix_nanos
.cmp(&left.fingerprint.modified_unix_nanos)
});
}

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the app-only session extraction pipeline to handle cases where the same logical session is discoverable via multiple physical sources (e.g., live rollout + archived copy) by processing the freshest copy first and dropping older duplicates, while reporting how many were dropped.

Changes:

  • Added duplicate_sources to SessionExtractionBatch and incremented it when a second physical source for an already-ingested session is encountered.
  • Introduced order_sources_freshest_first and changed extract_agent_sessions to sort selected sources by mtime descending before parsing/ingesting.
  • Updated CLI/session batch summary output and added a unit test to validate the ordering behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/extraction/mod.rs Adds duplicate source counting, introduces freshest-first ordering, and updates extraction loop to drop duplicates.
src/extraction/tests.rs Adds a test asserting freshest-first ordering for duplicate-session sources.
src/main.rs Extends session ingest summary output to include duplicate_sources when non-zero.
Comments suppressed due to low confidence (1)

src/extraction/mod.rs:139

  • Duplicate sources are only detected after parsing the file. Since CatalogSource often already has logical_session_id, you can drop already-ingested duplicates before calling parse_file, saving work for archived/older copies while still keeping the post-parse guard as a fallback when logical_session_id is missing.
        batch.selected_sessions += 1;
        let parsed = crate::parser_dispatch::parse_file(
            parser_agent,
            &source.source_id,
            source.logical_session_id.clone(),

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/extraction/mod.rs
Comment on lines +144 to +148
if batch
.ingested_session_ids
.contains(&session.model().session_id)
{
batch.duplicate_sources += 1;
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.

2 participants