Skip to content

Conversation

@xkonjin
Copy link

@xkonjin xkonjin commented Jan 5, 2026

Summary

Adds a fully automatic continuity system that preserves session state across /clear operations with zero manual intervention.

What's Automatic

Event Action
Start opencode Loads existing ledger (if any)
First session Creates new ledger automatically
First message Injects ledger context into chat
Todo updates Syncs to ledger (done/now/next)
85% context Auto-saves handoff file
Context warnings Toast at 60%/80%/85%

Features

Continuity Ledger (thoughts/ledgers/CONTINUITY_CLAUDE-{session}.md)

  • Structured session state preservation
  • Goal, constraints, key decisions tracking
  • State management (done/now/next) - auto-synced with todos
  • Working set (branch, files, commands)
  • Agent reports with auto-pruning

Auto-Continuity Hook

  • Context window monitoring with thresholds (60% yellow, 80% red, 85% critical)
  • Auto-save handoffs when hitting critical threshold
  • Auto-create ledger on first session
  • Auto-inject context on session resume
  • Auto-sync ledger with todo list updates
  • Toast notifications for context warnings

Handoff System (thoughts/shared/handoffs/{session}/)

  • Manual and auto-generated handoffs
  • Structured format with recovery instructions

Built-in Skills (optional manual use)

  • /continuity_ledger - Create/update ledger
  • /create_handoff - Manual handoff creation
  • /resume_handoff - Load handoff after /clear

Edge Cases Handled

  • Session names with invalid filesystem characters
  • Very long session names (truncation)
  • Empty/malformed markdown files
  • Race conditions during file enumeration
  • Unicode content (日本語, emojis)
  • Concurrent rapid updates
  • Shallow config merging for nested objects

Tests

  • 30 tests for LedgerManager (including 14 edge case tests)
  • 5 tests for auto-continuity handoff structure
  • 7 tests for builtin skills registration
  • 661/663 tests passing (2 pre-existing MCP loader failures unrelated)

Commits

  1. feat: add continuity ledger system - Core implementation
  2. test: add comprehensive tests - 28 tests
  3. fix: harden with edge case handling - Security & robustness
  4. feat: make continuity fully automatic - Zero-config automation

- Add continuity-ledger feature for markdown-based state tracking
- Add auto-continuity hook for context monitoring and warnings
- Add 3 built-in skills: continuity_ledger, create_handoff, resume_handoff
- Monitor context usage with progressive warnings (60%, 80%, 85%)
- Auto-save handoffs at critical threshold to prevent token overflow
- Support ledger recovery after /clear operations

Inspired by Continuous Claude v2 concepts for preserving session state.
- Add 16 tests for LedgerManager (create, load, update, prune)
- Add 5 tests for auto-continuity handoff structure
- Add 7 tests for builtin skills registration
- All 28 new tests passing
@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 2026

Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA).

To sign the CLA, please comment on this PR with:

I have read the CLA Document and I hereby sign the CLA

This is a one-time requirement. Once signed, all your future contributions will be automatically accepted.


I have read the CLA Document and I hereby sign the CLA


