Skip to content

fix(core): deep copy in wouldCreateCycle() prevents graph corruption + settling workers tracking#32

Merged
dean0x merged 13 commits intomainfrom
fix/issue-28-graph-corruption-shallow-copy
Nov 28, 2025
Merged

fix(core): deep copy in wouldCreateCycle() prevents graph corruption + settling workers tracking#32
dean0x merged 13 commits intomainfrom
fix/issue-28-graph-corruption-shallow-copy

Conversation

@dean0x
Copy link
Owner

@dean0x dean0x commented Nov 28, 2025

User description

Summary

  • Critical security fix: Resolves graph corruption bug in DependencyGraph.wouldCreateCycle() where shallow copy allowed cycle checks to mutate the original graph state (Issue CRITICAL: Shallow copy in wouldCreateCycle() corrupts dependency graph #28)
  • Performance enhancement: Adds settling workers tracking to ResourceMonitor to prevent spawn burst overload when load average hasn't caught up with recent spawns
  • Defense-in-depth: Increases default minSpawnDelayMs from 50ms to 1000ms for additional protection

Changes

Bug Fixes

Graph Corruption Prevention (Issue #28)

  • src/core/dependency-graph.ts: Changed from shallow copy (new Map(this.graph)) to deep copy that properly clones Set values
  • Root cause: JavaScript's Map constructor only copies the Map structure; Set values remained as references to original Sets
  • Impact: Without this fix, calling wouldCreateCycle() could permanently add edges to the dependency graph

Performance Improvements

Settling Workers Tracking

  • src/implementations/resource-monitor.ts: Added recentSpawnTimestamps array to track workers spawned within a 15-second settling window
  • src/implementations/resource-monitor.ts: Added recordSpawn() method to record spawn events
  • src/services/handlers/worker-handler.ts: Calls resourceMonitor.recordSpawn() after successful spawn
  • src/core/interfaces.ts: Added optional recordSpawn() method to ResourceMonitor interface
  • Problem solved: Load average is a 1-minute rolling average that doesn't reflect sudden resource spikes

Configuration Changes

  • src/core/configuration.ts: Increased minSpawnDelayMs default from 50ms to 1000ms

Tests

  • tests/unit/core/dependency-graph.test.ts: Added 3 regression tests verifying graph immutability after cycle checks

Breaking Changes

None. The recordSpawn() method is optional on the ResourceMonitor interface for backwards compatibility.

Testing

Test Coverage

  • 3 new test cases in dependency-graph.test.ts
  • Tests verify immutability by capturing graph state before/after wouldCreateCycle()

Manual Testing Recommendations

  1. Submit multiple tasks with complex dependencies and verify graph consistency
  2. Trigger burst task submission (5+ tasks rapidly) and verify no spawn overload
  3. Monitor resource usage during high-load scenarios

Testing Gaps

  • Settling workers tracking logic not unit tested (relies on integration behavior)

Related Issues

Fixes #28


🤖 Generated with Claude Code


PR Type

Bug fix, Enhancement


Description

  • Fix critical graph corruption bug in wouldCreateCycle() using deep copy

    • Prevents shallow copy from mutating original graph's Set values
    • Adds 3 regression tests verifying immutability after cycle checks
  • Add settling workers tracking to prevent spawn burst overload

    • Tracks recently spawned workers within 15-second settling window
    • Projects resource usage before load average reflects new spawns
    • Calls recordSpawn() after successful worker spawn
  • Increase default minSpawnDelayMs from 50ms to 1000ms for additional protection


Diagram Walkthrough

flowchart LR
  A["wouldCreateCycle<br/>shallow copy bug"] -->|"deep copy fix"| B["Graph immutability<br/>preserved"]
  C["Load average<br/>lagging indicator"] -->|"settling window<br/>tracking"| D["Resource projection<br/>prevents overload"]
  E["minSpawnDelayMs<br/>50ms"] -->|"increase to"| F["1000ms<br/>defense-in-depth"]
  B --> G["3 regression<br/>tests added"]
  D --> H["recordSpawn()<br/>method added"]
Loading

File Walkthrough

Relevant files
Bug fix
dependency-graph.ts
Deep copy implementation prevents graph mutation                 

src/core/dependency-graph.ts

  • Changed shallow copy to deep copy in wouldCreateCycle() method
  • Uses Array.from().map() to create new Set instances for each graph
    entry
  • Added security fix comment explaining the shallow copy vulnerability
+6/-1     
Enhancement
interfaces.ts
Add recordSpawn method to ResourceMonitor interface           

src/core/interfaces.ts

  • Added optional recordSpawn?() method to ResourceMonitor interface
  • Includes JSDoc explaining settling worker tracking purpose
  • Maintains backwards compatibility with optional method signature
+6/-0     
resource-monitor.ts
Implement settling workers tracking and resource projection

src/implementations/resource-monitor.ts

  • Added recentSpawnTimestamps array and SETTLING_WINDOW_MS constant (15
    seconds)
  • Implemented recordSpawn() method to track spawn events
  • Modified canSpawnWorker() to clean old timestamps and project resource
    usage
  • Adjusted CPU and memory availability calculations to account for
    settling workers
  • Updated debug logging to include settling worker counts
+54/-13 
worker-handler.ts
Call recordSpawn after worker spawn event                               

src/services/handlers/worker-handler.ts

  • Added call to resourceMonitor.recordSpawn?.() after successful worker
    spawn
  • Tracks spawn event for settling window resource calculations
  • Uses optional chaining for backwards compatibility
+3/-0     
Configuration changes
configuration.ts
Increase minSpawnDelayMs default to 1000ms                             

src/core/configuration.ts

  • Updated minSpawnDelayMs default from 50ms to 1000ms in schema
  • Updated minSpawnDelayMs default from 50ms to 1000ms in DEFAULT_CONFIG
  • Updated comments to reference settling worker tracking
  • Increased max allowed value from 10000ms to 30000ms
+2/-2     
Tests
dependency-graph.test.ts
Add regression tests for graph immutability                           

tests/unit/core/dependency-graph.test.ts

  • Added 3 regression tests in new "Cycle Detection - Immutability (Issue
    CRITICAL: Shallow copy in wouldCreateCycle() corrupts dependency graph #28)" suite
  • Test 1: Verifies graph unchanged when cycle is detected with existing
    task
  • Test 2: Verifies graph unchanged when no cycle is detected
  • Test 3: Verifies multiple successive cycle checks don't accumulate
    corruption
  • Tests capture graph state before/after cycle checks and verify
    immutability
+92/-0   

Dean Sharon and others added 2 commits November 28, 2025 08:45
…28)

CRITICAL SECURITY FIX: The previous shallow copy using `new Map(this.graph)`
only copied the Map structure - Set values remained as references to the
original Sets. When checking for cycles, modifications to the temporary
graph's Sets would mutate the original graph's Sets, corrupting state.

Root cause: JavaScript's Map constructor creates shallow copies. For a Map<K, Set<V>>,
the Set values are references, not copies.

Fix: Deep copy using Array.from with mapped new Set() instances:
`new Map(Array.from(this.graph.entries()).map(([k, v]) => [k, new Set(v)]))`

Added 3 regression tests to verify immutability after cycle checks:
- Graph unchanged after detecting would-create-cycle
- Graph unchanged after detecting no-cycle
- Graph unchanged after multiple sequential cycle checks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Load average (os.loadavg()) is a 1-minute rolling average that
doesn't reflect sudden resource spikes from recent spawns. The resource
monitor could approve multiple spawns before load average caught up,
causing fork-bomb scenarios during recovery or burst task submission.

Solution: Track recently spawned workers in a "settling window" (15 seconds)
and project their resource usage when deciding if more workers can spawn.

Changes:
- Add recentSpawnTimestamps array to track spawns within settling window
- Project CPU and memory usage including settling workers
- Add recordSpawn() method to ResourceMonitor interface (optional for
  backwards compatibility with existing implementations)
- Call recordSpawn() from WorkerHandler after successful spawn
- Increase default minSpawnDelayMs from 50ms to 1000ms for additional
  protection with the settling worker tracking

This works in conjunction with the existing spawn delay to provide
defense-in-depth against resource exhaustion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Nov 28, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Spawn tracking manipulation

Description: The recordSpawn() method lacks validation and can be called multiple times for the same
spawn event, potentially causing incorrect resource projections and allowing spawn burst
overload that the settling window tracking is designed to prevent. resource-monitor.ts [175-181]

Referred Code
recordSpawn(): void {
  this.recentSpawnTimestamps.push(Date.now());
  this.logger?.debug('Recorded spawn for settling tracking', {
    settlingWorkers: this.recentSpawnTimestamps.length,
    settlingWindowMs: this.SETTLING_WINDOW_MS
  });
}
Ticket Compliance
🟢
🎫 #28
🟢 Fix shallow copy bug in wouldCreateCycle() method at line 218 of
src/core/dependency-graph.ts
Implement deep copy that clones both Map structure and Set values to prevent mutation of
original graph
Prevent data corruption where proposed edges are permanently added to graph during cycle
checks
Ensure cycle detection operations don't mutate the original dependency graph state
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Unstructured Debug Logging: Debug log statements use unstructured format with object literals instead of structured
JSON logging for auditing and monitoring.

Referred Code
this.logger?.debug('Cannot spawn: Max workers limit reached (including settling)', {
  currentWorkers: this.workerCount,
  settlingWorkers,
  effectiveWorkerCount,
  maxWorkers: this.maxWorkers
});

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Nov 28, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Make resource estimates configurable

The hardcoded resource estimates for CPU and memory in the "settling worker"
logic should be made configurable. This change would allow for better tuning in
different deployment environments.

Examples:

src/implementations/resource-monitor.ts [24-25]
  private readonly MEMORY_PER_WORKER_MB = 450; // ~410MB observed + buffer
  private readonly CORES_PER_WORKER = 0.15; // ~11-15% of one core observed

Solution Walkthrough:

Before:

// src/implementations/resource-monitor.ts
export class SystemResourceMonitor implements ResourceMonitor {
  // Per-worker resource estimates are hardcoded based on observation
  private readonly MEMORY_PER_WORKER_MB = 450; // ~410MB observed + buffer
  private readonly CORES_PER_WORKER = 0.15; // ~11-15% of one core observed

  // ...

  async canSpawnWorker(): Promise<Result<boolean>> {
    // ...
    const settlingWorkers = this.recentSpawnTimestamps.length;
    
    // Projected usage is calculated using the hardcoded constants
    const projectedCoresUsed = settlingWorkers * this.CORES_PER_WORKER;
    const projectedMemoryUsed = settlingWorkers * this.MEMORY_PER_WORKER_MB * 1024 * 1024;
    
    // ... logic uses projected usage to decide if a worker can be spawned
  }
}

After:

// src/core/configuration.ts
export const ConfigurationSchema = z.object({
  // ...
  projectedMemoryPerWorkerMb: z.number().min(50).default(450),
  projectedCoresPerWorker: z.number().min(0.01).default(0.15),
});

// src/implementations/resource-monitor.ts
export class SystemResourceMonitor implements ResourceMonitor {
  private readonly memoryPerWorkerMb: number;
  private readonly coresPerWorker: number;

  constructor(config: Configuration, ...) {
    // Estimates are now read from the main configuration
    this.memoryPerWorkerMb = config.projectedMemoryPerWorkerMb;
    this.coresPerWorker = config.projectedCoresPerWorker;
    // ...
  }

  async canSpawnWorker(): Promise<Result<boolean>> {
    // ...
    // Projected usage is now calculated using configurable values
    const projectedCoresUsed = settlingWorkers * this.coresPerWorker;
    // ...
  }
}
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that the new "settling worker" feature relies on hardcoded resource estimates (MEMORY_PER_WORKER_MB and CORES_PER_WORKER), which is a significant design flaw that limits the feature's adaptability and reliability across different environments.

Medium
Possible issue
Prevent a potential memory leak
Suggestion Impact:The suggestion was directly implemented. The commit adds the cleanup logic (filtering old timestamps) to the recordSpawn method exactly as suggested, preventing unbounded array growth if recordSpawn is called without canSpawnWorker. The implementation matches the suggestion's intent and code structure.

code diff:

   recordSpawn(): void {
-    this.recentSpawnTimestamps.push(Date.now());
+    const now = Date.now();
+    // Clean up expired timestamps to prevent unbounded array growth
+    this.recentSpawnTimestamps = this.recentSpawnTimestamps.filter(
+      t => now - t < this.settlingWindowMs
+    );
+    this.recentSpawnTimestamps.push(now);
     this.logger?.debug('Recorded spawn for settling tracking', {
       settlingWorkers: this.recentSpawnTimestamps.length,
-      settlingWindowMs: this.SETTLING_WINDOW_MS
+      settlingWindowMs: this.settlingWindowMs
     });

Move the cleanup logic for recentSpawnTimestamps from canSpawnWorker to
recordSpawn to prevent a potential memory leak and improve class encapsulation.

src/implementations/resource-monitor.ts [175-181]

 recordSpawn(): void {
-  this.recentSpawnTimestamps.push(Date.now());
+  const now = Date.now();
+  // Prune old timestamps to prevent memory leak if canSpawnWorker isn't called
+  this.recentSpawnTimestamps = this.recentSpawnTimestamps.filter(
+    t => now - t < this.SETTLING_WINDOW_MS
+  );
+  this.recentSpawnTimestamps.push(now);
   this.logger?.debug('Recorded spawn for settling tracking', {
     settlingWorkers: this.recentSpawnTimestamps.length,
     settlingWindowMs: this.SETTLING_WINDOW_MS
   });
 }

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: This suggestion correctly identifies a potential memory leak if recordSpawn were ever called without a preceding call to canSpawnWorker. Moving the cleanup logic into recordSpawn makes the SystemResourceMonitor class more robust and self-contained, which is a valuable improvement for maintainability.

Medium
  • Update

Dean Sharon and others added 6 commits November 28, 2025 10:54
Fix 3 security issues identified by npm audit:
- glob CLI command injection (HIGH) - GHSA-5j98-mcp5-4vw2
- body-parser denial of service (MODERATE) - GHSA-wqch-xfxh-vrr4
- vite path traversal on Windows (MODERATE) - GHSA-93m4-6634-74q7

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Previously, configuration validation failures silently fell back to
defaults, making it difficult to discover environment variable
typos or invalid values. Now logs a warning with specific errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Improves type safety by using the proper Worker domain type
instead of any[] for the workers array return type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…kers tests

- Implement recordSpawn() no-op in TestResourceMonitor for interface compatibility
- Add 5 unit tests for settling workers tracking:
  - recordSpawn() does not throw
  - settling workers included in effective count
  - settling workers expire after 15 second window
  - settling workers persist within window
  - resource usage projection limits spawning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Update wouldCreateCycle() line reference from 50 to 240 in TASK-DEPENDENCIES.md
- Add deep copy pattern with explanation in TASK_ARCHITECTURE.md
- Document why shallow copy (new Map(this.graph)) corrupts graph

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive changelog entries for recent work:
- Security fixes (graph corruption, npm audit, config validation)
- Performance improvements (settling workers tracking)
- Technical improvements (type safety, test compatibility)
- Test coverage (settling workers, graph immutability)
- Documentation updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
recordSpawn?(): void;
}

/**
Copy link
Owner Author

Choose a reason for hiding this comment

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

[WARNING] Architecture: Optional Method Pattern Inconsistency

Making recordSpawn() optional violates the Interface Segregation Principle (ISP). This creates caller burden (requires optional chaining recordSpawn?.()) and implementation ambiguity.

Option 1: Make it required with no-op default (preferred)

export interface ResourceMonitor {
  // ... existing methods ...
  recordSpawn(): void;  // Required, implementors can no-op
}

Option 2: Use Interface Segregation

export interface ResourceMonitor { /* base methods */ }
export interface SettlingAwareResourceMonitor extends ResourceMonitor {
  recordSpawn(): void;
}

