Skip to content

feat: harden continuity source hygiene and refresh workflows#3

Merged
Boulea7 merged 1 commit intomainfrom
feat/continuity-source-hygiene
Mar 20, 2026
Merged

feat: harden continuity source hygiene and refresh workflows#3
Boulea7 merged 1 commit intomainfrom
feat/continuity-source-hygiene

Conversation

@Boulea7
Copy link
Owner

@Boulea7 Boulea7 commented Mar 19, 2026

Summary

  • add cam session refresh with replace semantics, provenance selection, and legacy-compatible audit/recovery metadata
  • harden rollout / continuity source hygiene and reviewer-facing continuity contracts
  • extract minimal shared test fixtures and update docs/tests around session continuity and reviewer surfaces

What changed

  • add the new cam session refresh command and keep save / wrapper auto-save on merge semantics
  • add replace-aware continuity store writes, exact-scope audit selection, and claude-style active-file rewrite behavior
  • extend continuity audit / recovery records with trigger and writeMode while preserving backward compatibility for older records
  • tighten reviewer history compaction so save and refresh are not collapsed together
  • add refresh, provenance, legacy-compatibility, and claude-path tests; extract test/helpers/cam-test-fixtures.ts
  • update README, continuity docs, release checklist, and related reviewer docs to reflect the current command surface

Review

  • implementation reviewer: no findings
  • test reviewer: no findings
  • docs reviewer: found one README command-table inconsistency; fixed before pushing this PR

Verification

  • pnpm lint
  • pnpm test
  • pnpm build
  • pnpm exec tsx src/cli.ts session status --json
  • pnpm exec tsx src/cli.ts session load --json
  • pnpm exec tsx src/cli.ts memory --json --recent 5

Notes

  • this PR intentionally bundles all local, not-yet-pushed working-tree changes into one reviewable branch, per request
  • repository-level .gitignore coverage was checked and staged diff was scanned for obvious hardcoded secrets before commit

Summary by Sourcery

Introduce a replace-oriented cam session refresh workflow with stricter continuity provenance selection, enhanced audit and recovery metadata, and clearer reviewer-facing memory/continuity surfaces.

New Features:

  • Add a cam session refresh CLI subcommand and supporting runtime logic to regenerate continuity from selected rollout provenance with replace semantics.
  • Support replace-style continuity writes in the session continuity store, including claude-style local file handling that rewrites only the active session file.
  • Expose subagent-aware rollout metadata and selection helpers so primary project rollouts are preferred over subagent rollouts for continuity and wrapper auto-save paths.

Bug Fixes:

  • Tighten session continuity evidence extraction to avoid capturing reviewer prompt and progress-narration text as actionable next steps.
  • Improve explicit correction handling in the heuristic extractor so high-confidence corrections (including Chinese phrasing and clear prefer-over language) correctly delete stale preferences while hedged wording does not.

Enhancements:

  • Extend continuity audit and recovery records with normalized trigger and writeMode fields while keeping legacy entries readable and compatible.
  • Refine cam session status/load text and JSON outputs to better explain merged resume behavior, audit previews, and continuity provenance without changing existing core fields.
  • Harden rollout parsing and selection to handle nested session_meta shapes, preserve the first valid identity line, and exclude subagent rollouts when auto-selecting the latest project rollout.
  • Factor shared CAM test fixtures and broaden test coverage around refresh flows, provenance priority, claude-style paths, and history compaction.
  • Clarify README and docs around companion-first posture, the memory/continuity reviewer surfaces, and the semantics of save vs refresh vs recovery markers.

Tests:

  • Add extensive tests for session refresh CLI behavior, provenance priority rules, replace semantics, audit history compaction, and legacy record compatibility.
  • Add tests for rollout parsing with subagent metadata, latest-primary rollout discovery, claude-style continuity replacement, and heuristic extractor correction/next-step behavior.
  • Introduce shared test helpers for app config, repo initialization, CAM config writing, and rollout fixtures to reduce duplication across suites.

Summary by cubic