1 out of 2 committers have signed the CLA.
✅ (code-yeongyu)[https://github.com/code-yeongyu]
@xkonjin
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@greptile-apps
Copy link

greptile-apps bot commented Jan 5, 2026

Greptile Summary

Adds comprehensive continuity ledger system for preserving session state across /clear operations, with automatic context monitoring and handoff generation. The PR also modernizes command/skill loaders to async/await and removes the websearch_exa MCP.

Key Changes:

  • Continuity Ledger System: New LedgerManager class creates structured markdown ledgers (thoughts/ledgers/CONTINUITY_CLAUDE-{session}.md) that track goals, constraints, key decisions, state (done/now/next), working set (branch, files, commands), and agent reports with auto-pruning (max 10)

  • Auto-Continuity Hook: Monitors context window usage with three thresholds—60% yellow warning (20% chance), 80% red warning, 85% critical auto-save. Automatically generates handoffs at critical threshold and displays toast notifications

  • Handoff System: Manual (/create_handoff) and auto-generated handoffs saved to thoughts/shared/handoffs/{session}/ with structured format including recovery instructions. Resume via /resume_handoff skill

  • Built-in Skills: Four new skills added—/continuity_ledger for ledger management, /create_handoff for manual handoffs, /resume_handoff for context restoration, plus existing playwright skill

  • Async Loader Refactoring: Command and skill loaders migrated to async-first design with parallel discovery via Promise.all. Functions renamed (removed Async suffix: discoverUserClaudeSkillsAsyncdiscoverUserClaudeSkills)

  • Agent-Aware Keyword Detector: resolveMessage function now accepts optional agentName parameter to enable dynamic, context-aware keyword detection messages

  • Planner-Sisyphus Mode: Set to "primary" for proper tab visibility, messages use variant="max"

  • MCP Updates: Removed websearch_exa MCP, updated docs. disabled_mcps now accepts any MCP name via AnyMcpNameSchema

  • Test Coverage: 28 new tests—16 for LedgerManager, 5 for auto-continuity handoff structure, 7 for builtin skills registration. All passing (647/649 total, 2 pre-existing MCP loader failures unrelated)

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Score reflects comprehensive test coverage (28 new tests, all passing), clean architecture following project conventions, proper async/await patterns, no breaking changes to existing APIs, and thorough documentation in skill templates
  • No files require special attention

Important Files Changed

Filename Overview
src/features/continuity-ledger/manager.ts Implements LedgerManager class for creating, loading, parsing, and persisting continuity ledgers with proper file I/O, state management, and agent report pruning
src/hooks/auto-continuity/index.ts Implements auto-continuity hook with context monitoring, threshold-based warnings (60%/80%/85%), auto-handoff generation, and toast notifications
src/features/builtin-skills/skills.ts Added four continuity-related skills (continuity_ledger, create_handoff, resume_handoff) with comprehensive templates and instructions
src/features/claude-code-command-loader/loader.ts Refactored to async/await with parallel discovery via Promise.all for command loading from multiple directories
src/features/opencode-skill-loader/loader.ts Migrated to async-first design with parallel skill discovery and renamed functions (removed Async suffix for cleaner API)
src/index.ts Integrated auto-continuity hook, updated async skill loader calls, and added variant="max" for Sisyphus agent messages

Sequence Diagram

sequenceDiagram
    participant User
    participant Hook as Auto-Continuity Hook
    participant LM as LedgerManager
    participant Skills as Builtin Skills
    participant FS as File System
    
    Note over User,FS: Session Start
    User->>Hook: Start session
    Hook->>LM: findLatestLedger()
    LM->>FS: Read thoughts/ledgers/CONTINUITY_CLAUDE-*.md
    FS-->>LM: Ledger content
    LM-->>Hook: Latest ledger loaded
    
    Note over User,FS: Context Window Monitoring
    User->>Hook: Execute tool (edit/write/bash)
    Hook->>Hook: Check token usage via session.messages()
    alt Context < 60%
        Hook-->>User: No warning
    else Context 60-80%
        Hook-->>User: 🟡 Yellow warning (20% chance)
    else Context 80-85%
        Hook-->>User: 🟠 Red warning via toast
    else Context >= 85%
        Hook->>LM: Save current ledger state
        Hook->>FS: Write thoughts/shared/handoffs/{session}/auto-handoff-*.md
        FS-->>Hook: Handoff saved
        Hook-->>User: 🔴 CRITICAL - Auto-handoff saved, run /clear
    end
    
    Note over User,FS: Manual Ledger Management
    User->>Skills: /continuity_ledger
    Skills->>LM: createLedger() or updateState()
    LM->>FS: Write thoughts/ledgers/CONTINUITY_CLAUDE-{session}.md
    FS-->>LM: Ledger saved
    LM-->>Skills: Updated ledger
    Skills-->>User: Ledger created/updated
    
    Note over User,FS: Manual Handoff
    User->>Skills: /create_handoff
    Skills->>LM: Load current ledger state
    LM-->>Skills: Ledger data
    Skills->>FS: Write thoughts/shared/handoffs/{session}/handoff-*.md
    FS-->>Skills: Handoff saved
    Skills-->>User: Handoff created
    
    Note over User,FS: Recovery After /clear
    User->>User: Run /clear
    User->>Skills: /resume_handoff
    Skills->>FS: Read thoughts/shared/handoffs/*/
    FS-->>Skills: Latest handoff
    Skills->>LM: Parse and restore state
    LM-->>Skills: Restored ledger
    Skills-->>User: Context restored with summary
    
    Note over User,FS: Agent Reports
    User->>Hook: Agent task completes
    Hook->>LM: addAgentReport(ledger, agent, summary)
    LM->>LM: Auto-prune to maxAgentReports (10)
    LM->>FS: Update ledger file
    FS-->>LM: Saved
    LM-->>Hook: Updated ledger
Loading

@greptile-apps
Copy link

greptile-apps bot commented Jan 5, 2026

Greptile found no issues!

From now on, if a review finishes and we haven't found any issues, we will not post anything, but you can confirm that we reviewed your changes in the status check section.

This feature can be toggled off in your Code Review Settings by deselecting "Create a status check for each PR".

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.

9 issues found across 41 files

Confidence score: 2/5

  • Two separate path-traversal vulnerabilities in src/features/continuity-ledger/manager.ts let untrusted filename and sessionName escape the ledger directory, posing a concrete security risk that should block merging until sanitized.
  • Additional async calls in src/tools/skill/tools.ts and src/tools/slashcommand/tools.ts lack rejection handling, so a failing description builder could crash or leave stale state, further increasing regression risk.
  • Pay close attention to src/features/continuity-ledger/manager.ts, src/tools/skill/tools.ts, and src/tools/slashcommand/tools.ts – these files need sanitization and defensive error handling before merge.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/hooks/auto-continuity/index.ts">

<violation number="1" location="src/hooks/auto-continuity/index.ts:348">
P2: Empty catch block silently swallows all API errors. While graceful degradation is a valid pattern, consider logging the error to aid debugging when the session messages API call fails.</violation>
</file>

<file name="src/hooks/auto-continuity/index.test.ts">

<violation number="1" location="src/hooks/auto-continuity/index.test.ts:116">
P2: These threshold tests are tautological - they test hardcoded arithmetic (`0.6 &gt;= 0.6`) rather than actual implementation code. They provide false confidence in test coverage. Consider importing the actual threshold detection functions and testing those instead.</violation>
</file>

<file name="src/features/continuity-ledger/types.ts">

<violation number="1" location="src/features/continuity-ledger/types.ts:66">
P2: Redundant configuration: `autoSaveThreshold` and `contextThresholds.critical` both represent the auto-save trigger (both default to 0.85, and the comment on `critical` says &quot;Auto-save trigger&quot;). Consider removing `autoSaveThreshold` and using `contextThresholds.critical` directly, or clarify in comments that they serve different purposes.</violation>
</file>

<file name="src/tools/slashcommand/tools.ts">

<violation number="1" location="src/tools/slashcommand/tools.ts:171">
P2: Missing error handling for the async `buildDescription()` call. If the promise rejects, it will cause an unhandled promise rejection and leave `cachedDescription` stuck at the placeholder value. Consider adding a `.catch()` handler to log errors and/or retry.</violation>
</file>

<file name="src/tools/skill/tools.ts">

<violation number="1" location="src/tools/skill/tools.ts:152">
P1: Unhandled promise rejection. The async `getDescription()` call should have error handling. Consider adding `.catch()` or use `void` to indicate intentional fire-and-forget.</violation>
</file>

<file name="src/features/continuity-ledger/manager.test.ts">

<violation number="1" location="src/features/continuity-ledger/manager.test.ts:88">
P2: Flaky test: 10ms `setTimeout` may not guarantee different file modification timestamps across all filesystems. File system timestamp resolution can be as coarse as 1 second on some systems, causing intermittent test failures. Consider mocking the timestamp mechanism, using explicit timestamps if supported by the API, or increasing the delay to at least 1000ms (though mocking is preferred).</violation>
</file>

<file name="src/agents/librarian.ts">

<violation number="1" location="src/agents/librarian.ts:139">
P2: Inconsistent parallel call requirements. The inline instruction now says 5+ calls for TYPE D, but the PARALLEL EXECUTION REQUIREMENTS table at the bottom of the file still says 6+. Either update the table to match or keep both values consistent.</violation>
</file>

<file name="src/features/continuity-ledger/manager.ts">

<violation number="1" location="src/features/continuity-ledger/manager.ts:51">
P1: Path traversal vulnerability: `filename` is used directly in `path.join` without sanitization. If this public method receives untrusted input containing `../`, it could read files outside the ledger directory. Consider using `path.basename(filename)` to extract only the filename component.</violation>

<violation number="2" location="src/features/continuity-ledger/manager.ts:173">
P1: Path traversal vulnerability: `sessionName` is used directly in filename construction without sanitization. If it contains path separators (e.g., `../malicious`), files could be written outside the ledger directory. Consider sanitizing the session name to remove or replace path separators and invalid filename characters.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

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

if (notification) {
output.output += `\n\n${notification}`;
}
} catch {
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: Empty catch block silently swallows all API errors. While graceful degradation is a valid pattern, consider logging the error to aid debugging when the session messages API call fails.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/auto-continuity/index.ts, line 348:

<comment>Empty catch block silently swallows all API errors. While graceful degradation is a valid pattern, consider logging the error to aid debugging when the session messages API call fails.</comment>

<file context>
@@ -0,0 +1,359 @@
+      if (notification) {
+        output.output += `\n\n${notification}`;
+      }
+    } catch {
+      // Graceful degradation
+    }
</file context>
Fix with Cubic

});

describe("context threshold detection", () => {
test("yellow threshold at 60%", () => {
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: These threshold tests are tautological - they test hardcoded arithmetic (0.6 >= 0.6) rather than actual implementation code. They provide false confidence in test coverage. Consider importing the actual threshold detection functions and testing those instead.

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

<comment>These threshold tests are tautological - they test hardcoded arithmetic (`0.6 &gt;= 0.6`) rather than actual implementation code. They provide false confidence in test coverage. Consider importing the actual threshold detection functions and testing those instead.</comment>

<file context>
@@ -0,0 +1,134 @@
+  });
+
+  describe(&quot;context threshold detection&quot;, () =&gt; {
+    test(&quot;yellow threshold at 60%&quot;, () =&gt; {
+      const contextPct = 0.6;
+      const isYellow = contextPct &gt;= 0.6 &amp;&amp; contextPct &lt; 0.8;
</file context>
Fix with Cubic

/** Ledger configuration */
ledger: LedgerConfig;
/** Auto-save threshold (percentage of context window, 0-1) */
autoSaveThreshold: number;
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: Redundant configuration: autoSaveThreshold and contextThresholds.critical both represent the auto-save trigger (both default to 0.85, and the comment on critical says "Auto-save trigger"). Consider removing autoSaveThreshold and using contextThresholds.critical directly, or clarify in comments that they serve different purposes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/continuity-ledger/types.ts, line 66:

<comment>Redundant configuration: `autoSaveThreshold` and `contextThresholds.critical` both represent the auto-save trigger (both default to 0.85, and the comment on `critical` says &quot;Auto-save trigger&quot;). Consider removing `autoSaveThreshold` and using `contextThresholds.critical` directly, or clarify in comments that they serve different purposes.</comment>

<file context>
@@ -0,0 +1,87 @@
+  /** Ledger configuration */
+  ledger: LedgerConfig;
+  /** Auto-save threshold (percentage of context window, 0-1) */
+  autoSaveThreshold: number;
+  /** Auto-clear after saving (instead of compact) */
+  autoClearAfterSave: boolean;
</file context>
Fix with Cubic

get description() {
if (!cachedDescription) {
cachedDescription = "Loading available commands and skills..."
buildDescription().then(desc => { cachedDescription = desc })
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: Missing error handling for the async buildDescription() call. If the promise rejects, it will cause an unhandled promise rejection and leave cachedDescription stuck at the placeholder value. Consider adding a .catch() handler to log errors and/or retry.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tools/slashcommand/tools.ts, line 171:

<comment>Missing error handling for the async `buildDescription()` call. If the promise rejects, it will cause an unhandled promise rejection and leave `cachedDescription` stuck at the placeholder value. Consider adding a `.catch()` handler to log errors and/or retry.</comment>

<file context>
@@ -151,15 +138,40 @@ function formatCommandList(items: CommandInfo[]): string {
+  get description() {
+    if (!cachedDescription) {
+      cachedDescription = &quot;Loading available commands and skills...&quot;
+      buildDescription().then(desc =&gt; { cachedDescription = desc })
+    }
+    return cachedDescription
</file context>
Fix with Cubic

const description = skillInfos.length === 0
? TOOL_DESCRIPTION_NO_SKILLS
: TOOL_DESCRIPTION_PREFIX + formatSkillsXml(skillInfos)
getDescription()
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P1: Unhandled promise rejection. The async getDescription() call should have error handling. Consider adding .catch() or use void to indicate intentional fire-and-forget.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tools/skill/tools.ts, line 152:

<comment>Unhandled promise rejection. The async `getDescription()` call should have error handling. Consider adding `.catch()` or use `void` to indicate intentional fire-and-forget.</comment>

<file context>
@@ -129,22 +129,38 @@ async function formatMcpCapabilities(
-  const description = skillInfos.length === 0
-    ? TOOL_DESCRIPTION_NO_SKILLS
-    : TOOL_DESCRIPTION_PREFIX + formatSkillsXml(skillInfos)
+  getDescription()
 
   return tool({
</file context>
Fix with Cubic

test("finds the most recent ledger", async () => {
// #given
manager.createLedger("session-old", { goal: "Old session" });
await new Promise((resolve) => setTimeout(resolve, 10));
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: Flaky test: 10ms setTimeout may not guarantee different file modification timestamps across all filesystems. File system timestamp resolution can be as coarse as 1 second on some systems, causing intermittent test failures. Consider mocking the timestamp mechanism, using explicit timestamps if supported by the API, or increasing the delay to at least 1000ms (though mocking is preferred).

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

<comment>Flaky test: 10ms `setTimeout` may not guarantee different file modification timestamps across all filesystems. File system timestamp resolution can be as coarse as 1 second on some systems, causing intermittent test failures. Consider mocking the timestamp mechanism, using explicit timestamps if supported by the API, or increasing the delay to at least 1000ms (though mocking is preferred).</comment>

<file context>
@@ -0,0 +1,291 @@
+    test(&quot;finds the most recent ledger&quot;, async () =&gt; {
+      // #given
+      manager.createLedger(&quot;session-old&quot;, { goal: &quot;Old session&quot; });
+      await new Promise((resolve) =&gt; setTimeout(resolve, 10));
+      manager.createLedger(&quot;session-new&quot;, { goal: &quot;New session&quot; });
+
</file context>
Fix with Cubic

**Trigger**: Complex questions, ambiguous requests, "deep dive into..."
**Execute ALL in parallel (6+ calls)**:
**Execute ALL available tools in parallel (5+ calls)**:
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: Inconsistent parallel call requirements. The inline instruction now says 5+ calls for TYPE D, but the PARALLEL EXECUTION REQUIREMENTS table at the bottom of the file still says 6+. Either update the table to match or keep both values consistent.

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

<comment>Inconsistent parallel call requirements. The inline instruction now says 5+ calls for TYPE D, but the PARALLEL EXECUTION REQUIREMENTS table at the bottom of the file still says 6+. Either update the table to match or keep both values consistent.</comment>

<file context>
@@ -136,21 +136,22 @@ gh api repos/owner/repo/pulls/&lt;number&gt;/files
 **Trigger**: Complex questions, ambiguous requests, &quot;deep dive into...&quot;
 
-**Execute ALL in parallel (6+ calls)**:
+**Execute ALL available tools in parallel (5+ calls)**:
 \`\`\`
-// Documentation &amp; Web
</file context>
Fix with Cubic

return this.loadLedger(files[0]);
}

loadLedger(filename: string): Ledger | null {
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P1: Path traversal vulnerability: filename is used directly in path.join without sanitization. If this public method receives untrusted input containing ../, it could read files outside the ledger directory. Consider using path.basename(filename) to extract only the filename component.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/continuity-ledger/manager.ts, line 51:

<comment>Path traversal vulnerability: `filename` is used directly in `path.join` without sanitization. If this public method receives untrusted input containing `../`, it could read files outside the ledger directory. Consider using `path.basename(filename)` to extract only the filename component.</comment>

<file context>
@@ -0,0 +1,359 @@
+    return this.loadLedger(files[0]);
+  }
+
+  loadLedger(filename: string): Ledger | null {
+    const filePath = path.join(this.ledgerDir, filename);
+    if (!fs.existsSync(filePath)) {
</file context>
Fix with Cubic

- Add session name sanitization for invalid filesystem characters
- Fix race condition in findLatestLedger when files are deleted
- Fix state parsing to handle placeholder values correctly
- Fix shallow config merging for nested contextThresholds
- Include reasoning tokens in context usage calculation
- Add filename sanitization for handoff files
- Remove unused color variable in generateStatusLine
- Fix filter condition from !== undefined to !== ''

Edge case tests added:
- Session names with invalid chars (<>:"/\|?*)
- Very long session names (truncation)
- Empty session names
- Placeholder values in state parsing
- Empty/malformed markdown files
- Unicode content (日本語, émojis)
- Concurrent rapid updates
- Files with special characters

All 661 tests passing (2 pre-existing MCP failures unrelated)
- Auto-create ledger on first session if none exists
- Auto-inject ledger context on first user message
- Auto-sync ledger state with todo list updates
- Ledger now tracks: done (last 10), now (in_progress), next (first 5)

No manual intervention needed - continuity just works.
- Fix disabled hook to return both handlers
- Add injection guard to prevent duplicate context injection
- Add session pruning to prevent memory leak (keep last 100)
- Improve todo parsing with type validation
- Clean UNCONFIRMED prefix duplication in context generation
- Add 8 new edge case tests for hook behavior

Tests: 669/671 passing (43 continuity tests)
- Add atomic writes to saveLedger() using temp file + rename
- Add atomic writes to saveAutoHandoff() with same pattern
- Add stale ledger recovery when todo sync fails
- Replace random 20% yellow warning with deterministic once-per-session
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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/hooks/auto-continuity/index.ts">

<violation number="1" location="src/hooks/auto-continuity/index.ts:280">
P2: The `yellowWarningShown` flag is not reset when a new session is created. The comment says &quot;show once per session&quot; but since this flag isn&#39;t reset in the `session.created` handler (where `autoSaveTriggered` is reset), users will only ever see the yellow warning once across all sessions, not once per session.</violation>
</file>

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


// Yellow threshold - show once per session when first crossing
if (contextPct >= yellow && contextPct < red && !state.yellowWarningShown) {
state.yellowWarningShown = true;
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P2: The yellowWarningShown flag is not reset when a new session is created. The comment says "show once per session" but since this flag isn't reset in the session.created handler (where autoSaveTriggered is reset), users will only ever see the yellow warning once across all sessions, not once per session.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/auto-continuity/index.ts, line 280:

<comment>The `yellowWarningShown` flag is not reset when a new session is created. The comment says &quot;show once per session&quot; but since this flag isn&#39;t reset in the `session.created` handler (where `autoSaveTriggered` is reset), users will only ever see the yellow warning once across all sessions, not once per session.</comment>

<file context>
@@ -261,11 +275,10 @@ export function createAutoContinuityHook(
-      }
+    // Yellow threshold - show once per session when first crossing
+    if (contextPct &gt;= yellow &amp;&amp; contextPct &lt; red &amp;&amp; !state.yellowWarningShown) {
+      state.yellowWarningShown = true;
+      return `🟡 Context at ${(contextPct * 100).toFixed(1)}%. Plan a good stopping point for handoff.`;
     }
</file context>
Fix with Cubic

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