Comparison

Approach Pros Cons
Required method Simple, consistent contract Breaks existing implementations
Interface segregation Type-safe, backward compatible More complex type hierarchy

Recommended: Option 1 - Simpler and forces implementors to consciously handle spawn tracking.


From: architecture audit | Severity: MEDIUM


Generated by Claude Code via /code-review

// SETTLING WORKERS TRACKING (Issue: load average is lagging indicator)
// Workers that were recently spawned but may not yet be reflected in system metrics
// This prevents spawning too many workers before load average catches up
private readonly SETTLING_WINDOW_MS = 15000; // 15 seconds for worker to "settle"
Copy link
Owner Author

Choose a reason for hiding this comment

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

[WARNING] Complexity: Magic Number for Settling Window

The 15-second settling window is hardcoded. While documented with a comment, this value should ideally be configurable or derived from a configuration constant.

Suggested Fix:

// Option A: Make configurable via Configuration schema
private readonly SETTLING_WINDOW_MS: number;
constructor(config: Configuration) {
  this.SETTLING_WINDOW_MS = config.workerSettlingWindowMs ?? 15000;
}

// Option B: Document relationship to other timings
// SETTLING_WINDOW_MS should be >= 3 * resourceMonitorIntervalMs (default 5000)
private readonly SETTLING_WINDOW_MS = 15000;

Why: Hardcoded values reduce configurability and make tuning difficult for different deployment scenarios.


From: complexity audit | Severity: MEDIUM


Generated by Claude Code via /code-review

// Workers that were recently spawned but may not yet be reflected in system metrics
// This prevents spawning too many workers before load average catches up
private readonly SETTLING_WINDOW_MS = 15000; // 15 seconds for worker to "settle"
private recentSpawnTimestamps: number[] = [];
Copy link
Owner Author

Choose a reason for hiding this comment

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

[WARNING] Complexity: Mutable Array for Timestamp Tracking

The mutable array pattern works but could lead to subtle issues:

  1. No cleanup if recordSpawn() is called but canSpawnWorker() is never called
  2. Array grows unbounded if cleanup only happens during spawn checks

Suggested Fix:

// Add cleanup to recordSpawn() as well to prevent unbounded growth
recordSpawn(): void {
  this.cleanupSettlingWorkers(); // Prevent unbounded growth
  this.recentSpawnTimestamps.push(Date.now());
  this.logger?.debug('Recorded spawn for settling tracking', {
    settlingWorkers: this.recentSpawnTimestamps.length,
    settlingWindowMs: this.SETTLING_WINDOW_MS
  });
}

private cleanupSettlingWorkers(): void {
  const now = Date.now();
  this.recentSpawnTimestamps = this.recentSpawnTimestamps.filter(
    t => now - t < this.SETTLING_WINDOW_MS
  );
}

Why: Defensive programming - cleanup should happen on both read and write paths to handle edge cases.


From: complexity audit | Severity: MEDIUM


Generated by Claude Code via /code-review


// Record spawn for settling worker tracking (accounts for lag in load average)
this.resourceMonitor.recordSpawn?.();

Copy link
Owner Author

Choose a reason for hiding this comment

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

[WARNING] Security: Optional Chaining Allows Silent Failure

The optional chaining (?.) means that if someone implements a custom ResourceMonitor without recordSpawn(), the settling workers tracking silently does nothing.

Suggested Fix:

// Add explicit logging when method is missing
if (this.resourceMonitor.recordSpawn) {
  this.resourceMonitor.recordSpawn();
} else {
  this.logger.debug('ResourceMonitor does not implement recordSpawn - settling tracking disabled');
}

Why: Silent failures make debugging difficult. Explicit logging helps operators understand when spawn burst protection is inactive.


From: security audit | Severity: MEDIUM


Generated by Claude Code via /code-review

this.logger?.debug('Cannot spawn: Max workers limit reached', {
// Clean up old spawn timestamps (outside settling window)
const now = Date.now();
this.recentSpawnTimestamps = this.recentSpawnTimestamps.filter(
Copy link
Owner Author

Choose a reason for hiding this comment

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

[WARNING] Performance: Array Filter Allocation

recentSpawnTimestamps.filter() creates a new array on every spawn check. While the array is typically small (0-5 elements), an in-place cleanup is more memory-efficient.

Suggested Fix (if optimization needed):

// In-place cleanup without allocation
private cleanupSettlingWorkers(): void {
  const now = Date.now();
  let writeIndex = 0;
  for (let i = 0; i < this.recentSpawnTimestamps.length; i++) {
    if (now - this.recentSpawnTimestamps[i] < this.SETTLING_WINDOW_MS) {
      this.recentSpawnTimestamps[writeIndex++] = this.recentSpawnTimestamps[i];
    }
  }
  this.recentSpawnTimestamps.length = writeIndex;
}

Why: Current implementation is acceptable for expected usage (called every 5 seconds with <10 elements). Consider optimization only if this becomes a hot path.


From: performance audit | Severity: MEDIUM (acceptable trade-off)


Generated by Claude Code via /code-review

@dean0x
Copy link
Owner Author

dean0x commented Nov 28, 2025

Code Review: Documentation Issues

The following documentation issues were identified but are not directly addressable via line comments (files not in diff or cross-cutting concerns):

1. [WARNING] Stale Line Number in TASK-DEPENDENCIES.md

File: docs/TASK-DEPENDENCIES.md line 706
Issue: The resolveDependencies line reference is outdated (says 199, actual is 344).

Fix needed:

- Dependency resolution: `src/services/handlers/dependency-handler.ts:344` (resolveDependencies)

2. [WARNING] Missing Documentation for Settling Workers Feature

Files affected:

  • docs/FEATURES.md (Autoscaling section)
  • docs/architecture/TASK_ARCHITECTURE.md

Issue: The settling workers tracking feature is documented in CHANGELOG.md but missing from feature documentation.

Suggested addition to FEATURES.md under "Autoscaling & Resource Management":

### Spawn Burst Protection (v0.3.1)
- **Settling Workers Tracking**: Tracks recently spawned workers for 15 seconds
- **Load Average Compensation**: Projects resource usage before system metrics update
- **recordSpawn() Interface**: ResourceMonitor method to record spawn events
- **minSpawnDelayMs**: Increased from 50ms to 1000ms for additional protection

3. [WARNING] Tests: Missing Test Coverage

Issue 1: should record spawn events test only verifies no throw, doesn't verify internal state was updated.

Issue 2: No test for recordSpawn() optional chaining behavior in WorkerHandler when ResourceMonitor lacks the method.

Suggested tests:

// Test 1: Verify recordSpawn updates internal state
it('should update settling worker count after recordSpawn', () => {
  monitor.recordSpawn();
  // Use canSpawnWorker to verify settling workers are tracked
  // ...
});

// Test 2: Verify WorkerHandler handles missing recordSpawn gracefully
it('should handle ResourceMonitor without recordSpawn method', () => {
  const mockMonitor = {
    getResources: vi.fn(),
    canSpawnWorker: vi.fn(),
    // Note: recordSpawn intentionally omitted
  };
  // Verify spawn works without throwing
});

From: documentation and tests audits | Severity: MEDIUM


Generated by Claude Code via /code-review

Dean Sharon and others added 5 commits November 28, 2025 20:36
…igurable

Interface Segregation Principle compliance: recordSpawn() is now a
required method on ResourceMonitor. Added settlingWindowMs configuration
option for tunable settling window duration (default 15s).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add cleanup of expired timestamps in recordSpawn() to prevent memory leak
- Use configurable settlingWindowMs instead of hardcoded constant
- Remove optional chaining on recordSpawn() call (now required method)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add no-op recordSpawn() implementations to:
- MockResourceMonitor (mock-resource-monitor.ts)
- TestResourceMonitor (test-doubles.ts)
- MockResourceMonitor (worker-handler.test.ts)

Required after making recordSpawn() non-optional in interface.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace trivial not-throw test with actual state change verification
- Test that recordSpawn() affects spawn eligibility at MAX_WORKERS=1
- Add all missing Configuration fields to ConfigFactory defaults

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add Settling Workers Tracking section to FEATURES.md explaining the
  problem solved (lagging load average) and configuration options
- Fix stale line reference in TASK-DEPENDENCIES.md (199->344)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@qodo-free-for-open-source-projects

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: test (20.x)

Failed stage: Run unit tests (error scenarios) [❌]

Failed test name: should handle packet loss simulation

Failure summary:

The action failed because a test assertion did not pass. The test "should handle packet loss
simulation" expected the actual packet loss rate to be less than 0.4, but the actual value was
exactly 0.4. This is a boundary condition failure where the test's upper bound expectation was not
met.

- Test file: tests/unit/error-scenarios/network-failures.test.ts
- Line: 336
- Expected:
actualLossRate to be less than 0.4
- Actual: actualLossRate was 0.4
- The test checks that the
packet loss rate is between 0.2 and 0.4 (exclusive), but the simulation resulted in exactly 0.4,
which fails the toBeLessThan(0.4) assertion.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

144:  > claudine@0.3.0 prebuild
145:  > npm run clean
146:  > claudine@0.3.0 clean
147:  > rm -rf dist logs test-logs test-db .tsbuildinfo
148:  > claudine@0.3.0 build
149:  > tsc
150:  ##[group]Run NODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/core/
151:  �[36;1mNODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/core/�[0m
152:  shell: /usr/bin/bash -e {0}
153:  ##[endgroup]
154:  > claudine@0.3.0 test:unit
155:  > NODE_OPTIONS='--max-old-space-size=2048' vitest run --no-file-parallelism tests/unit/core/
156:  �[1m�[46m RUN �[49m�[22m �[36mv3.2.4 �[39m�[90m/home/runner/work/claudine/claudine�[39m
157:  �[32m✓�[39m tests/unit/core/dependency-graph.test.ts �[2m(�[22m�[2m72 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m
158:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mEnvironment variable loading�[2m > �[22m�[2mshould handle invalid number parsing
159:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
160:  - timeout: Number must be greater than or equal to 1000
161:  - maxOutputBuffer: Number must be greater than or equal to 1024
162:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mValidation fallback�[2m > �[22m�[2mshould fallback to defaults on invalid timeout
163:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
164:  - timeout: Number must be greater than or equal to 1000
165:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mValidation fallback�[2m > �[22m�[2mshould fallback to defaults on invalid CPU threshold
166:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
167:  - cpuCoresReserved: Number must be less than or equal to 32
168:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mValidation fallback�[2m > �[22m�[2mshould fallback to defaults on invalid memory reserve
169:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
170:  - memoryReserve: Number must be greater than or equal to 0
171:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mValidation fallback�[2m > �[22m�[2mshould fallback to all defaults on any validation failure
172:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
173:  - memoryReserve: Number must be greater than or equal to 0
174:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mEdge cases�[2m > �[22m�[2mshould handle very large numbers
175:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
176:  - memoryReserve: Number must be less than or equal to 68719476736
177:  �[90mstderr�[2m | tests/unit/core/configuration.test.ts�[2m > �[22m�[2mloadConfiguration - REAL Configuration Loading�[2m > �[22m�[2mConfiguration consistency�[2m > �[22m�[2mshould always return valid configuration
178:  �[22m�[39m[Claudine] Configuration validation failed, using defaults:
179:  - timeout: Number must be greater than or equal to 1000
180:  - cpuCoresReserved: Number must be less than or equal to 32
181:  [Claudine] Configuration validation failed, using defaults:
182:  - maxOutputBuffer: Number must be greater than or equal to 1024
183:  - memoryReserve: Number must be greater than or equal to 0
184:  [Claudine] Configuration validation failed, using defaults:
185:  - timeout: Number must be greater than or equal to 1000
186:  [Claudine] Configuration validation failed, using defaults:
187:  - cpuCoresReserved: Number must be greater than or equal to 1
188:  �[32m✓�[39m tests/unit/core/configuration.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m
189:  �[32m✓�[39m tests/unit/core/events/event-bus.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m
190:  �[32m✓�[39m tests/unit/core/result.test.ts �[2m(�[22m�[2m37 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
191:  �[32m✓�[39m tests/unit/core/domain.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
192:  �[32m✓�[39m tests/unit/core/errors.test.ts �[2m(�[22m�[2m30 tests�[22m�[2m)�[22m�[32m 45�[2mms�[22m�[39m
193:  �[32m✓�[39m tests/unit/core/config-validator.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m
...

212:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependency()�[2m > �[22m�[2mshould allow different tasks to depend on the same task
213:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
214:  Migration v1 applied successfully
215:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependency()�[2m > �[22m�[2mshould allow a task to depend on multiple tasks
216:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
217:  Migration v1 applied successfully
218:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependency()�[2m > �[22m�[2mshould reject adding dependency when task already has 100 dependencies
219:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
220:  Migration v1 applied successfully
221:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependencies() - Atomic Batch Operations�[2m > �[22m�[2mshould successfully add multiple dependencies atomically
222:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
223:  Migration v1 applied successfully
224:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependencies() - Atomic Batch Operations�[2m > �[22m�[2mshould rollback all dependencies on duplicate detection
225:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
226:  Migration v1 applied successfully
227:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependencies() - Atomic Batch Operations�[2m > �[22m�[2mshould rollback all dependencies on task not found error
228:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
229:  Migration v1 applied successfully
230:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependencies() - Atomic Batch Operations�[2m > �[22m�[2mshould reject empty dependency arrays
231:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
232:  Migration v1 applied successfully
233:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependencies() - Atomic Batch Operations�[2m > �[22m�[2mshould handle large batch additions atomically
234:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
235:  Migration v1 applied successfully
236:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2maddDependencies() - Atomic Batch Operations�[2m > �[22m�[2mshould rollback large batch on single failure
237:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
...

248:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mgetDependencies()�[2m > �[22m�[2mshould return empty array for task with no dependencies
249:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
250:  Migration v1 applied successfully
251:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mgetDependencies()�[2m > �[22m�[2mshould return dependencies in correct format
252:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
253:  Migration v1 applied successfully
254:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mgetDependents()�[2m > �[22m�[2mshould return all tasks that depend on a given task
255:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
256:  Migration v1 applied successfully
257:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mgetDependents()�[2m > �[22m�[2mshould return empty array for task with no dependents
258:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
259:  Migration v1 applied successfully
260:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependency()�[2m > �[22m�[2mshould resolve dependency as completed
261:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
262:  Migration v1 applied successfully
263:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependency()�[2m > �[22m�[2mshould resolve dependency as failed
264:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
265:  Migration v1 applied successfully
266:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependency()�[2m > �[22m�[2mshould resolve dependency as cancelled
267:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
268:  Migration v1 applied successfully
269:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependency()�[2m > �[22m�[2mshould fail when resolving non-existent dependency
270:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
271:  Migration v1 applied successfully
272:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependency()�[2m > �[22m�[2mshould update resolvedAt timestamp
273:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
274:  Migration v1 applied successfully
275:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould batch resolve all pending dependencies in single query
276:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
277:  Migration v1 applied successfully
278:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould only resolve pending dependencies, skip already resolved
279:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
280:  Migration v1 applied successfully
281:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould return 0 when no pending dependencies exist
282:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
283:  Migration v1 applied successfully
284:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould handle failed resolution state
285:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
286:  Migration v1 applied successfully
287:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould handle cancelled resolution state
288:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
289:  Migration v1 applied successfully
290:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould handle large number of dependents efficiently
291:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
292:  Migration v1 applied successfully
293:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mresolveDependenciesBatch()�[2m > �[22m�[2mshould handle database errors gracefully
294:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
...

302:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2mgetUnresolvedDependencies()�[2m > �[22m�[2mshould return all dependencies when none resolved
303:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
304:  Migration v1 applied successfully
305:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2misBlocked()�[2m > �[22m�[2mshould return true when task has unresolved dependencies
306:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
307:  Migration v1 applied successfully
308:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2misBlocked()�[2m > �[22m�[2mshould return false when task has no dependencies
309:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
310:  Migration v1 applied successfully
311:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2misBlocked()�[2m > �[22m�[2mshould return false when all dependencies resolved
312:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
313:  Migration v1 applied successfully
314:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2misBlocked()�[2m > �[22m�[2mshould return true when at least one dependency is unresolved
315:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
316:  Migration v1 applied successfully
317:  �[90mstdout�[2m | tests/unit/implementations/dependency-repository.test.ts�[2m > �[22m�[2mSQLiteDependencyRepository - Unit Tests�[2m > �[22m�[2misBlocked()�[2m > �[22m�[2mshould return false even if dependencies failed or cancelled
318:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
...

364:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mConnection management�[2m > �[22m�[2mshould handle double close gracefully
365:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
366:  Migration v1 applied successfully
367:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mSchema initialization�[2m > �[22m�[2mshould initialize schema with tables
368:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
369:  Migration v1 applied successfully
370:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mSchema initialization�[2m > �[22m�[2mshould create tasks table with all columns
371:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
372:  Migration v1 applied successfully
373:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mSchema initialization�[2m > �[22m�[2mshould create task_output table with all columns
374:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
375:  Migration v1 applied successfully
376:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mSchema initialization�[2m > �[22m�[2mshould create indexes for performance
377:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
378:  Migration v1 applied successfully
379:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mSchema initialization�[2m > �[22m�[2mshould be idempotent - creating tables multiple times should not fail
380:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
381:  Migration v1 applied successfully
382:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mSchema initialization�[2m > �[22m�[2mshould be idempotent - creating tables multiple times should not fail
383:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
384:  Migration v1 applied successfully
385:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mDatabase operations�[2m > �[22m�[2mshould allow direct SQL queries through getDatabase()
386:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
387:  Migration v1 applied successfully
388:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mDatabase operations�[2m > �[22m�[2mshould handle transactions
389:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
390:  Migration v1 applied successfully
391:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mDatabase operations�[2m > �[22m�[2mshould handle foreign key constraints
392:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
393:  Migration v1 applied successfully
394:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mDatabase operations�[2m > �[22m�[2mshould handle concurrent operations with WAL mode
395:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
396:  Migration v1 applied successfully
397:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mError handling�[2m > �[22m�[2mshould handle SQL errors gracefully
398:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
399:  Migration v1 applied successfully
400:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mError handling�[2m > �[22m�[2mshould handle invalid SQL
401:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
...

405:  Migration v1 applied successfully
406:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mPerformance optimizations�[2m > �[22m�[2mshould use transactions for bulk operations
407:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
408:  Migration v1 applied successfully
409:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mDefault path handling�[2m > �[22m�[2mshould use in-memory database for tests
410:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
411:  Migration v1 applied successfully
412:  �[90mstdout�[2m | tests/unit/implementations/database.test.ts�[2m > �[22m�[2mDatabase - REAL Database Operations (In-Memory)�[2m > �[22m�[2mDefault path handling�[2m > �[22m�[2mshould use in-memory database for tests
413:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
414:  Migration v1 applied successfully
415:  �[32m✓�[39m tests/unit/implementations/database.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m
416:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mLogger creation and configuration�[2m > �[22m�[2mshould expose all required log levels
417:  �[22m�[39m[Test] DEBUG: Debug message 
418:  [Test] INFO: Info message 
419:  [Test] WARN: Warning message 
420:  [Test] ERROR: Error message 
421:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mContext handling�[2m > �[22m�[2mshould accept context objects
422:  �[22m�[39m[Test] INFO: Message with context { userId: �[32m'123'�[39m }
423:  [Test] WARN: Warning with context { code: �[32m'W001'�[39m }
424:  [Test] DEBUG: Debug with context { data: { nested: �[33mtrue�[39m } }
425:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mContext handling�[2m > �[22m�[2mshould handle messages without context
426:  �[22m�[39m[Test] INFO: Simple message 
427:  [Test] WARN: Simple warning 
428:  [Test] ERROR: Simple error 
429:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mContext handling�[2m > �[22m�[2mshould handle various context types
430:  �[22m�[39m[Test] INFO: With string context
431:  [Test] INFO: With number �[33m123�[39m
432:  [Test] INFO: With array [ �[33m1�[39m, �[33m2�[39m, �[33m3�[39m ]
433:  [Test] INFO: With null 
434:  [Test] INFO: With undefined 
435:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mError handling�[2m > �[22m�[2mshould handle error objects
436:  �[22m�[39m[Test] ERROR: Operation failed 
437:  Error: Test error
438:  at �[90m/home/runner/work/claudine/claudine/�[39mtests/unit/implementations/console-logger.test.ts:91:21
439:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:155:11
440:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:752:26
441:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1897:20
442:  at new Promise (<anonymous>)
443:  at runWithTimeout �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1863:10�[90m)�[39m
444:  at runTest �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1574:12�[90m)�[39m
445:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
446:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
447:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
448:  [Test] ERROR: Failed with context { userId: �[32m'123'�[39m }
449:  Error: Test error
450:  at �[90m/home/runner/work/claudine/claudine/�[39mtests/unit/implementations/console-logger.test.ts:91:21
451:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:155:11
452:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:752:26
453:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1897:20
454:  at new Promise (<anonymous>)
455:  at runWithTimeout �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1863:10�[90m)�[39m
456:  at runTest �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1574:12�[90m)�[39m
457:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
458:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
459:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
460:  [Test] ERROR: Just message 
461:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mError handling�[2m > �[22m�[2mshould handle various error types
462:  �[22m�[39m[Test] ERROR: Standard 
463:  Error: Standard error
464:  at �[90m/home/runner/work/claudine/claudine/�[39mtests/unit/implementations/console-logger.test.ts:102:29
465:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:155:11
466:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:752:26
467:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1897:20
468:  at new Promise (<anonymous>)
469:  at runWithTimeout �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1863:10�[90m)�[39m
470:  at runTest �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1574:12�[90m)�[39m
471:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
472:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
473:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
474:  [Test] ERROR: Type 
475:  TypeError: Type error
476:  at �[90m/home/runner/work/claudine/claudine/�[39mtests/unit/implementations/console-logger.test.ts:103:25
477:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:155:11
478:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:752:26
479:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1897:20
480:  at new Promise (<anonymous>)
481:  at runWithTimeout �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1863:10�[90m)�[39m
482:  at runTest �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1574:12�[90m)�[39m
483:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
484:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
485:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
486:  [Test] ERROR: Range 
487:  RangeError: Range error
488:  at �[90m/home/runner/work/claudine/claudine/�[39mtests/unit/implementations/console-logger.test.ts:104:26
489:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:155:11
490:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:752:26
491:  at �[90mfile:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1897:20
492:  at new Promise (<anonymous>)
493:  at runWithTimeout �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1863:10�[90m)�[39m
494:  at runTest �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1574:12�[90m)�[39m
495:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
496:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
497:  at runSuite �[90m(file:///home/runner/work/claudine/claudine/�[39mnode_modules/�[4m@vitest�[24m/runner/dist/chunk-hooks.js:1729:8�[90m)�[39m
498:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mError handling�[2m > �[22m�[2mshould handle error-like objects
499:  �[22m�[39m[Test] ERROR: Error-like 
500:  { message: �[32m'error-like'�[39m, stack: �[32m'fake stack'�[39m }
501:  [Test] ERROR: Custom 
502:  { code: �[32m'ERR_001'�[39m, details: �[32m'Something went wrong'�[39m }
503:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mChild logger creation�[2m > �[22m�[2mshould create child with different contexts
504:  �[22m�[39m[Parent][auth] INFO: Auth message 
505:  [Parent] INFO: API message 
506:  [Parent] INFO: Data message 
507:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mChild logger creation�[2m > �[22m�[2mshould handle nested children
508:  �[22m�[39m[Root] INFO: Root log 
509:  [Root][api] INFO: Service log 
510:  [Root][api][auth] INFO: Nested log 
511:  [Root][api][auth][token] INFO: Deep log 
512:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mChild logger creation�[2m > �[22m�[2mshould preserve color settings in children
513:  �[22m�[39m�[32m[Parent][test] INFO:�[0m With colors 
514:  [Parent][test] INFO: Without colors 
515:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mPerformance and reliability�[2m > �[22m�[2mshould handle rapid logging without errors
516:  �[22m�[39m[Test] INFO: Message 0 
517:  [Test] DEBUG: Debug 0 
518:  [Test] WARN: Warning 0 
519:  [Test] ERROR: Error 0 
520:  [Test] INFO: Message 1 
521:  [Test] DEBUG: Debug 1 
522:  [Test] WARN: Warning 1 
523:  [Test] ERROR: Error 1 
524:  [Test] INFO: Message 2 
525:  [Test] DEBUG: Debug 2 
526:  [Test] WARN: Warning 2 
527:  [Test] ERROR: Error 2 
528:  [Test] INFO: Message 3 
529:  [Test] DEBUG: Debug 3 
530:  [Test] WARN: Warning 3 
531:  [Test] ERROR: Error 3 
532:  [Test] INFO: Message 4 
533:  [Test] DEBUG: Debug 4 
534:  [Test] WARN: Warning 4 
535:  [Test] ERROR: Error 4 
536:  [Test] INFO: Message 5 
537:  [Test] DEBUG: Debug 5 
538:  [Test] WARN: Warning 5 
539:  [Test] ERROR: Error 5 
540:  [Test] INFO: Message 6 
541:  [Test] DEBUG: Debug 6 
542:  [Test] WARN: Warning 6 
543:  [Test] ERROR: Error 6 
544:  [Test] INFO: Message 7 
545:  [Test] DEBUG: Debug 7 
546:  [Test] WARN: Warning 7 
547:  [Test] ERROR: Error 7 
548:  [Test] INFO: Message 8 
549:  [Test] DEBUG: Debug 8 
550:  [Test] WARN: Warning 8 
551:  [Test] ERROR: Error 8 
552:  [Test] INFO: Message 9 
553:  [Test] DEBUG: Debug 9 
554:  [Test] WARN: Warning 9 
555:  [Test] ERROR: Error 9 
556:  [Test] INFO: Message 10 
557:  [Test] DEBUG: Debug 10 
558:  [Test] WARN: Warning 10 
559:  [Test] ERROR: Error 10 
560:  [Test] INFO: Message 11 
561:  [Test] DEBUG: Debug 11 
562:  [Test] WARN: Warning 11 
563:  [Test] ERROR: Error 11 
564:  [Test] INFO: Message 12 
565:  [Test] DEBUG: Debug 12 
566:  [Test] WARN: Warning 12 
567:  [Test] ERROR: Error 12 
568:  [Test] INFO: Message 13 
569:  [Test] DEBUG: Debug 13 
570:  [Test] WARN: Warning 13 
571:  [Test] ERROR: Error 13 
572:  [Test] INFO: Message 14 
573:  [Test] DEBUG: Debug 14 
574:  [Test] WARN: Warning 14 
575:  [Test] ERROR: Error 14 
576:  [Test] INFO: Message 15 
577:  [Test] DEBUG: Debug 15 
578:  [Test] WARN: Warning 15 
579:  [Test] ERROR: Error 15 
580:  [Test] INFO: Message 16 
581:  [Test] DEBUG: Debug 16 
582:  [Test] WARN: Warning 16 
583:  [Test] ERROR: Error 16 
584:  [Test] INFO: Message 17 
585:  [Test] DEBUG: Debug 17 
586:  [Test] WARN: Warning 17 
587:  [Test] ERROR: Error 17 
588:  [Test] INFO: Message 18 
589:  [Test] DEBUG: Debug 18 
590:  [Test] WARN: Warning 18 
591:  [Test] ERROR: Error 18 
592:  [Test] INFO: Message 19 
593:  [Test] DEBUG: Debug 19 
594:  [Test] WARN: Warning 19 
595:  [Test] ERROR: Error 19 
596:  [Test] INFO: Message 20 
597:  [Test] DEBUG: Debug 20 
598:  [Test] WARN: Warning 20 
599:  [Test] ERROR: Error 20 
600:  [Test] INFO: Message 21 
601:  [Test] DEBUG: Debug 21 
602:  [Test] WARN: Warning 21 
603:  [Test] ERROR: Error 21 
604:  [Test] INFO: Message 22 
605:  [Test] DEBUG: Debug 22 
606:  [Test] WARN: Warning 22 
607:  [Test] ERROR: Error 22 
608:  [Test] INFO: Message 23 
609:  [Test] DEBUG: Debug 23 
610:  [Test] WARN: Warning 23 
611:  [Test] ERROR: Error 23 
612:  [Test] INFO: Message 24 
613:  [Test] DEBUG: Debug 24 
614:  [Test] WARN: Warning 24 
615:  [Test] ERROR: Error 24 
616:  [Test] INFO: Message 25 
617:  [Test] DEBUG: Debug 25 
618:  [Test] WARN: Warning 25 
619:  [Test] ERROR: Error 25 
620:  [Test] INFO: Message 26 
621:  [Test] DEBUG: Debug 26 
622:  [Test] WARN: Warning 26 
623:  [Test] ERROR: Error 26 
624:  [Test] INFO: Message 27 
625:  [Test] DEBUG: Debug 27 
626:  [Test] WARN: Warning 27 
627:  [Test] ERROR: Error 27 
628:  [Test] INFO: Message 28 
629:  [Test] DEBUG: Debug 28 
630:  [Test] WARN: Warning 28 
631:  [Test] ERROR: Error 28 
632:  [Test] INFO: Message 29 
633:  [Test] DEBUG: Debug 29 
634:  [Test] WARN: Warning 29 
635:  [Test] ERROR: Error 29 
636:  [Test] INFO: Message 30 
637:  [Test] DEBUG: Debug 30 
638:  [Test] WARN: Warning 30 
639:  [Test] ERROR: Error 30 
640:  [Test] INFO: Message 31 
641:  [Test] DEBUG: Debug 31 
642:  [Test] WARN: Warning 31 
643:  [Test] ERROR: Error 31 
644:  [Test] INFO: Message 32 
645:  [Test] DEBUG: Debug 32 
646:  [Test] WARN: Warning 32 
647:  [Test] ERROR: Error 32 
648:  [Test] INFO: Message 33 
649:  [Test] DEBUG: Debug 33 
650:  [Test] WARN: Warning 33 
651:  [Test] ERROR: Error 33 
652:  [Test] INFO: Message 34 
653:  [Test] DEBUG: Debug 34 
654:  [Test] WARN: Warning 34 
655:  [Test] ERROR: Error 34 
656:  [Test] INFO: Message 35 
657:  [Test] DEBUG: Debug 35 
658:  [Test] WARN: Warning 35 
659:  [Test] ERROR: Error 35 
660:  [Test] INFO: Message 36 
661:  [Test] DEBUG: Debug 36 
662:  [Test] WARN: Warning 36 
663:  [Test] ERROR: Error 36 
664:  [Test] INFO: Message 37 
665:  [Test] DEBUG: Debug 37 
666:  [Test] WARN: Warning 37 
667:  [Test] ERROR: Error 37 
668:  [Test] INFO: Message 38 
669:  [Test] DEBUG: Debug 38 
670:  [Test] WARN: Warning 38 
671:  [Test] ERROR: Error 38 
672:  [Test] INFO: Message 39 
673:  [Test] DEBUG: Debug 39 
674:  [Test] WARN: Warning 39 
675:  [Test] ERROR: Error 39 
676:  [Test] INFO: Message 40 
677:  [Test] DEBUG: Debug 40 
678:  [Test] WARN: Warning 40 
679:  [Test] ERROR: Error 40 
680:  [Test] INFO: Message 41 
681:  [Test] DEBUG: Debug 41 
682:  [Test] WARN: Warning 41 
683:  [Test] ERROR: Error 41 
684:  [Test] INFO: Message 42 
685:  [Test] DEBUG: Debug 42 
686:  [Test] WARN: Warning 42 
687:  [Test] ERROR: Error 42 
688:  [Test] INFO: Message 43 
689:  [Test] DEBUG: Debug 43 
690:  [Test] WARN: Warning 43 
691:  [Test] ERROR: Error 43 
692:  [Test] INFO: Message 44 
693:  [Test] DEBUG: Debug 44 
694:  [Test] WARN: Warning 44 
695:  [Test] ERROR: Error 44 
696:  [Test] INFO: Message 45 
697:  [Test] DEBUG: Debug 45 
698:  [Test] WARN: Warning 45 
699:  [Test] ERROR: Error 45 
700:  [Test] INFO: Message 46 
701:  [Test] DEBUG: Debug 46 
702:  [Test] WARN: Warning 46 
703:  [Test] ERROR: Error 46 
704:  [Test] INFO: Message 47 
705:  [Test] DEBUG: Debug 47 
706:  [Test] WARN: Warning 47 
707:  [Test] ERROR: Error 47 
708:  [Test] INFO: Message 48 
709:  [Test] DEBUG: Debug 48 
710:  [Test] WARN: Warning 48 
711:  [Test] ERROR: Error 48 
712:  [Test] INFO: Message 49 
713:  [Test] DEBUG: Debug 49 
714:  [Test] WARN: Warning 49 
715:  [Test] ERROR: Error 49 
716:  [Test] INFO: Message 50 
717:  [Test] DEBUG: Debug 50 
718:  [Test] WARN: Warning 50 
719:  [Test] ERROR: Error 50 
720:  [Test] INFO: Message 51 
721:  [Test] DEBUG: Debug 51 
722:  [Test] WARN: Warning 51 
723:  [Test] ERROR: Error 51 
724:  [Test] INFO: Message 52 
725:  [Test] DEBUG: Debug 52 
726:  [Test] WARN: Warning 52 
727:  [Test] ERROR: Error 52 
728:  [Test] INFO: Message 53 
729:  [Test] DEBUG: Debug 53 
730:  [Test] WARN: Warning 53 
731:  [Test] ERROR: Error 53 
732:  [Test] INFO: Message 54 
733:  [Test] DEBUG: Debug 54 
734:  [Test] WARN: Warning 54 
735:  [Test] ERROR: Error 54 
736:  [Test] INFO: Message 55 
737:  [Test] DEBUG: Debug 55 
738:  [Test] WARN: Warning 55 
739:  [Test] ERROR: Error 55 
740:  [Test] INFO: Message 56 
741:  [Test] DEBUG: Debug 56 
742:  [Test] WARN: Warning 56 
743:  [Test] ERROR: Error 56 
744:  [Test] INFO: Message 57 
745:  [Test] DEBUG: Debug 57 
746:  [Test] WARN: Warning 57 
747:  [Test] ERROR: Error 57 
748:  [Test] INFO: Message 58 
749:  [Test] DEBUG: Debug 58 
750:  [Test] WARN: Warning 58 
751:  [Test] ERROR: Error 58 
752:  [Test] INFO: Message 59 
753:  [Test] DEBUG: Debug 59 
754:  [Test] WARN: Warning 59 
755:  [Test] ERROR: Error 59 
756:  [Test] INFO: Message 60 
757:  [Test] DEBUG: Debug 60 
758:  [Test] WARN: Warning 60 
759:  [Test] ERROR: Error 60 
760:  [Test] INFO: Message 61 
761:  [Test] DEBUG: Debug 61 
762:  [Test] WARN: Warning 61 
763:  [Test] ERROR: Error 61 
764:  [Test] INFO: Message 62 
765:  [Test] DEBUG: Debug 62 
766:  [Test] WARN: Warning 62 
767:  [Test] ERROR: Error 62 
768:  [Test] INFO: Message 63 
769:  [Test] DEBUG: Debug 63 
770:  [Test] WARN: Warning 63 
771:  [Test] ERROR: Error 63 
772:  [Test] INFO: Message 64 
773:  [Test] DEBUG: Debug 64 
774:  [Test] WARN: Warning 64 
775:  [Test] ERROR: Error 64 
776:  [Test] INFO: Message 65 
777:  [Test] DEBUG: Debug 65 
778:  [Test] WARN: Warning 65 
779:  [Test] ERROR: Error 65 
780:  [Test] INFO: Message 66 
781:  [Test] DEBUG: Debug 66 
782:  [Test] WARN: Warning 66 
783:  [Test] ERROR: Error 66 
784:  [Test] INFO: Message 67 
785:  [Test] DEBUG: Debug 67 
786:  [Test] WARN: Warning 67 
787:  [Test] ERROR: Error 67 
788:  [Test] INFO: Message 68 
789:  [Test] DEBUG: Debug 68 
790:  [Test] WARN: Warning 68 
791:  [Test] ERROR: Error 68 
792:  [Test] INFO: Message 69 
793:  [Test] DEBUG: Debug 69 
794:  [Test] WARN: Warning 69 
795:  [Test] ERROR: Error 69 
796:  [Test] INFO: Message 70 
797:  [Test] DEBUG: Debug 70 
798:  [Test] WARN: Warning 70 
799:  [Test] ERROR: Error 70 
800:  [Test] INFO: Message 71 
801:  [Test] DEBUG: Debug 71 
802:  [Test] WARN: Warning 71 
803:  [Test] ERROR: Error 71 
804:  [Test] INFO: Message 72 
805:  [Test] DEBUG: Debug 72 
806:  [Test] WARN: Warning 72 
807:  [Test] ERROR: Error 72 
808:  [Test] INFO: Message 73 
809:  [Test] DEBUG: Debug 73 
810:  [Test] WARN: Warning 73 
811:  [Test] ERROR: Error 73 
812:  [Test] INFO: Message 74 
813:  [Test] DEBUG: Debug 74 
814:  [Test] WARN: Warning 74 
815:  [Test] ERROR: Error 74 
816:  [Test] INFO: Message 75 
817:  [Test] DEBUG: Debug 75 
818:  [Test] WARN: Warning 75 
819:  [Test] ERROR: Error 75 
820:  [Test] INFO: Message 76 
821:  [Test] DEBUG: Debug 76 
822:  [Test] WARN: Warning 76 
823:  [Test] ERROR: Error 76 
824:  [Test] INFO: Message 77 
825:  [Test] DEBUG: Debug 77 
826:  [Test] WARN: Warning 77 
827:  [Test] ERROR: Error 77 
828:  [Test] INFO: Message 78 
829:  [Test] DEBUG: Debug 78 
830:  [Test] WARN: Warning 78 
831:  [Test] ERROR: Error 78 
832:  [Test] INFO: Message 79 
833:  [Test] DEBUG: Debug 79 
834:  [Test] WARN: Warning 79 
835:  [Test] ERROR: Error 79 
836:  [Test] INFO: Message 80 
837:  [Test] DEBUG: Debug 80 
838:  [Test] WARN: Warning 80 
839:  [Test] ERROR: Error 80 
840:  [Test] INFO: Message 81 
841:  [Test] DEBUG: Debug 81 
842:  [Test] WARN: Warning 81 
843:  [Test] ERROR: Error 81 
844:  [Test] INFO: Message 82 
845:  [Test] DEBUG: Debug 82 
846:  [Test] WARN: Warning 82 
847:  [Test] ERROR: Error 82 
848:  [Test] INFO: Message 83 
849:  [Test] DEBUG: Debug 83 
850:  [Test] WARN: Warning 83 
851:  [Test] ERROR: Error 83 
852:  [Test] INFO: Message 84 
853:  [Test] DEBUG: Debug 84 
854:  [Test] WARN: Warning 84 
855:  [Test] ERROR: Error 84 
856:  [Test] INFO: Message 85 
857:  [Test] DEBUG: Debug 85 
858:  [Test] WARN: Warning 85 
859:  [Test] ERROR: Error 85 
860:  [Test] INFO: Message 86 
861:  [Test] DEBUG: Debug 86 
862:  [Test] WARN: Warning 86 
863:  [Test] ERROR: Error 86 
864:  [Test] INFO: Message 87 
865:  [Test] DEBUG: Debug 87 
866:  [Test] WARN: Warning 87 
867:  [Test] ERROR: Error 87 
868:  [Test] INFO: Message 88 
869:  [Test] DEBUG: Debug 88 
870:  [Test] WARN: Warning 88 
871:  [Test] ERROR: Error 88 
872:  [Test] INFO: Message 89 
873:  [Test] DEBUG: Debug 89 
874:  [Test] WARN: Warning 89 
875:  [Test] ERROR: Error 89 
876:  [Test] INFO: Message 90 
877:  [Test] DEBUG: Debug 90 
878:  [Test] WARN: Warning 90 
879:  [Test] ERROR: Error 90 
880:  [Test] INFO: Message 91 
881:  [Test] DEBUG: Debug 91 
882:  [Test] WARN: Warning 91 
883:  [Test] ERROR: Error 91 
884:  [Test] INFO: Message 92 
885:  [Test] DEBUG: Debug 92 
886:  [Test] WARN: Warning 92 
887:  [Test] ERROR: Error 92 
888:  [Test] INFO: Message 93 
889:  [Test] DEBUG: Debug 93 
890:  [Test] WARN: Warning 93 
891:  [Test] ERROR: Error 93 
892:  [Test] INFO: Message 94 
893:  [Test] DEBUG: Debug 94 
894:  [Test] WARN: Warning 94 
895:  [Test] ERROR: Error 94 
896:  [Test] INFO: Message 95 
897:  [Test] DEBUG: Debug 95 
898:  [Test] WARN: Warning 95 
899:  [Test] ERROR: Error 95 
900:  [Test] INFO: Message 96 
901:  [Test] DEBUG: Debug 96 
902:  [Test] WARN: Warning 96 
903:  [Test] ERROR: Error 96 
904:  [Test] INFO: Message 97 
905:  [Test] DEBUG: Debug 97 
906:  [Test] WARN: Warning 97 
907:  [Test] ERROR: Error 97 
908:  [Test] INFO: Message 98 
909:  [Test] DEBUG: Debug 98 
910:  [Test] WARN: Warning 98 
911:  [Test] ERROR: Error 98 
912:  [Test] INFO: Message 99 
913:  [Test] DEBUG: Debug 99 
914:  [Test] WARN: Warning 99 
915:  [Test] ERROR: Error 99 
916:  �[90mstderr�[2m | tests/unit/implementations/console-logger.test.ts�[2m > �[22m�[2mConsoleLogger - Behavioral Tests�[2m > �[22m�[2mPerformance and reliability�[2m > �[22m�[2mshould handle large context objects
...

1031:  �[22m�[39m[Root][child-0] INFO: Child 0 message 
1032:  [Root][child-1] INFO: Child 1 message 
1033:  [Root][child-2] INFO: Child 2 message 
1034:  [Root][child-3] INFO: Child 3 message 
1035:  [Root][child-4] INFO: Child 4 message 
1036:  [Root][child-5] INFO: Child 5 message 
1037:  [Root][child-6] INFO: Child 6 message 
1038:  [Root][child-7] INFO: Child 7 message 
1039:  [Root][child-8] INFO: Child 8 message 
1040:  [Root][child-9] INFO: Child 9 message 
1041:  �[32m✓�[39m tests/unit/implementations/console-logger.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
1042:  �[90mstderr�[2m | tests/unit/implementations/structured-logger.test.ts�[2m > �[22m�[2mStructuredLogger - JSON Logging Behavior�[2m > �[22m�[2mDefault output behavior�[2m > �[22m�[2mshould work without custom output function
1043:  �[22m�[39m{"timestamp":"2025-11-28T20:47:27.975Z","level":"info","message":"Test message","context":{}}
1044:  {"timestamp":"2025-11-28T20:47:27.975Z","level":"debug","message":"Debug message","context":{}}
1045:  {"timestamp":"2025-11-28T20:47:27.975Z","level":"warn","message":"Warning message","context":{}}
1046:  {"timestamp":"2025-11-28T20:47:27.975Z","level":"error","message":"Error message","context":{}}
1047:  �[90mstderr�[2m | tests/unit/implementations/structured-logger.test.ts�[2m > �[22m�[2mStructuredLogger - JSON Logging Behavior�[2m > �[22m�[2mDefault output behavior�[2m > �[22m�[2mshould handle various payload sizes with default output
...

1056:  �[2m   Start at �[22m 20:47:26
1057:  �[2m   Duration �[22m 1.02s�[2m (transform 324ms, setup 37ms, collect 367ms, tests 315ms, environment 0ms, prepare 61ms)�[22m
1058:  ##[group]Run NODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/services/handlers/query-handler.test.ts
1059:  �[36;1mNODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/services/handlers/query-handler.test.ts�[0m
1060:  shell: /usr/bin/bash -e {0}
1061:  ##[endgroup]
1062:  > claudine@0.3.0 test:unit
1063:  > NODE_OPTIONS='--max-old-space-size=2048' vitest run --no-file-parallelism tests/unit/services/handlers/query-handler.test.ts
1064:  �[1m�[46m RUN �[49m�[22m �[36mv3.2.4 �[39m�[90m/home/runner/work/claudine/claudine�[39m
1065:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mTask status queries�[2m > �[22m�[2mshould return task when it exists
1066:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1067:  Migration v1 applied successfully
1068:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mTask status queries�[2m > �[22m�[2mshould return null for non-existent task
1069:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1070:  Migration v1 applied successfully
1071:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mTask status queries�[2m > �[22m�[2mshould handle database errors gracefully
1072:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
...

1086:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mTask output queries�[2m > �[22m�[2mshould return empty output for task with no capture
1087:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1088:  Migration v1 applied successfully
1089:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mTask output queries�[2m > �[22m�[2mshould handle large output efficiently
1090:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1091:  Migration v1 applied successfully
1092:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mRequest timeout handling�[2m > �[22m�[2mshould timeout long-running requests
1093:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1094:  Migration v1 applied successfully
1095:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mConcurrent query handling�[2m > �[22m�[2mshould handle multiple concurrent queries correctly
1096:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1097:  Migration v1 applied successfully
1098:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mConcurrent query handling�[2m > �[22m�[2mshould maintain query isolation
1099:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1100:  Migration v1 applied successfully
1101:  �[90mstdout�[2m | tests/unit/services/handlers/query-handler.test.ts�[2m > �[22m�[2mQueryHandler - Behavioral Tests�[2m > �[22m�[2mError recovery�[2m > �[22m�[2mshould recover from transient database errors
1102:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
...

1108:  �[2m   Duration �[22m 601ms�[2m (transform 166ms, setup 29ms, collect 168ms, tests 127ms, environment 0ms, prepare 61ms)�[22m
1109:  ##[group]Run NODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/adapters/ tests/unit/utils/
1110:  �[36;1mNODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/adapters/ tests/unit/utils/�[0m
1111:  shell: /usr/bin/bash -e {0}
1112:  ##[endgroup]
1113:  > claudine@0.3.0 test:unit
1114:  > NODE_OPTIONS='--max-old-space-size=2048' vitest run --no-file-parallelism tests/unit/adapters/ tests/unit/utils/
1115:  �[1m�[46m RUN �[49m�[22m �[36mv3.2.4 �[39m�[90m/home/runner/work/claudine/claudine�[39m
1116:  �[32m✓�[39m tests/unit/adapters/mcp-adapter.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
1117:  �[32m✓�[39m tests/unit/utils/retry.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[33m 3022�[2mms�[22m�[39m
1118:  �[33m�[2m✓�[22m�[39m Integration with Result type�[2m > �[22mshould combine retryWithBackoff with Result type �[33m 3003�[2mms�[22m�[39m
1119:  �[2m Test Files �[22m �[1m�[32m2 passed�[39m�[22m�[90m (2)�[39m
1120:  �[2m      Tests �[22m �[1m�[32m87 passed�[39m�[22m�[90m (87)�[39m
1121:  �[2m   Start at �[22m 20:47:29
1122:  �[2m   Duration �[22m 3.59s�[2m (transform 170ms, setup 33ms, collect 208ms, tests 3.04s, environment 0ms, prepare 65ms)�[22m
1123:  ##[group]Run NODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/error-scenarios/
1124:  �[36;1mNODE_OPTIONS="--max-old-space-size=2048" npm run test:unit -- tests/unit/error-scenarios/�[0m
1125:  shell: /usr/bin/bash -e {0}
1126:  ##[endgroup]
1127:  > claudine@0.3.0 test:unit
1128:  > NODE_OPTIONS='--max-old-space-size=2048' vitest run --no-file-parallelism tests/unit/error-scenarios/
1129:  �[1m�[46m RUN �[49m�[22m �[36mv3.2.4 �[39m�[90m/home/runner/work/claudine/claudine�[39m
1130:  �[31m❯�[39m tests/unit/error-scenarios/network-failures.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m | �[22m�[31m1 failed�[39m�[2m)�[22m�[33m 10633�[2mms�[22m�[39m
1131:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mProcess Communication Failures�[2m > �[22mshould handle process spawn timeout�[32m 2�[2mms�[22m�[39m
1132:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mProcess Communication Failures�[2m > �[22mshould handle process disconnection�[32m 1�[2mms�[22m�[39m
1133:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mProcess Communication Failures�[2m > �[22mshould handle stdout/stderr pipe broken�[32m 1�[2mms�[22m�[39m
1134:  �[33m�[2m✓�[22m�[39m Network Failure Scenarios�[2m > �[22mEvent Bus Communication Failures�[2m > �[22mshould handle event emission timeout �[33m 5006�[2mms�[22m�[39m
1135:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mEvent Bus Communication Failures�[2m > �[22mshould handle event handler exceptions�[32m 1�[2mms�[22m�[39m
1136:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mEvent Bus Communication Failures�[2m > �[22mshould handle request/response timeout�[32m 100�[2mms�[22m�[39m
1137:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mWorker Communication Failures�[2m > �[22mshould detect unresponsive worker�[32m 0�[2mms�[22m�[39m
1138:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mWorker Communication Failures�[2m > �[22mshould handle worker output buffer overflow�[32m 0�[2mms�[22m�[39m
1139:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mWorker Communication Failures�[2m > �[22mshould handle worker sudden death�[32m 0�[2mms�[22m�[39m
1140:  �[33m�[2m✓�[22m�[39m Network Failure Scenarios�[2m > �[22mRecovery from Network Failures�[2m > �[22mshould retry on transient network errors �[33m 301�[2mms�[22m�[39m
1141:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mRecovery from Network Failures�[2m > �[22mshould reconnect event bus subscriptions after failure�[32m 0�[2mms�[22m�[39m
1142:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mRecovery from Network Failures�[2m > �[22mshould handle partial message delivery�[32m 0�[2mms�[22m�[39m
1143:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mNetwork Latency Simulation�[2m > �[22mshould handle high latency operations�[32m 201�[2mms�[22m�[39m
1144:  �[31m   �[31m�[31m Network Failure Scenarios�[2m > �[22mNetwork Latency Simulation�[2m > �[22mshould handle packet loss simulation�[39m�[32m 6�[2mms�[22m�[39m
1145:  �[31m     → expected 0.4 to be less than 0.4�[39m
1146:  �[33m�[2m✓�[22m�[39m Network Failure Scenarios�[2m > �[22mNetwork Latency Simulation�[2m > �[22mshould handle bandwidth throttling �[33m 5007�[2mms�[22m�[39m
1147:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mEdge Cases�[2m > �[22mshould handle ECONNRESET errors�[32m 0�[2mms�[22m�[39m
1148:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mEdge Cases�[2m > �[22mshould handle EPIPE errors�[32m 0�[2mms�[22m�[39m
1149:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mEdge Cases�[2m > �[22mshould handle DNS resolution failures�[32m 0�[2mms�[22m�[39m
1150:  �[32m✓�[39m Network Failure Scenarios�[2m > �[22mEdge Cases�[2m > �[22mshould handle maximum retry exceeded�[32m 0�[2mms�[22m�[39m
1151:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mConnection Failures�[2m > �[22m�[2mshould handle database connection failure on initialization
1152:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1153:  Migration v1 applied successfully
1154:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mConnection Failures�[2m > �[22m�[2mshould handle database file permission errors
1155:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1156:  Migration v1 applied successfully
1157:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mConnection Failures�[2m > �[22m�[2mshould handle database closed errors
1158:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1159:  Migration v1 applied successfully
1160:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mLock and Timeout Failures�[2m > �[22m�[2mshould handle database lock timeout
1161:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1162:  Migration v1 applied successfully
1163:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mLock and Timeout Failures�[2m > �[22m�[2mshould handle transaction failures
1164:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1165:  Migration v1 applied successfully
1166:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mData Corruption Scenarios�[2m > �[22m�[2mshould handle corrupted task data retrieval
1167:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1168:  Migration v1 applied successfully
1169:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mData Corruption Scenarios�[2m > �[22m�[2mshould handle missing required columns
1170:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1171:  Migration v1 applied successfully
1172:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mDisk Space Issues�[2m > �[22m�[2mshould handle out of disk space errors gracefully
1173:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1174:  Migration v1 applied successfully
1175:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mRecovery and Resilience�[2m > �[22m�[2mshould recover from temporary database unavailability
1176:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1177:  Migration v1 applied successfully
1178:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mRecovery and Resilience�[2m > �[22m�[2mshould handle concurrent read/write operations
1179:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1180:  Migration v1 applied successfully
1181:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mRecovery and Resilience�[2m > �[22m�[2mshould handle invalid SQL injection attempts
1182:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1183:  Migration v1 applied successfully
1184:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mRecovery and Resilience�[2m > �[22m�[2mshould handle WAL mode checkpoint failures
1185:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1186:  Migration v1 applied successfully
1187:  �[90mstdout�[2m | tests/unit/error-scenarios/database-failures.test.ts�[2m > �[22m�[2mDatabase Failure Scenarios�[2m > �[22m�[2mSchema Migration Failures�[2m > �[22m�[2mshould handle incompatible schema versions
1188:  �[22m�[39mApplying migration v1: Baseline schema with tasks, dependencies, and output tables
1189:  Migration v1 applied successfully
1190:  �[32m✓�[39m tests/unit/error-scenarios/database-failures.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 126�[2mms�[22m�[39m
1191:  �[31m⎯⎯⎯⎯⎯⎯⎯�[39m�[1m�[41m Failed Tests 1 �[49m�[22m�[31m⎯⎯⎯⎯⎯⎯⎯�[39m
1192:  �[41m�[1m FAIL �[22m�[49m tests/unit/error-scenarios/network-failures.test.ts�[2m > �[22mNetwork Failure Scenarios�[2m > �[22mNetwork Latency Simulation�[2m > �[22mshould handle packet loss simulation
1193:  �[31m�[1mAssertionError�[22m: expected 0.4 to be less than 0.4�[39m
1194:  �[36m �[2m❯�[22m tests/unit/error-scenarios/network-failures.test.ts:�[2m336:30�[22m�[39m
1195:  �[90m334| �[39m      �[35mconst�[39m actualLossRate �[33m=�[39m failures �[33m/�[39m attempts�[33m;�[39m
1196:  �[90m335| �[39m      �[34mexpect�[39m(actualLossRate)�[33m.�[39m�[34mtoBeGreaterThan�[39m(�[34m0.2�[39m)�[33m;�[39m
1197:  �[90m336| �[39m      �[34mexpect�[39m(actualLossRate)�[33m.�[39m�[34mtoBeLessThan�[39m(�[34m0.4�[39m)�[33m;�[39m
1198:  �[90m   | �[39m                             �[31m^�[39m
1199:  �[90m337| �[39m    })�[33m;�[39m
1200:  �[90m338| �[39m
1201:  �[31m�[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯�[22m�[39m
1202:  �[2m Test Files �[22m �[1m�[31m1 failed�[39m�[22m�[2m | �[22m�[1m�[32m1 passed�[39m�[22m�[90m (2)�[39m
1203:  �[2m      Tests �[22m �[1m�[31m1 failed�[39m�[22m�[2m | �[22m�[1m�[32m31 passed�[39m�[22m�[90m (32)�[39m
1204:  �[2m   Start at �[22m 20:47:33
1205:  �[2m   Duration �[22m 11.26s�[2m (transform 175ms, setup 30ms, collect 178ms, tests 10.76s, environment 0ms, prepare 64ms)�[22m
1206:  ##[error]AssertionError: expected 0.4 to be less than 0.4
1207:   ❯ tests/unit/error-scenarios/network-failures.test.ts:336:30
1208:  
1209:  
1210:  ##[error]Process completed with exit code 1.
1211:  Post job cleanup.

@dean0x dean0x merged commit 1d35db1 into main Nov 28, 2025
1 of 2 checks passed
@dean0x dean0x deleted the fix/issue-28-graph-corruption-shallow-copy branch November 28, 2025 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CRITICAL: Shallow copy in wouldCreateCycle() corrupts dependency graph

1 participant