Adds a replace-capable cam session refresh with explicit provenance and exact scope handling, and tightens continuity source hygiene across save/refresh and wrapper auto-save. Reviewers get safer, clearer continuity updates, and existing JSON consumers stay compatible.

  • New Features

    • Introduced cam session refresh (replace mode) with --rollout <path>, --scope project|project-local|both, and --json.
    • Provenance order: explicit rollout, matching recovery marker, latest matching audit entry, then latest primary project rollout; save still prefers the latest primary rollout and skips subagents by default.
    • Replace-aware continuity writes with exact scope; save and wrapper auto-save remain merge mode; history no longer collapses save and refresh.
    • Audit and recovery records now include trigger and writeMode fields; legacy JSON remains readable.
  • Refactors

    • Rollout parsing detects subagents and forked sessions; added helpers to read session meta.
    • Heuristic extractor tightens “correction” vs “prefer” logic and widens continuity prompt/evidence patterns.
    • Extracted test/helpers/cam-test-fixtures.ts; added tests for refresh, provenance, legacy compatibility, and Claude-style paths.
    • Updated docs (README, session-continuity, native-migration, architecture, release checklist) and clarified cam memory output on startup files vs on-demand topic refs.

Written for commit 834ed25. Summary will update on new commits.

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 19, 2026

Reviewer's Guide

Introduces a new cam session refresh command with replace semantics and explicit provenance selection, tightens continuity/audit hygiene (including subagent-aware rollout selection, replace-aware writes, and richer audit/recovery metadata), and factors common test fixtures while updating reviewer-facing docs for continuity and compatibility posture.

Updated class diagram for session continuity store and related types

classDiagram
    direction LR

    class SessionContinuityStore {
      -project: ProjectContext
      -config: AppConfig
      -paths: SessionContinuityPaths
      +saveSummary(summary: SessionContinuitySummary, scope: SessionContinuityScope_or_both) string[]
      +replaceSummary(summary: SessionContinuitySummary, scope: SessionContinuityScope_or_both) string[]
      +clear(scope: SessionContinuityScope_or_both) string[]
      +readState(scope: SessionContinuityScope) SessionContinuityState_or_null
      +readRecentAuditEntries(limit: number) SessionContinuityAuditEntry[]
      +readLatestAuditEntry() SessionContinuityAuditEntry_or_null
      +readLatestAuditEntryMatchingScope(scope: SessionContinuityScope_or_both) SessionContinuityAuditEntry_or_null
      +writeRecoveryRecord(record: ContinuityRecoveryRecord) void
      +readRecoveryRecord() ContinuityRecoveryRecord_or_null
      +getLocalIgnorePath() string
      +ensureSharedLayout() void
      +ensureLocalLayout() void
      +ensureLocalIgnore() void
      %% new private helpers
      -writeSummary(summary: SessionContinuitySummary, scope: SessionContinuityScope_or_both, writeMode: SessionContinuityWriteMode) string[]
      -readAuditEntries() SessionContinuityAuditEntry[]
      -resolveLocalWritePath(writeMode: SessionContinuityWriteMode) string
    }

    class SessionContinuitySummary {
      +project: SessionContinuityLayerSummary
      +projectLocal: SessionContinuityLayerSummary
      +sourceSessionId: string
    }

    class SessionContinuityState {
      +status: string
      +sourceSessionId: string
      +updatedAt: string
      +goal: string
      +confirmedWorking: string[]
      +triedAndFailed: string[]
      +notYetTried: string[]
      +incompleteNext: string[]
      +filesDecisionsEnvironment: string[]
    }

    class SessionContinuityLayerSummary {
      +goal: string
      +confirmedWorking: string[]
      +triedAndFailed: string[]
      +notYetTried: string[]
      +incompleteNext: string[]
      +filesDecisionsEnvironment: string[]
    }

    class SessionContinuityWriteMode {
      <<enumeration>>
      merge
      replace
    }

    class SessionContinuityAuditTrigger {
      <<enumeration>>
      manual_save
      manual_refresh
      wrapper_auto_save
    }

    class SessionContinuityScope {
      <<enumeration>>
      project
      project_local
    }

    class SessionContinuityAuditEntry {
      +generatedAt: string
      +projectId: string
      +worktreeId: string
      +configuredExtractorMode: SessionContinuityExtractorPath
      +trigger: SessionContinuityAuditTrigger_optional
      +writeMode: SessionContinuityWriteMode_optional
      +scope: SessionContinuityScope_or_both
      +rolloutPath: string
      +sourceSessionId: string
      +preferredPath: SessionContinuityExtractorPath
      +actualPath: SessionContinuityExtractorPath
      +fallbackReason: SessionContinuityFallbackReason_optional
      +evidenceCounts: SessionContinuityEvidenceCounts
      +writtenPaths: string[]
    }

    class ContinuityRecoveryRecord {
      +generatedAt: string
      +projectId: string
      +worktreeId: string
      +rolloutPath: string
      +sourceSessionId: string
      +trigger: SessionContinuityAuditTrigger_optional
      +writeMode: SessionContinuityWriteMode_optional
      +scope: SessionContinuityScope_or_both
      +writtenPaths: string[]
      +preferredPath: SessionContinuityExtractorPath
      +actualPath: SessionContinuityExtractorPath
      +fallbackReason: SessionContinuityFallbackReason_optional
      +evidenceCounts: SessionContinuityEvidenceCounts
      +failedStage: ContinuityRecoveryFailedStage
      +failureMessage: string
    }

    class RolloutMeta {
      +sessionId: string
      +createdAt: string
      +createdAtMs: number
      +cwd: string
      +rolloutPath: string
      +isSubagent: boolean_optional
      +forkedFromSessionId: string_optional
    }

    class RolloutEvidence {
      +sessionId: string
      +createdAt: string
      +cwd: string
      +userMessages: string[]
      +agentMessages: string[]
      +toolCalls: RolloutToolCall[]
      +rolloutPath: string
      +isSubagent: boolean_optional
      +forkedFromSessionId: string_optional
    }

    class SessionContinuityDiagnostics {
      +generatedAt: string
      +rolloutPath: string
      +sourceSessionId: string
      +preferredPath: SessionContinuityExtractorPath
      +actualPath: SessionContinuityExtractorPath
      +fallbackReason: SessionContinuityFallbackReason_optional
      +evidenceCounts: SessionContinuityEvidenceCounts
      +writtenPaths: string[]
    }

    class SessionContinuityExtractorPath {
      <<enumeration>>
      codex
      heuristic
    }

    class SessionContinuityFallbackReason {
      <<enumeration>>
      none
      codex_failed
      codex_empty
      codex_malformed
      heuristic_empty
    }

    class SessionContinuityEvidenceCounts {
      +commands: number
      +fileWrites: number
      +nextSteps: number
      +untriedIdeas: number
    }

    class buildSessionContinuityAuditEntry {
      +buildSessionContinuityAuditEntry(project: ProjectContext, config: AppConfig, diagnostics: SessionContinuityDiagnostics, writtenPaths: string[], scope: SessionContinuityScope_or_both, options: BuildSessionContinuityAuditEntryOptions) SessionContinuityAuditEntry
      +normalizeSessionContinuityAuditTrigger(trigger: SessionContinuityAuditTrigger_optional) SessionContinuityAuditTrigger_or_legacy
      +normalizeSessionContinuityWriteMode(writeMode: SessionContinuityWriteMode_optional) SessionContinuityWriteMode
    }

    class BuildSessionContinuityAuditEntryOptions {
      +trigger: SessionContinuityAuditTrigger_optional
      +writeMode: SessionContinuityWriteMode_optional
    }

    class buildContinuityRecoveryRecord {
      +buildContinuityRecoveryRecord(options: BuildContinuityRecoveryRecordOptions) ContinuityRecoveryRecord
    }

    class BuildContinuityRecoveryRecordOptions {
      +projectId: string
      +worktreeId: string
      +diagnostics: SessionContinuityDiagnostics
      +trigger: SessionContinuityAuditTrigger_optional
      +writeMode: SessionContinuityWriteMode_optional
      +scope: SessionContinuityScope_or_both
      +writtenPaths: string[]
      +failedStage: ContinuityRecoveryFailedStage
      +failureMessage: string
    }

    class session_continuity_layer_ops {
      +applySessionContinuityLayerSummary(base: SessionContinuityState, summary: SessionContinuityLayerSummary, sourceSessionId: string_optional) SessionContinuityState
      +replaceSessionContinuityLayerSummary(base: SessionContinuityState, summary: SessionContinuityLayerSummary, sourceSessionId: string_optional) SessionContinuityState
    }

    SessionContinuityStore --> SessionContinuitySummary : writes
    SessionContinuityStore --> SessionContinuityState : reads
    SessionContinuityStore --> SessionContinuityAuditEntry : appends
    SessionContinuityStore --> ContinuityRecoveryRecord : reads_writes
    SessionContinuityStore --> SessionContinuityWriteMode : uses

    buildSessionContinuityAuditEntry --> SessionContinuityAuditEntry : creates
    buildSessionContinuityAuditEntry --> BuildSessionContinuityAuditEntryOptions : uses
    buildContinuityRecoveryRecord --> ContinuityRecoveryRecord : creates
    buildContinuityRecoveryRecord --> BuildContinuityRecoveryRecordOptions : uses

    session_continuity_layer_ops --> SessionContinuityState : updates
    session_continuity_layer_ops --> SessionContinuityLayerSummary : consumes

    RolloutEvidence --> RolloutMeta : fields_aligned
Loading

File-Level Changes

Change Details Files
Add cam session refresh with replace semantics, provenance selection, and shared persistence flow with save.
  • Extend session CLI to support a new refresh action with --json, --rollout, and --scope options.
  • Introduce selectRefreshRollout to choose provenance from explicit rollout, matching recovery marker, matching audit entry, or latest primary rollout with strict scope matching and failure-on-missing semantics.
  • Extract persistSessionContinuity to share summarization/audit/recovery logic between save, refresh, and wrapper auto-save, parameterized by trigger and write mode.
  • Ensure refresh uses write mode replace, does not pre-clear continuity, and surfaces selection metadata and write mode in JSON and text output.
src/lib/commands/session.ts
src/cli.ts
docs/session-continuity.md
docs/release-checklist.md
test/session-command.test.ts
Make continuity storage and audit/recovery records replace-aware and scope-precise while preserving legacy compatibility.
  • Add SessionContinuityWriteMode and SessionContinuityAuditTrigger types and thread them through audit entries, diagnostics, recovery records, and helper builders.
  • Extend SessionContinuityStore with a shared writeSummary path plus replaceSummary, using replaceSessionContinuityLayerSummary and a write-mode-aware local path resolver (including claude-style active-file replacement).
  • Factor audit-log reading into readAuditEntries, add readLatestAuditEntryMatchingScope, and adjust grouping/formatting to normalize trigger/writeMode while still accepting legacy entries that omit them.
  • Extend continuity recovery records with optional trigger/writeMode fields and ensure best-effort write/clear helpers pass them through without changing logical matching semantics.
src/lib/types.ts
src/lib/domain/session-continuity.ts
src/lib/domain/session-continuity-store.ts
src/lib/domain/session-continuity-diagnostics.ts
src/lib/domain/recovery-records.ts
src/lib/commands/session.ts
test/session-continuity.test.ts
test/session-command.test.ts
Harden rollout provenance handling to distinguish primary vs subagent sessions and prefer primary rollouts for save/auto-save while allowing refresh to target subagents explicitly.
  • Introduce parsing helpers for session_meta that detect nested metadata, subagent sources, and fork relationships, and augment RolloutMeta/RolloutEvidence with isSubagent and forkedFromSessionId.
  • Ensure parseRolloutEvidence locks onto the first valid meta entry (e.g., subagent) and ignores later meta lines, with tests for nested/broken meta shapes.
  • Update findRelevantRollouts and findLatestProjectRollout to filter/choose primary rollouts, and update wrapper auto-save to pick the latest primary rollout among candidates (via selectLatestPrimaryRollout).
  • Add tests to confirm latest-primary selection, subagent skipping, and wrapper auto-save behavior that prefers the primary session while ignoring reviewer subagent rollouts in continuity summaries.
src/lib/domain/rollout.ts
src/lib/commands/wrapper.ts
src/lib/types.ts
test/rollout.test.ts
test/session-command.test.ts
test/session-continuity.test.ts
Tighten continuity evidence extraction to avoid polluting continuity with reviewer-prompt text while keeping actionable next steps and corrections, including Chinese and prefer-over phrasing.
  • Refine NEXT_STEP_PATTERNS and add additional patterns plus rejection heuristics (shouldRejectContinuityCapture) to filter out reviewer-sub-agent prompts, progress narration, and audit-only language while preserving genuine next steps.
  • Extend explicit correction extraction to support high-confidence prefer-over patterns and Chinese 先别用… corrections, guarded by hedging detection to avoid ambiguous updates.
  • Add tests for keeping actionable follow-up/focus phrasing, excluding reviewer subagent prompts from continuity, and new preference-correction rollouts (including ambiguous cases that should be ignored).
