Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Nov 6, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
rivetkit-serverless Ready Ready Preview Comment Nov 6, 2025 5:37am
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Nov 6, 2025 5:37am
rivet-inspector Ignored Ignored Preview Nov 6, 2025 5:37am
rivet-site Ignored Ignored Preview Nov 6, 2025 5:37am

Copy link
Member Author

NathanFlurry commented Nov 6, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link

claude bot commented Nov 6, 2025

Code Review

Overview

This PR introduces a cached child logger with runner-specific attributes, improving observability by automatically attaching the runnerId to all log messages. This is a clean refactoring that reduces repetition across ~80 log statements.

Positive Aspects

  1. DRY Principle: Eliminates repetitive runnerId parameters across all log calls
  2. Consistent Logging: Ensures runnerId is automatically included in all log messages once the runner is connected
  3. Minimal Changes: The refactoring is focused and doesn't introduce unnecessary complexity
  4. Performance: Caching the child logger prevents recreating it on every log call

Issues and Concerns

1. Potential Race Condition in Logger Caching (Minor)

get log(): Logger | undefined {
    if (this.#logCached) return this.#logCached;

    const l = logger();
    if (l) {
        if (this.runnerId) {
            this.#logCached = l.child({
                runnerId: this.runnerId,
            });
            return this.#logCached;
        } else {
            return l;
        }
    }

    return undefined;
}

Issue: The cache is set based on whether this.runnerId exists. However, if log is called before the runner has a runnerId, the cache remains unset. When runnerId is later assigned, subsequent calls will still check the cache first, potentially missing the runnerId context.

Scenario:

  1. Call this.log before connection → returns base logger, cache not set
  2. Runner connects, runnerId is assigned
  3. Call this.log again → cache is still empty, creates child logger with runnerId
  4. Works correctly from this point

Actually, on closer inspection, this appears to work correctly because the cache is only set when runnerId exists. However, the logic could be clearer.

Recommendation: Consider adding a comment explaining that the cache is only populated after runnerId is available, or reset the cache when runnerId is set:

set runnerId(value: string) {
    this.#runnerId = value;
    this.#logCached = undefined; // Reset cache when runnerId changes
}

2. Missing Type Import (Minor)

The Logger type is imported in tunnel.ts but appears to already be available from the base code. Verify this doesn't introduce duplicate type imports if Logger is already imported elsewhere in the file.

3. Test Coverage (Important)

The test file (tests/lifecycle.test.ts) is entirely commented out. While this PR doesn't need to uncomment those tests, consider:

  • Are there any existing tests that validate logging behavior?
  • Should we add a simple test to verify the child logger includes runnerId?

Recommendation: At minimum, add a unit test that verifies:

test('log property creates child logger with runnerId', () => {
    const runner = new Runner(config);
    // Before runnerId is set
    expect(runner.log).toBeDefined();
    
    // Simulate connection and runnerId assignment
    runner.runnerId = 'test-runner-123';
    
    // Verify child logger includes runnerId in context
    // (This would require inspecting the pino child logger's bindings)
});

4. Documentation (Minor)

The getter has a brief comment, but consider documenting:

  • When the cache is populated
  • What happens if logger() is undefined
  • The lifecycle of the cached logger

Security Considerations

No security concerns identified. The change only affects logging infrastructure.

Performance Considerations

Improvement: Caching the child logger prevents recreating it on every log call, which is more efficient than the previous approach of adding runnerId to each log statement.

Adherence to Repository Standards

Based on CLAUDE.md:

Structured Logging: The PR maintains structured logging practices by using pino's child logger feature instead of formatting the runnerId into messages

Code Style: The changes follow existing patterns in the codebase

Naming Conventions: The #logCached private field follows the existing naming pattern

Suggestions

  1. Consider invalidating cache on reconnection: If a runner reconnects and gets a new runnerId, the cache should be cleared. Check if this scenario is possible.

  2. Add JSDoc comment:

/**
 * Returns a logger instance with runner-specific context.
 * Once the runner is connected and has a runnerId, this returns a cached
 * child logger that automatically includes the runnerId in all log messages.
 * Before connection, returns the base logger without runner context.
 */
get log(): Logger | undefined {
    // ...
}
  1. Tunnel logger pattern: The Tunnel class getter is clean and follows the delegation pattern well.

Verdict

✅ Approved with minor suggestions

This is a solid refactoring that improves code quality and observability. The main suggestions are around edge case handling and documentation. The implementation is correct for the common case and represents a clear improvement over the previous approach.

Great work on reducing repetition and improving the logging infrastructure! 🎯

@NathanFlurry NathanFlurry force-pushed the 11-05-chore_rivetkit_remove_warnings_for_graceful_runner_shtudown branch from 1da12da to abfe409 Compare November 6, 2025 01:00
@NathanFlurry NathanFlurry force-pushed the 11-05-chore_runner_add_child_logger_with_runner_id branch from c923a6f to 51912f8 Compare November 6, 2025 01:00
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 6, 2025

More templates

@rivetkit/actor

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/actor@3380

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@3380

@rivetkit/core

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/core@3380

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@3380

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@3380

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@3380

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@3380

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@3380

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@3380

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@3380

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@3380

commit: ff5ae6a

@claude
Copy link

claude bot commented Nov 6, 2025

Code Review

Summary

This PR introduces a child logger with runner-specific context (runner ID) to improve observability by automatically including the runnerId in all log messages. This is a good refactoring that reduces code duplication and makes logs more structured.

Positive Changes

Excellent refactoring - Removes repetitive runnerId fields from individual log calls (83 deletions vs 75 additions)
Better structured logging - Uses Pino's child logger feature properly for contextual logging
Consistent pattern - Applied uniformly across both mod.ts and tunnel.ts
Proper lazy initialization - Logger is only created when runnerId is available

Issues & Concerns

🔴 Critical: Stale Logger Cache Bug

Location: mod.ts:142-161

The #logCached field is never invalidated when runnerId changes. This creates a bug:

get log(): Logger | undefined {
    if (this.#logCached) return this.#logCached; // ❌ Returns stale logger!
    
    const l = logger();
    if (l) {
        if (this.runnerId) {
            this.#logCached = l.child({
                runnerId: this.runnerId, // This runnerId could be old
            });
            return this.#logCached;
        } else {
            return l;
        }
    }
    return undefined;
}

The problem is at mod.ts:612-613:

if (this.runnerId !== init.runnerId) {
    this.runnerId = init.runnerId; // ❌ Cache not cleared!

Impact: After a reconnect where runnerId changes, all logs will contain the OLD runnerId value, making debugging reconnection issues very difficult.

Fix: Clear the cache when runnerId changes:

if (this.runnerId !== init.runnerId) {
    this.runnerId = init.runnerId;
    this.#logCached = undefined; // Clear stale logger cache
    
    // Clear history if runner id changed
    this.#eventHistory.length = 0;
}

⚠️ Medium: Type Consistency

Location: tunnel.ts:3,39-41

The Tunnel class imports the Logger type but doesn't actually need it:

import type { Logger } from "pino"; // ❌ Unnecessary import

get log(): Logger | undefined { // Could be inferred
    return this.#runner.log;
}

Recommendation: Remove the explicit Logger import and type annotation since TypeScript can infer the return type from this.#runner.log. This reduces coupling and keeps the tunnel simpler.

💡 Minor: Commented Code

Locations: mod.ts:978, mod.ts:1389, mod.ts:1479, mod.ts:1510

There are several commented-out log statements:

//this.#log?.log("Sending command acknowledgment", this.#lastCommandIdx);

Recommendation: Either remove these entirely or uncomment them using the new this.log pattern with proper structured logging (e.g., this.log?.debug({ msg: "...", lastCommandIdx: this.#lastCommandIdx })).

Code Quality Assessment

Adherence to CLAUDE.md: ✅ Excellent

  • Follows structured logging pattern correctly
  • Log messages are lowercase as required
  • Uses ? syntax for optional logging as per tracing patterns

Performance: ✅ Good

  • Lazy initialization prevents unnecessary logger creation
  • Cached logger avoids repeated child() calls

Maintainability: ⚠️ Needs fix (cache invalidation bug)

Recommendations

  1. MUST FIX: Clear #logCached when runnerId changes (see critical issue above)
  2. SHOULD: Remove unnecessary Logger type import from tunnel.ts
  3. CONSIDER: Remove or update commented log statements
  4. CONSIDER: Add a test case that verifies logger context is updated on reconnection with a new runner ID

Test Coverage

No new tests were added. Given the critical bug found, I recommend adding a test that:

  • Simulates a runner receiving an init with runnerId A
  • Captures a log message and verifies it contains runnerId A
  • Simulates a reconnect with runnerId B
  • Captures a log message and verifies it contains runnerId B (this would currently fail)

Overall Assessment: Good refactoring with one critical bug that must be fixed before merging. The cache invalidation issue could lead to very confusing debugging sessions during runner reconnections.

@claude
Copy link

claude bot commented Nov 6, 2025

PR Review: Add child logger with runner ID

Summary

This PR refactors logging throughout the TypeScript runner to use a cached child logger that automatically includes the runnerId in all log entries. This eliminates the need to manually include runnerId in every log call.


✅ Strengths

  1. DRY Principle: Eliminates ~50 instances of manually adding runnerId to log calls, reducing code duplication
  2. Consistency: Ensures runnerId is always included in logs when available, preventing accidental omissions
  3. Clean Refactoring: The changes are purely mechanical replacements of logger() with this.log, making the diff easy to review
  4. Proper Caching: Uses lazy initialization pattern with caching to avoid recreating child loggers
  5. Backward Compatible: Gracefully handles the case where runnerId is not yet set by returning the default logger

🔍 Code Quality Observations

1. Cache Invalidation Issue ⚠️

Location: mod.ts:142-161

The current implementation has a subtle bug. The cached logger is created when runnerId is first set, but if runnerId changes (which the code explicitly handles at mod.ts:613), the cached logger will continue using the old runnerId.

get log(): Logger | undefined {
    if (this.#logCached) return this.#logCached; // ❌ Returns stale logger if runnerId changed
    
    const l = logger();
    if (l) {
        if (this.runnerId) {
            this.#logCached = l.child({
                runnerId: this.runnerId,
            });
            return this.#logCached;
        } else {
            return l;
        }
    }
    
    return undefined;
}

Recommendation: Clear the cache when runnerId changes:

// In mod.ts around line 613
if (this.runnerId !== init.runnerId) {
    this.runnerId = init.runnerId;
    this.#logCached = undefined; // Clear cached logger
    
    // Clear history if runner id changed
    this.#eventHistory.length = 0;
}

2. TypeScript Type Safety 💡

The log getter returns Logger | undefined, requiring all call sites to use optional chaining (this.log?.info(...)). While this is safe, consider if there are scenarios where logging should always be available and the undefined case represents a configuration error.

Question: Should the runner fail-fast if no logger is configured, or is silent operation acceptable?

3. Performance Consideration

The getter pattern is efficient:

  • Caching prevents repeated child logger creation
  • Minimal overhead (single property check on cache hit)
  • No memory leaks (single cached instance)

🧪 Test Coverage

Observation: The PR doesn't include test updates. Consider adding tests for:

  1. Logger properly includes runnerId after initialization
  2. Logger cache is valid and reused across calls
  3. Logger fallback behavior when runnerId is not set
  4. Critical: Logger cache invalidation when runnerId changes (if recommendation [SVC-2555] Set up issue templates #1 is implemented)

📊 Overall Assessment

This is a solid refactoring that improves code maintainability and logging consistency. The implementation is clean and follows good patterns, with one notable edge case that should be addressed.

Recommendation: ✅ Approve with minor changes

Required:

  • Fix cache invalidation when runnerId changes

Optional:

  • Add tests for the new logging behavior
  • Consider documenting when/why runnerId might change during runtime

🎯 Compliance with CLAUDE.md

  • ✅ Follows TypeScript/JavaScript conventions
  • ✅ Uses structured logging approach (Pino)
  • ✅ Changes are mechanical and maintain existing behavior
  • ✅ No unnecessary documentation files added

Nice work on improving the logging infrastructure! 🚀

@NathanFlurry NathanFlurry force-pushed the 11-05-chore_runner_add_child_logger_with_runner_id branch from 51912f8 to 4831d26 Compare November 6, 2025 02:16
@NathanFlurry NathanFlurry force-pushed the 11-05-chore_rivetkit_remove_warnings_for_graceful_runner_shtudown branch from abfe409 to 5b69155 Compare November 6, 2025 02:16
@claude
Copy link

claude bot commented Nov 6, 2025

PR Review: Add child logger with runner ID

Summary

This PR improves logging consistency by creating a child logger with runnerId context, eliminating the need to manually include runnerId in every log statement. The refactoring is clean and follows good structured logging practices.

Code Quality ✅

Strengths:

  • Clean refactoring that reduces code duplication
  • Follows structured logging best practices by using child loggers for contextual metadata
  • Consistent with the CLAUDE.md guideline: "Use tracing for logging. Do not format parameters into the main message"
  • The getter pattern with lazy caching is appropriate for this use case
  • All 83 deletions vs 75 additions shows good code reduction

Potential Issues ⚠️

1. Cache Invalidation Concern
The cached logger at mod.ts:140 is never invalidated when runnerId changes:

#logCached?: Logger;

get log(): Logger | undefined {
    if (this.#logCached) return this.#logCached;
    // ...
    if (this.runnerId) {
        this.#logCached = l.child({ runnerId: this.runnerId });
        return this.#logCached;
    }
    // ...
}

Issue: If runnerId changes during the runner's lifecycle (e.g., during reconnection), the cached logger will still contain the old runnerId.

Recommendation:

  • If runnerId is immutable after first assignment, add a comment documenting this assumption
  • If runnerId can change, invalidate the cache when it's updated, e.g.:
    set runnerId(value: string) {
        this.#runnerId = value;
        this.#logCached = undefined; // Invalidate cache
    }

2. Logging Before Runner Initialization
The log getter returns undefined when there's no runnerId yet (mod.ts:150-157). This means early lifecycle logs (before connection) won't have the runnerId context, which is expected but worth noting.

Question: Should we log a warning if attempting to log before the runner is initialized? Or is the current silent fallback to the base logger intentional?

Performance Considerations ✅

Positive:

  • Lazy initialization with caching avoids creating child loggers unnecessarily
  • Single child logger creation vs. creating context objects on every log call
  • Reduced memory allocations by eliminating repeated runnerId property in log calls

Negligible overhead:

  • The getter call adds minimal overhead compared to direct field access
  • Cache check is a simple null check

Security Concerns ✅

No security issues identified. This is a pure refactoring of logging code.

Test Coverage 📝

Observation: No test changes included in this PR.

Recommendations:

  • Add a test verifying the child logger includes runnerId in log output
  • Test behavior when logging before runnerId is set
  • If runnerId can change, test cache invalidation

Style & Convention ✅

  • Follows TypeScript private field naming convention (#logCached)
  • Consistent with existing codebase patterns
  • Comments are clear and helpful

Additional Notes

The same pattern is correctly applied to tunnel.ts:39-41 where the Tunnel class delegates to the runner's logger:

get log(): Logger | undefined {
    return this.#runner.log;
}

This is clean and maintains a single source of truth for the logger instance.

Verdict

Overall: Approve with minor suggestions

This is a solid refactoring that improves code quality and maintainability. The main concern is potential cache invalidation issues if runnerId can change during the runner lifecycle. Otherwise, the changes are well-executed and follow best practices.

@claude
Copy link

claude bot commented Nov 6, 2025

PR Review: Add child logger with runner id

Summary

This PR improves logging observability by creating a child logger with the runner ID automatically included in all log messages. This removes the need to manually add runnerId to every log statement.

Code Quality ✅

Strengths:

  • Clean refactoring: The implementation uses a getter with lazy initialization and caching, which is efficient
  • Consistent application: The change is applied systematically across all logging statements (92 additions, 95 deletions - nearly a 1:1 replacement)
  • Proper TypeScript patterns: Uses optional chaining (this.log?.info(...)) consistently
  • Extends to Tunnel class: The pattern is properly propagated to the Tunnel class via a getter

Implementation Review ✅

The logger getter (lines 142-161 in mod.ts):

get log(): Logger | undefined {
    if (this.#logCached) return this.#logCached;
    
    const l = logger();
    if (l) {
        if (this.runnerId) {
            this.#logCached = l.child({
                runnerId: this.runnerId,
            });
            return this.#logCached;
        } else {
            return l;
        }
    }
    
    return undefined;
}

Observations:

  • ✅ Properly caches the child logger to avoid recreating it on every call
  • ✅ Gracefully falls back to the default logger before runner ID is available
  • ✅ Handles the case when no logger is configured
  • ⚠️ Potential issue: The caching logic has a subtle bug - once #logCached is set, it will always be returned even if runnerId changes. However, this is likely acceptable since runner IDs shouldn't change during normal operation (only on reconnect with a new ID).

Potential Issues ⚠️

  1. Cache invalidation: When the runner ID changes (line 613-616), the cached logger is not cleared:
if (this.runnerId \!== init.runnerId) {
    this.runnerId = init.runnerId;
    // Missing: this.#logCached = undefined;
    this.#eventHistory.length = 0;
}

This means log messages after a runner ID change may still use the old runner ID until the getter is called again.

  1. Minor: The commented-out log statements (lines 978, 1389, 1479, 1510) should potentially be removed rather than just commented out if they're not needed.

Security Concerns ✅

No security issues identified. The runner ID is an internal identifier and doesn't expose sensitive information.

Performance Considerations ✅

  • ✅ Excellent - the caching prevents repeated child logger creation
  • ✅ The getter pattern is lightweight and doesn't add measurable overhead
  • ✅ Reduces code verbosity without sacrificing performance

Test Coverage ⚠️

The PR doesn't include test updates. Consider:

  • Testing that logs include runner ID after connection
  • Testing that logs work correctly before runner ID is assigned
  • Testing logger behavior on reconnection/runner ID change

Recommendations

Critical:

  1. Add cache invalidation when runner ID changes:
if (this.runnerId \!== init.runnerId) {
    this.runnerId = init.runnerId;
    this.#logCached = undefined; // Clear cached logger
    this.#eventHistory.length = 0;
}

Nice to have:
2. Remove commented-out log statements or document why they're kept
3. Consider adding a test that verifies runner ID appears in logs

Conclusion

This is a solid refactoring that improves code maintainability and logging consistency. The implementation is clean and follows good TypeScript patterns. The only critical issue is the missing cache invalidation on runner ID change, which should be addressed before merging.

Recommendation: Approve with minor fixes 👍


Reviewed with Claude Code - focusing on code quality, best practices, and potential issues

@NathanFlurry NathanFlurry force-pushed the 11-05-chore_runner_add_child_logger_with_runner_id branch from 4831d26 to ff5ae6a Compare November 6, 2025 05:36
@NathanFlurry NathanFlurry force-pushed the 11-05-chore_rivetkit_remove_warnings_for_graceful_runner_shtudown branch from 5b69155 to c179f06 Compare November 6, 2025 05:36
@claude
Copy link

claude bot commented Nov 6, 2025

PR Review: Add child logger with runner id

Summary

This PR introduces a child logger with runner-specific attributes to improve log traceability. The implementation creates a cached logger getter that automatically includes the runnerId in all log messages, eliminating the need to manually add it to each log statement.

✅ Strengths

  1. DRY Principle: Eliminates repetitive runnerId parameters across 30+ log statements
  2. Consistent Logging: Ensures runner ID is always included once available, reducing chance of missing context
  3. Performance: Implements caching to avoid recreating child loggers on every call
  4. Clean Refactoring: Changes are mechanical and straightforward throughout

🔍 Code Quality Observations

Implementation Pattern

The logger getter implementation is solid:

get log(): Logger | undefined {
  if (this.#logCached) return this.#logCached;
  
  const l = logger();
  if (l) {
    if (this.runnerId) {
      this.#logCached = l.child({ runnerId: this.runnerId });
      return this.#logCached;
    } else {
      return l;
    }
  }
  return undefined;
}

Potential Issue: The cache is set only when runnerId exists. If log is called before the runner connects (when runnerId is undefined), it returns the base logger. Once runnerId becomes available, subsequent calls will cache the child logger. This works correctly, but the transition point is subtle.

🐛 Potential Issues

1. Logger Cache Invalidation (Minor)

The cached logger is created when runnerId first becomes available, but if runnerId ever changes (unlikely but possible during reconnection scenarios), the cached logger won't update.

Recommendation: Consider invalidating the cache if the implementation allows runner ID changes:

get log(): Logger | undefined {
  const l = logger();
  if (l) {
    if (this.runnerId) {
      // Recreate if runnerId changed
      if (\!this.#logCached || this.#lastRunnerId \!== this.runnerId) {
        this.#logCached = l.child({ runnerId: this.runnerId });
        this.#lastRunnerId = this.runnerId;
      }
      return this.#logCached;
    }
    return l;
  }
  return undefined;
}

However, if runner IDs are immutable once set, the current implementation is fine.

2. Commented Debug Logs (Cleanup Opportunity)

Found several commented log lines:

  • Line 978: //this.#log?.log(...)
  • Lines 1389, 1479, 1510: Similar commented logs

Recommendation: Remove these commented lines in a follow-up cleanup if they're no longer needed.

🔒 Security Considerations

No security concerns identified. The change is purely internal logging infrastructure.

⚡ Performance Considerations

Positive:

  • Caching prevents repeated child logger creation
  • Removes object creation overhead from inline { runnerId: this.runnerId } in every log call

Note: The getter is called frequently (50+ times per file). The caching strategy is appropriate.

🧪 Test Coverage

The test file (lifecycle.test.ts) is currently commented out entirely. While this PR doesn't change functionality (only logging), consider:

  1. Logging Tests: Verify that logs include runnerId after connection
  2. Log Behavior Before Connection: Ensure logs work correctly before runnerId is set

Recommendation: Enable and update tests to verify the logging behavior, especially around the connection lifecycle.

📝 Code Style

Adheres to TypeScript conventions. The use of private fields (#logCached) and getters is idiomatic.

✨ Suggestions for Improvement

  1. Type Safety: Consider a more explicit type for when logger is unavailable:

    get log(): Logger | undefined {
      // Current implementation
    }

    The current typing is good; just ensure callers always use optional chaining (this.log?.info(...)), which the PR does consistently.

  2. Documentation: Add a JSDoc comment explaining the caching behavior:

    /**
     * Returns a child logger with runner-specific context.
     * Caches the logger once runnerId is available to avoid repeated allocations.
     * Returns undefined if no logger is configured.
     */
    get log(): Logger | undefined {

🎯 Summary

This is a clean, well-executed refactoring that improves code maintainability and logging consistency. The changes are low-risk and provide clear benefits.

Recommendation: ✅ Approve with minor suggestions

The suggestions above are optional improvements, not blockers. The PR is ready to merge as-is.


Review generated with assistance from Claude Code

@graphite-app
Copy link
Contributor

graphite-app bot commented Nov 6, 2025

Merge activity

  • Nov 6, 5:47 AM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Nov 6, 5:48 AM UTC: CI is running for this pull request on a draft pull request (#3395) due to your merge queue CI optimization settings.
  • Nov 6, 5:50 AM UTC: Merged by the Graphite merge queue via draft PR: #3395.

@graphite-app graphite-app bot closed this Nov 6, 2025
@graphite-app graphite-app bot deleted the 11-05-chore_runner_add_child_logger_with_runner_id branch November 6, 2025 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants