Skip to content

fix/context-explicit-lineage - #233

Merged
omarluq merged 8 commits into
mainfrom
fix/context-explicit-lineage
Jul 28, 2026
Merged

fix/context-explicit-lineage#233
omarluq merged 8 commits into
mainfrom
fix/context-explicit-lineage

Conversation

@omarluq

@omarluq omarluq commented Jul 27, 2026

Copy link
Copy Markdown
Owner

No description provided.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f2e55f68-7a62-43d5-bad2-b8f12d5c61c1

📥 Commits

Reviewing files that changed from the base of the PR and between 1b895c0 and 8701ea7.

📒 Files selected for processing (2)
  • internal/assistant/context_auto_compaction.go
  • internal/assistant/context_overflow_compaction.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/assistant/context_overflow_compaction.go
  • internal/assistant/context_auto_compaction.go

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved prompt persistence reliability by serializing per-session operations and ensuring completions consistently target the active conversation branch after compaction.
    • Corrected auto-compaction and provider-overflow recovery to adopt the correct compaction parent and persist/rebuild more consistently, including stricter handling for missing/nil/blank context endpoints.
  • Tests
    • Expanded coverage for lineage-based auto-compaction flows, session operation locking (including cancellation/idempotent release), and context-building validation.

Walkthrough

Prompt execution now serializes session operations and tracks active prompt lineage explicitly. Context construction requires explicit branch endpoints, compaction rebuilds context from adopted lineage entries, assistant persistence uses the active parent, and terminal compaction snapshots session parameters before asynchronous execution.

Changes

Prompt lineage coordination

Layer / File(s) Summary
Session operation serialization
internal/assistant/session_operations.go, internal/assistant/runtime.go, internal/assistant/*_test.go
Per-session operations are serialized, runtime clones preserve the coordinator, and concurrency behavior is tested.
Explicit context branch endpoints
internal/assistant/context_build.go, internal/assistant/runtime_context.go, internal/database/session_store.go, internal/assistant/*_test.go, internal/database/session_repository_test.go
Context loading uses explicit entry endpoints, rejects blank endpoints, handles missing leaves as empty context, and validates branch-specific requests.
Prompt lineage and compaction flow
internal/assistant/runtime_model.go, internal/assistant/runtime_persist.go, internal/assistant/context_auto_compaction.go, internal/assistant/context_overflow_compaction.go, internal/assistant/*_test.go
Prompt lineage replaces mutable parent identifiers across response generation, compaction, overflow recovery, request rebuilding, and assistant persistence.
Terminal compaction request snapshot
internal/terminal/compact_commands.go, internal/terminal/compact_commands_internal_test.go
Asynchronous compaction receives captured session and working-directory values.
Payload assertion hardening
internal/assistant/lifecyclepayload/lifecyclepayload_test.go
Lifecycle payload tests use parallel subtests and typed required assertions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Prompt
  participant OperationCoordinator
  participant Lineage
  participant ContextBuilder
  participant Provider
  participant SessionRepository
  Prompt->>OperationCoordinator: acquire session operation
  Prompt->>Lineage: create active parent
  Prompt->>ContextBuilder: build branch context
  ContextBuilder->>Provider: submit completion request
  Provider-->>Prompt: response or overflow
  Prompt->>SessionRepository: compact from active parent
  SessionRepository-->>Lineage: return compaction entry
  Lineage->>ContextBuilder: rebuild from adopted parent
  Prompt->>OperationCoordinator: release session operation
Loading

Possibly related PRs

Poem

A rabbit hops through branches bright,
With lineage tucked in neat and light.
Locks keep sessions marching true,
Compaction finds the path anew.
“Hop, rebuild, and persist with care!”
Whiskers cheer the flow we share.

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No description was provided, so there is nothing substantive to evaluate. Add a brief description of the lineage and auto-compaction changes so reviewers can quickly understand the intent.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title points to explicit lineage handling, which matches the main change in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/context-explicit-lineage

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.35028% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.76%. Comparing base (95b13d1) to head (8701ea7).

Files with missing lines Patch % Lines
internal/assistant/runtime.go 66.66% 4 Missing and 4 partials ⚠️
internal/assistant/context_compaction.go 66.66% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #233      +/-   ##
==========================================
+ Coverage   84.71%   84.76%   +0.05%     
==========================================
  Files         314      315       +1     
  Lines       29106    29196      +90     
==========================================
+ Hits        24656    24748      +92     
+ Misses       3058     3053       -5     
- Partials     1392     1395       +3     
Flag Coverage Δ
unittests 84.76% <94.35%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/assistant/context_overflow_compaction.go (1)

26-32: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Input validation doesn't guard the new lineage field, but recoverProviderContextOverflow dereferences it unconditionally.

input.preparation.auth == nil is checked here, but input.preparation.lineage is not, even though recoverProviderContextOverflow (line 60) does input.preparation.lineage.activeParentEntryID as a direct field read (not through the nil-safe promptLineage.adopt() method). Before this PR, the equivalent field was userEntryID string, whose zero value could never panic; now that it's *promptLineage, a nil value here will panic when the context-window-error recovery path is taken.

Today's only caller (modelResponse in runtime_model.go) always supplies a non-nil lineage, so this isn't reachable in the current call graph, but the validation function's explicit purpose is to guard against exactly this nil-deref class for every required field — lineage should be included.

🛡️ Proposed fix
-	if input == nil || input.build == nil || input.preparation == nil || input.preparation.auth == nil {
+	if input == nil || input.build == nil || input.preparation == nil ||
+		input.preparation.auth == nil || input.preparation.lineage == nil {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/assistant/context_overflow_compaction.go` around lines 26 - 32,
Extend the nil-input validation for recoverProviderContextOverflow to also
reject a nil input.preparation.lineage, alongside the existing build,
preparation, and auth checks. Keep the current invalid-input error and return
behavior unchanged so recoverProviderContextOverflow cannot dereference lineage
before validation.
🧹 Nitpick comments (1)
internal/assistant/session_operations_internal_test.go (1)

60-79: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Test doesn't actually exercise the mid-wait cancellation branch.

ctx is already canceled before coordinator.acquire(ctx, "session") is called, so execution hits the upfront ctx.Err() check in session_operations.go (lines 30-32) rather than the select's <-ctx.Done() branch (lines 55-62) that exercises releaseReference cleanup for a goroutine that was genuinely blocked. The name "CancelsWaiter" implies the latter, but the latter is untested.

Consider adding a case where a second goroutine actually blocks on acquire for a held session, then cancel its context mid-wait (similar to the synchronization pattern in TestSessionOperationCoordinatorSerializesSameSession), to cover the refcount cleanup for the in-flight cancellation path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/assistant/session_operations_internal_test.go` around lines 60 - 79,
The test TestSessionOperationCoordinatorCancelsWaiter currently cancels its
context before acquire, covering only the upfront cancellation check. Modify it
so a second goroutine calls acquire while the session is held, then cancel the
context after confirming it is blocked and assert context.Canceled with a nil
release function; finally release the owner and verify a subsequent acquire
succeeds, covering the in-flight waiter cleanup path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/assistant/context_overflow_compaction.go`:
- Around line 26-32: Extend the nil-input validation for
recoverProviderContextOverflow to also reject a nil input.preparation.lineage,
alongside the existing build, preparation, and auth checks. Keep the current
invalid-input error and return behavior unchanged so
recoverProviderContextOverflow cannot dereference lineage before validation.

---

Nitpick comments:
In `@internal/assistant/session_operations_internal_test.go`:
- Around line 60-79: The test TestSessionOperationCoordinatorCancelsWaiter
currently cancels its context before acquire, covering only the upfront
cancellation check. Modify it so a second goroutine calls acquire while the
session is held, then cancel the context after confirming it is blocked and
assert context.Canceled with a nil release function; finally release the owner
and verify a subsequent acquire succeeds, covering the in-flight waiter cleanup
path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5498ed25-6848-4592-8e7f-25d60b4cafb2

📥 Commits

Reviewing files that changed from the base of the PR and between caca35c and c6c3128.

📒 Files selected for processing (23)
  • internal/assistant/agent_runtime_wrappers_internal_test.go
  • internal/assistant/context_auto_compaction.go
  • internal/assistant/context_auto_compaction_internal_extra_test.go
  • internal/assistant/context_auto_compaction_internal_test.go
  • internal/assistant/context_build.go
  • internal/assistant/context_build_test.go
  • internal/assistant/context_compaction.go
  • internal/assistant/context_overflow_compaction.go
  • internal/assistant/context_overflow_compaction_test.go
  • internal/assistant/export_test.go
  • internal/assistant/provider_hook_test_helpers_internal_test.go
  • internal/assistant/runtime.go
  • internal/assistant/runtime_context.go
  • internal/assistant/runtime_context_internal_test.go
  • internal/assistant/runtime_model.go
  • internal/assistant/runtime_persist.go
  • internal/assistant/session_operations.go
  • internal/assistant/session_operations_internal_test.go
  • internal/assistant/tool_schema_cache_internal_test.go
  • internal/database/session_repository_test.go
  • internal/database/session_store.go
  • internal/terminal/compact_commands.go
  • internal/terminal/compact_commands_internal_test.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 27, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/assistant/export_test.go`:
- Around line 93-116: Update ProviderOverflowRecoveryNilLineageForTest to
initialize CompletionRequest and contextwindow.Budget with explicit zero values
for every field instead of using empty struct literals, satisfying exhaustruct
while preserving the existing test behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 19f96ee0-77e7-4744-861b-86a9abde63a7

📥 Commits

Reviewing files that changed from the base of the PR and between c6c3128 and 1a7f399.

📒 Files selected for processing (9)
  • internal/assistant/context_build_test.go
  • internal/assistant/context_overflow_compaction.go
  • internal/assistant/context_overflow_compaction_test.go
  • internal/assistant/context_post_response_auto_compaction_test.go
  • internal/assistant/export_test.go
  • internal/assistant/lifecyclepayload/lifecyclepayload_test.go
  • internal/assistant/runtime_context_internal_test.go
  • internal/assistant/session_operations_internal_test.go
  • internal/database/session_repository_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/assistant/context_overflow_compaction.go
  • internal/assistant/runtime_context_internal_test.go
  • internal/assistant/context_build_test.go

Comment thread internal/assistant/export_test.go
@omarluq
omarluq force-pushed the fix/context-explicit-lineage branch from 1a7f399 to 1b895c0 Compare July 28, 2026 15:33
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 28, 2026
@sonarqubecloud

Copy link
Copy Markdown

@omarluq
omarluq merged commit 2117ca6 into main Jul 28, 2026
16 checks passed
@omarluq
omarluq deleted the fix/context-explicit-lineage branch July 28, 2026 15:57
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