src/lib/extractor/session-continuity-evidence.ts
src/lib/extractor/heuristic-extractor.ts
test/session-continuity.test.ts
test/extractor.test.ts
test/fixtures/rollouts/preferences-prefer-over-correction.jsonl
test/fixtures/rollouts/ambiguous-preferences-prefer-over-correction.jsonl
Improve reviewer-facing CLI surfaces (cam memory, cam session load/status) with clearer explanations of startup/continuity semantics and continuity history compaction.
  • Update runMemory output to explain that startup-loaded files are the actual quoted startup payload and that topic files remain references until read.
  • Update runSession load/status text surfaces to clarify merged resume brief semantics, and that prior generations are compact audit previews (not startup-injected history).
  • Adjust continuity audit grouping to normalize trigger/writeMode so save and refresh entries with the same rollout remain distinct in previews and are not coalesced.
  • Add tests asserting the new explanatory strings appear in CLI output and that same-rollout save+refresh entries both appear in compact history.
src/lib/commands/memory.ts
src/lib/commands/session.ts
test/memory-command.test.ts
test/session-command.test.ts
docs/session-continuity.md
README.en.md
README.md
docs/architecture.en.md
docs/architecture.md
docs/README.en.md
docs/README.md
Factor shared test fixtures for CAM repos/config and rollout JSONL, and propagate them across tests.
  • Create test/helpers/cam-test-fixtures.ts with helpers for makeAppConfig, initGitRepo, writeCamConfig, and makeRolloutFixture.
  • Refactor session, memory, and continuity tests to use shared helpers instead of inlined repo/config/rollout setup, keeping behavior equivalent while reducing duplication.
  • Introduce small helper makeEvidenceCounts in session-command tests to generate consistent evidence count objects for audit/recovery records.
test/helpers/cam-test-fixtures.ts
test/session-command.test.ts
test/session-continuity.test.ts
test/memory-command.test.ts
Align docs with the new continuity and compatibility behavior, emphasizing companion-first posture and the compatibility seam rather than imminent native migration.
  • Reword main README (Chinese and English) to emphasize companion-first with a narrow compatibility seam, clarify cam session command roles (save vs refresh vs load/status), and clarify startup injection semantics (quoted startup files and on-demand topic refs).
  • Update session continuity docs to document save vs refresh semantics, provenance selection rules, audit fields (trigger, writeMode), compact audit previews, and narrow recovery marker behavior.
  • Adjust native-migration docs to describe a compatibility seam and readiness signals instead of a multi-phase migration plan, and add last-verified comments tied to official docs URLs.
  • Update docs/README entry to describe native-migration doc as about compatibility seam re-evaluation rather than migration plan.
README.en.md
README.md
docs/session-continuity.md
docs/native-migration.en.md
docs/native-migration.md
docs/architecture.en.md
docs/architecture.md
docs/README.en.md
docs/README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The new selectRefreshRollout and persistSessionContinuity helpers centralize important behavior; consider adding brief inline comments or JSDoc summarizing their provenance/priority rules and replace-vs-merge semantics, since future changes to continuity behavior will likely need to start from these functions.
  • When selectRefreshRollout fails to find a rollout it throws a generic "No relevant rollout found for this project."; including the requested scope and whether a recovery marker or audit entry was present in the error message would make it much easier for reviewers to diagnose why a refresh failed.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `selectRefreshRollout` and `persistSessionContinuity` helpers centralize important behavior; consider adding brief inline comments or JSDoc summarizing their provenance/priority rules and replace-vs-merge semantics, since future changes to continuity behavior will likely need to start from these functions.
- When `selectRefreshRollout` fails to find a rollout it throws a generic `"No relevant rollout found for this project."`; including the requested scope and whether a recovery marker or audit entry was present in the error message would make it much easier for reviewers to diagnose why a `refresh` failed.

## Individual Comments

### Comment 1
<location path="docs/architecture.en.md" line_range="55" />
<code_context>
-- each `MEMORY.md` is injected as quoted local data
-- structured topic file refs are appended
-- topic entry bodies are not eagerly loaded
+- each `MEMORY.md` is injected as quoted startup files
+- structured topic file refs are appended as on-demand lookup pointers
+- topic entry bodies are not eagerly loaded at startup
</code_context>
<issue_to_address>
**nitpick (typo):** Tighten singular/plural agreement in this sentence.

Using "each" with plural "files" is grammatically awkward. Consider singular phrasing like "each `MEMORY.md` is injected as a quoted startup file" or "each `MEMORY.md` is injected as quoted startup content."

```suggestion
- each `MEMORY.md` is injected as a quoted startup file
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

- each `MEMORY.md` is injected as quoted local data
- structured topic file refs are appended
- topic entry bodies are not eagerly loaded
- each `MEMORY.md` is injected as quoted startup files
Copy link

Choose a reason for hiding this comment

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

nitpick (typo): Tighten singular/plural agreement in this sentence.

Using "each" with plural "files" is grammatically awkward. Consider singular phrasing like "each MEMORY.md is injected as a quoted startup file" or "each MEMORY.md is injected as quoted startup content."

Suggested change
- each `MEMORY.md` is injected as quoted startup files
- each `MEMORY.md` is injected as a quoted startup file

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 30 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/lib/domain/rollout.ts">

<violation number="1" location="src/lib/domain/rollout.ts:281">
P2: Variable `seenPrimaryMeta` is set to `true` for any valid session meta, including subagent entries. Either the name is misleading (should be `seenSessionMeta`) or the code is missing a `parsedMeta.isSubagent` guard to skip subagent entries before assigning session fields — consistent with how `findLatestProjectRollout` uses `isPrimaryRolloutMeta` to filter them out.</violation>
</file>

<file name="test/session-continuity.test.ts">

<violation number="1" location="test/session-continuity.test.ts:526">
P2: This assertion checks `positiveBuckets` for "reviewer sub-agent", but that text only exists in the `negativeBuckets` input. The check trivially passes and doesn't actually validate the filtering behavior. It should assert against `negativeBuckets.explicitNextSteps` instead.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

cwd = await normalizeFsPath(parsedMeta.cwd);
isSubagent = parsedMeta.isSubagent;
forkedFromSessionId = parsedMeta.forkedFromSessionId;
seenPrimaryMeta = true;
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

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

P2: Variable seenPrimaryMeta is set to true for any valid session meta, including subagent entries. Either the name is misleading (should be seenSessionMeta) or the code is missing a parsedMeta.isSubagent guard to skip subagent entries before assigning session fields — consistent with how findLatestProjectRollout uses isPrimaryRolloutMeta to filter them out.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/domain/rollout.ts, line 281:

<comment>Variable `seenPrimaryMeta` is set to `true` for any valid session meta, including subagent entries. Either the name is misleading (should be `seenSessionMeta`) or the code is missing a `parsedMeta.isSubagent` guard to skip subagent entries before assigning session fields — consistent with how `findLatestProjectRollout` uses `isPrimaryRolloutMeta` to filter them out.</comment>

<file context>
@@ -209,10 +264,21 @@ export async function parseRolloutEvidence(filePath: string): Promise<RolloutEvi
+      cwd = await normalizeFsPath(parsedMeta.cwd);
+      isSubagent = parsedMeta.isSubagent;
+      forkedFromSessionId = parsedMeta.forkedFromSessionId;
+      seenPrimaryMeta = true;
       continue;
     }
</file context>
Fix with Cubic

'需要更新测试文件以覆盖新的守卫逻辑'
])
);
expect(positiveBuckets.explicitNextSteps.join("\n")).not.toContain("reviewer sub-agent");
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

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

P2: This assertion checks positiveBuckets for "reviewer sub-agent", but that text only exists in the negativeBuckets input. The check trivially passes and doesn't actually validate the filtering behavior. It should assert against negativeBuckets.explicitNextSteps instead.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At test/session-continuity.test.ts, line 526:

<comment>This assertion checks `positiveBuckets` for "reviewer sub-agent", but that text only exists in the `negativeBuckets` input. The check trivially passes and doesn't actually validate the filtering behavior. It should assert against `negativeBuckets.explicitNextSteps` instead.</comment>

<file context>
@@ -531,7 +516,39 @@ describe("session continuity domain", () => {
+        '需要更新测试文件以覆盖新的守卫逻辑'
+      ])
+    );
+    expect(positiveBuckets.explicitNextSteps.join("\n")).not.toContain("reviewer sub-agent");
+  });
+
</file context>
Suggested change
expect(positiveBuckets.explicitNextSteps.join("\n")).not.toContain("reviewer sub-agent");
expect(negativeBuckets.explicitNextSteps.join("\n")).not.toContain("reviewer sub-agent");
Fix with Cubic

@Boulea7 Boulea7 merged commit 24c35ef into main Mar 20, 2026
5 checks passed
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