Skip to content

fix(reborn): correlate run logs with thread_id/run_id for operator Logs panel - #4955

Merged
loopstring merged 4 commits into
mainfrom
fix/operator-logs-run-correlation
Jun 17, 2026
Merged

loopstring merged 4 commits into
mainfrom
fix/operator-logs-run-correlation

Conversation

@loopstring

Copy link
Copy Markdown
Contributor

Problem

The operator Logs panel's scoped (thread/run) view shows "0 entries" during active runs. Run-execution code emits no tracing events carrying thread_id/run_id, and OperatorLogLayer correlates entries by reading those fields from the enclosing span — so scoped queries match nothing.

Fix

Instrument both run-executor paths with a thread_id + run_id span plus an INFO anchor event, so every run yields at least one correlated entry:

  • ironclaw_reborn::turn_runner::execute_claimed_run — the serve/local-dev path the standalone binary actually uses
  • ironclaw_host_runtime::turn_scheduler executor task — the scheduler-backed path other deployments use

Verification

Built locally, ran ironclaw-reborn serve --port 3030, sent a chat message:

  • server log: INFO execute_claimed_run{thread_id=… run_id=…}: turn run started
  • Logs panel scoped to the thread: 1 entry ("turn run started") — previously 0.

Note

Default EnvFilter is info, so DEBUG-level driver/tool logs are still filtered before capture; surfacing those is a separate filter change. This PR fixes the "scoped logs are always empty" bug.

…gs panel

The operator Logs panel's scoped (thread/run) view showed "0 entries"
during active runs: run-execution code emitted no tracing events carrying
thread_id/run_id, and OperatorLogLayer reads those correlation fields from
the enclosing span, so scoped queries matched nothing.

Instrument both run-executor paths with a thread_id+run_id span plus an
INFO anchor event so every run yields at least one correlated entry:
- ironclaw_reborn::turn_runner::execute_claimed_run (serve/local-dev path)
- ironclaw_host_runtime::turn_scheduler executor task (scheduler path)

Verified via `ironclaw-reborn serve`: sending a chat message now produces a
thread/run-correlated "turn run started" entry in the Logs panel, which was
empty before.
@coderabbitai

coderabbitai Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 391adb4f-975b-4511-9feb-426838b85ea2

📥 Commits

Reviewing files that changed from the base of the PR and between c6b8b51 and d351f1c.

📒 Files selected for processing (5)
  • crates/ironclaw_host_runtime/src/turn_scheduler.rs
  • crates/ironclaw_host_runtime/tests/turn_scheduler_contract.rs
  • crates/ironclaw_reborn/src/turn_runner.rs
  • crates/ironclaw_reborn/tests/loop_driver_host.rs
  • crates/ironclaw_reborn_cli/src/runtime/mod.rs

📝 Walkthrough

Summary by CodeRabbit

  • Chores / Observability
    • Improved per-turn tracing by correlating log events with consistent run and thread identifiers.
    • Added clearer “turn run started” and “turn run finished” signals to simplify turn-level debugging.
    • Enhanced CLI tracing setup with separately configurable operator-log filtering to keep debug noise out of terminal output.
  • Tests
    • Updated tracing-related tests to capture span-scoped tracing output and verify it includes the expected thread_id and run_id correlation data.

Walkthrough

Tracing spans keyed by thread_id and run_id are added to execute_claimed_run in turn_runner.rs via #[tracing::instrument] and to the spawned executor task in turn_scheduler.rs via .instrument(run_span). Both sites emit lifecycle debug logs. Tests verify log correlation by the span identifiers using custom tracing layers that capture and correlate events. Tracing startup wiring is refactored to apply separate EnvFilters per layer, keeping debug output isolated to operator logs.

Changes

Per-run tracing instrumentation

Layer / File(s) Summary
Dependency updates
crates/ironclaw_host_runtime/Cargo.toml, crates/ironclaw_reborn/Cargo.toml
tracing-subscriber = "0.3" added to dev-dependencies and dependencies respectively.
Turn runner span and lifecycle events
crates/ironclaw_reborn/src/turn_runner.rs
execute_claimed_run wrapped with #[tracing::instrument] keyed by thread_id/run_id from claimed.state.*; emits tracing::debug!("turn run started") and tracing::debug!("turn run finished").
Turn runner tracing verification
crates/ironclaw_reborn/tests/loop_driver_host.rs
Custom tracing Layer captures span fields into extensions and merges them with event fields on emission; test installs capture layer and verifies "turn run started" event with expected thread_id/run_id.
Scheduler executor span and lifecycle events
crates/ironclaw_host_runtime/src/turn_scheduler.rs
spawn_executor_task imports tracing::Instrument and wraps spawned async block with .instrument(run_span) containing thread_id/run_id fields; emits info log at task start and debug log at finish.
Scheduler tracing verification
crates/ironclaw_host_runtime/tests/turn_scheduler_contract.rs
Custom tracing Layer captures and correlates span fields; test installs capture layer, executes a scheduled turn, and asserts "turn run started" event correlates with expected thread_id/run_id.
Operator log filtering configuration
crates/ironclaw_reborn_cli/src/runtime/mod.rs
init_tracing() applies separate EnvFilters to terminal-facing fmt logs (controlled by IRONCLAW_REBORN_LOG) and operator logs (controlled by IRONCLAW_REBORN_OPERATOR_LOG), enforcing debug output isolation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A span wraps each run, from start until the end,
Thread ID and run ID on each log message send,
Debug events flow through the instrumented thread,
No logic perturbed—just observers instead,
Tracing brings sight to the darkness ahead. 🔍

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title follows Conventional Commits style with type(scope):summary format and accurately describes the main fix: correlating run logs with thread_id/run_id for operator visibility.
Description check ✅ Passed Description explains the problem, fix, and verification; however, Validation and Review Track sections are unfilled, and Security/Database/Blast Radius sections lack explicit closure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@github-actions github-actions Bot added size: M 50-199 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: new First-time contributor labels Jun 16, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces tracing instrumentation to turn runs in both turn_scheduler.rs and turn_runner.rs by tagging events with thread_id and run_id to populate the operator Logs panel. Feedback on the changes suggests avoiding info! logging in REPL/TUI-reachable code like turn_runner.rs to prevent interface corruption, recommending the use of debug! logging instead.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread crates/ironclaw_reborn/src/turn_runner.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@crates/ironclaw_host_runtime/src/turn_scheduler.rs`:
- Around line 433-436: The issue is that tracing::info! is being used for run
lifecycle anchors in background execution paths, which violates the REPL/TUI
logging invariant (info! and warn! corrupt the terminal UI). Fix this across
three locations: in crates/ironclaw_host_runtime/src/turn_scheduler.rs lines
433-436, change the tracing::info! call for the "turn run started" message to
tracing::debug!; in crates/ironclaw_host_runtime/src/turn_scheduler.rs line 488,
change the run-finish anchor tracing::info! call to tracing::debug!; and in
crates/ironclaw_reborn/src/turn_runner.rs line 381, change the run-start anchor
tracing::info! call to tracing::debug!. Background tasks and internal
diagnostics must use debug! level logging to preserve correlation via span
fields without corrupting the terminal UI.

In `@crates/ironclaw_reborn/src/turn_runner.rs`:
- Around line 378-381: The tracing::info! call logging "turn run started"
violates the repo logging invariant for background tasks. Replace the
tracing::info! call with tracing::debug! to use the appropriate diagnostic level
for internal background task logging, maintaining correlation through span
fields rather than INFO-level diagnostics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e2362396-531e-47fe-897d-71678c52797c

📥 Commits

Reviewing files that changed from the base of the PR and between 46ad781 and 9ce5901.

📒 Files selected for processing (2)
  • crates/ironclaw_host_runtime/src/turn_scheduler.rs
  • crates/ironclaw_reborn/src/turn_runner.rs

Comment thread crates/ironclaw_host_runtime/src/turn_scheduler.rs Outdated
Comment thread crates/ironclaw_reborn/src/turn_runner.rs Outdated

@zmanian zmanian left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Correct, well-targeted fix — the root cause and the field names are right. Requesting changes on one hard blocker (missing test, which CI already enforces) plus one rule-conflict to confirm.

What's good

  • Root cause is right. OperatorLogLayer correlates by reading exactly thread_id / run_id from spans via from_root() (operator_logs.rs:171-174, 302-304). The new span fields use those exact names, so the fix lands where the layer actually looks.
  • The two paths are genuinely distinct, so no double-instrumentation: turn_scheduler drives the TurnRunExecutor trait (execute_claimed_run(claimed, transitions)), while turn_runner's is TurnRunnerWorker::execute_claimed_run(claimed, cancel) — different signatures, not nested.
  • skip_all is the right call — only the two correlation fields are recorded, so self/claimed/cancel aren't captured as span fields (no secret/bloat leak).
  • The INFO anchor is a sound workaround for the info-level EnvFilter (a debug! anchor would be filtered before capture, leaving the panel empty).

Blocking

  1. No regression test — and the Regression test enforcement check is failing because of it. This is a fix: with no test, which the repo gate rejects. A test would also lock the bug: install OperatorLogLayer, drive a run through the span, and assert a thread/run-scoped query returns ≥1 entry. Must-fix to merge.

Please confirm

  1. info! in background run-executor tasks vs. the repo rule. CLAUDE.md: "Background tasks must NEVER use info! — it breaks the interactive REPL/TUI." The info! here is deliberate (to survive the info filter), which is fine if these Reborn executors never run under the v1 Ratatui TUI subscriber (the serve path is an HTTP server, where info! is appropriate). Please confirm that — and if so, add a one-line note in the code so the next reader doesn't trip on the rule. If these can run under the TUI, the two anchor events per run will corrupt it and a different approach is needed (e.g. capture below the global filter rather than emitting info!).

Minor / polish

  1. Span-name inconsistency: turn_scheduler names the span "turn_run"; turn_runner's #[instrument] defaults to the fn name "execute_claimed_run". Add name = "turn_run" to the turn_runner instrument for a consistent operator-facing span name across both paths.
  2. Anchor asymmetry: turn_scheduler emits both "turn run started" and "turn run finished"; turn_runner emits only "started". Harmless, but a "finished" anchor would be symmetric.

@serrrfirat serrrfirat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Multi-agent review for nearai/ironclaw#4955 at 9ce590199f9f96c2951074c1470de7bf88953998.

Summary:

  • Security: 0 findings
  • Bugs: 0 findings
  • Performance/Concurrency: 0 findings
  • Tests: 2 findings
  • Conventions: 1 finding

Event: COMMENT. No Critical/High findings were found.

Retained findings:

  1. Medium tests: Reborn executor log correlation is untested.
  2. Medium tests: Scheduler executor log correlation is untested.
  3. Low conventions: Scheduler-only INFO finish log adds unnecessary operator/terminal noise.

Comment thread crates/ironclaw_reborn/src/turn_runner.rs
Comment thread crates/ironclaw_host_runtime/src/turn_scheduler.rs
Comment thread crates/ironclaw_host_runtime/src/turn_scheduler.rs Outdated
@github-actions github-actions Bot added the scope: dependencies Dependency updates label Jun 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@crates/ironclaw_host_runtime/src/turn_scheduler.rs`:
- Line 433: The tracing::debug! call for "turn run started" at line 433 is
emitted at DEBUG level, which means it gets filtered out when the default
EnvFilter is set to INFO. This prevents the operator correlation logic from
capturing the per-run anchor event, resulting in zero-row results for thread/run
scoped queries. Change the tracing::debug! call to tracing::info! so the anchor
event remains visible and can be captured for operator log correlation at the
default INFO log level.

In `@crates/ironclaw_reborn/src/turn_runner.rs`:
- Line 379: The tracing::debug! call for "turn run started" is filtered out by
the default EnvFilter (which passes only INFO and above) before it can reach
OperatorLogLayer, preventing the run-start anchor from being recorded in the
operator log buffer and causing scoped queries to show 0 entries in production.
Change the tracing::debug! macro to tracing::info! so the event passes through
the filter and reaches OperatorLogLayer, allowing the run-start anchor to
populate the operator log buffer correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 13238bc3-a6ca-40bb-8e90-e1953af463af

📥 Commits

Reviewing files that changed from the base of the PR and between 9ce5901 and 68e1b92.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock, !**/Cargo.lock
📒 Files selected for processing (6)
  • crates/ironclaw_host_runtime/Cargo.toml
  • crates/ironclaw_host_runtime/src/turn_scheduler.rs
  • crates/ironclaw_host_runtime/tests/turn_scheduler_contract.rs
  • crates/ironclaw_reborn/Cargo.toml
  • crates/ironclaw_reborn/src/turn_runner.rs
  • crates/ironclaw_reborn/tests/loop_driver_host.rs

Comment thread crates/ironclaw_host_runtime/src/turn_scheduler.rs
Comment thread crates/ironclaw_reborn/src/turn_runner.rs

Copy link
Copy Markdown
Collaborator

Human final-review guidance for current head c6b8b51a020443f43c1030fdbee2d2d6dd00d6b0:

CI is green, GitHub reports the PR as mergeable, and all review threads are resolved. The remaining blocker is human review state.

Please focus final review on:

  • Whether tracing::info!("turn run started") is acceptable as the operator-log anchor in both executor paths despite the usual REPL/TUI logging caution. The reason it is INFO is that the default INFO filter otherwise drops the only per-run anchor before OperatorLogLayer can capture it.
  • Whether the correlation fields are attached in the right runtime paths: ironclaw_host_runtime::turn_scheduler for scheduled/spawned runs and ironclaw_reborn::turn_runner::execute_claimed_run for Reborn worker runs.
  • Whether the two regression tests cover the intended production behavior: they install an INFO-level subscriber filter and assert the operator log remains queryable by the submitted thread_id / accepted run_id.
  • Whether the extra INFO event volume is acceptable operationally: one turn run started event per claimed run, with IDs only and no user content.

I would not spend time re-reviewing unrelated tracing or scheduler behavior outside those anchor/correlation paths unless something in the above looks wrong.

…debug

Addresses review: run lifecycle anchors must be debug! (info!/warn! corrupt
the REPL/TUI per the logging invariant). But debug! anchors were being dropped
by the info-level capture filter, leaving the Logs panel empty again.

Decouple terminal safety from Logs-panel visibility with per-layer filters in
init_tracing: the stderr/fmt layer stays at info (terminal-safe), while
OperatorLogLayer captures ironclaw run-path crates at debug. Both run anchors
move to debug!. Regression tests capture at DEBUG to mirror the operator filter.

Verified via `ironclaw-reborn serve`: stderr no longer prints the anchors, and
the scoped Logs panel shows the run's correlated entries (anchors plus the
model-gateway/loop-exit debug steps), which previously did not appear.
@think-in-universe

Copy link
Copy Markdown
Collaborator

Code review update for current head d351f1c8a03b72acea3ae699479f010010e8146e:

I reviewed the new commit d351f1c8 (fix(reborn): keep run log anchors at debug; capture operator logs at debug) across:

  • crates/ironclaw_reborn_cli/src/runtime/mod.rs:34
  • crates/ironclaw_host_runtime/src/turn_scheduler.rs:423
  • crates/ironclaw_reborn/src/turn_runner.rs:367
  • the updated regression tests in turn_scheduler_contract.rs and loop_driver_host.rs

No actionable code findings from this pass. The split tracing filters preserve the terminal invariant by keeping stderr at info while allowing OperatorLogLayer to capture debug run anchors for ironclaw_reborn and ironclaw_host_runtime.

CI note: Clippy (all-features) failed before compilation while downloading agent-client-protocol from crates.io (curl [55] ... unexpected eof while reading). That looks transient and unrelated to this PR; GitHub currently rejects rerunning the failed job because the workflow run is still in progress. I will retry the failed job once the run finishes if it remains red.

Not ready for human final review yet: CI is still in progress/red.

@think-in-universe

Copy link
Copy Markdown
Collaborator

Human final-review guidance for current head d351f1c8a03b72acea3ae699479f010010e8146e:

Current status:

  • CI check rollup is green.
  • No unresolved review threads are present.
  • GitHub reports the branch as mergeable with no conflicts.
  • Review decision still shows CHANGES_REQUESTED because of the earlier human review, so this needs a human re-review/approval to clear that state.

Suggested human review focus:

  1. Confirm the previous requested-changes concerns are satisfied: regression tests now cover run-log correlation, the run spans use consistent turn_run naming, and run anchor events use debug! rather than info!.
  2. Review the tracing filter split in crates/ironclaw_reborn_cli/src/runtime/mod.rs: stderr remains info-filtered for terminal safety, while OperatorLogLayer captures debug events from ironclaw_reborn and ironclaw_host_runtime.
  3. Review the run correlation paths in crates/ironclaw_host_runtime/src/turn_scheduler.rs and crates/ironclaw_reborn/src/turn_runner.rs to confirm thread_id / run_id spans are still correct for operator Logs panel scoping.
  4. Sanity-check the regression tests in crates/ironclaw_host_runtime/tests/turn_scheduler_contract.rs and crates/ironclaw_reborn/tests/loop_driver_host.rs for coverage of the intended user-visible Logs panel behavior.

I did not find additional actionable code issues on the current head.

@zmanian zmanian left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving — the fix is correctly diagnosed and well-architected. The per-layer filter split cleanly decouples terminal (REPL/TUI) safety from Logs-panel visibility, and the thread_id/run_id span fields match exactly what OperatorLogLayer correlates on via from_root. Tests drive both call sites end-to-end with the right runtime flavor.

A few minor, non-blocking items posted inline (addressing them or consciously deferring is fine):

  • The ~115-line tracing-capture test harness is duplicated byte-for-byte across two crates.
  • The new IRONCLAW_REBORN_OPERATOR_LOG env var and the IRONCLAW_REBORN_LOG behavior change should be documented in .env.example.
  • operator_filter captures all debug! from the whole ironclaw_reborn crate (broader than just run anchors) — fine given the bounded ring buffer, just flagging the volume/eviction tradeoff.

// populated, while those `debug!` events are NOT written to stderr. This is
// a *separate* per-layer filter, so terminal safety and Logs-panel
// visibility are decoupled. Override via IRONCLAW_REBORN_OPERATOR_LOG.
let operator_filter =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two config nits worth documenting in .env.example:

  1. New var undocumented. IRONCLAW_REBORN_OPERATOR_LOG is a new knob — please add it to .env.example alongside IRONCLAW_REBORN_LOG.
  2. Silent behavior change. Previously IRONCLAW_REBORN_LOG also governed OperatorLogLayer verbosity; now it only controls the stderr layer. Anyone who set IRONCLAW_REBORN_LOG=debug to enrich the Logs panel will silently lose that and must switch to IRONCLAW_REBORN_OPERATOR_LOG. Worth a note in the PR body and .env.example.

Also minor: this sets ironclaw_reborn=debug for the entire crate, so every debug! in it lands in the operator buffer, not just run-lifecycle anchors. The buffer is a bounded ring (operator_logs.rs pop_front at capacity), so no leak — but under heavy debug volume run anchors can be evicted faster than expected. Non-blocking; flagging the tradeoff.

events: Arc<Mutex<Vec<CapturedEvent>>>,
}

struct CorrelatedEventLayer {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This entire tracing-capture harness (CapturedEvent, CorrelatedEventCapture, CorrelatedEventLayer, CaptureVisitor, CapturedSpanFields, and the Layer/Visit impls — ~115 lines) is duplicated byte-for-byte in crates/ironclaw_reborn/tests/loop_driver_host.rs. Dev-only so not blocking, but a fix to one capture bug won't propagate. Consider extracting into a shared test-support location (ironclaw_common / ironclaw_loop_support both exist as candidate homes, behind a test-only feature), or at minimum add a // keep in sync with loop_driver_host.rs note.

events: Arc<Mutex<Vec<CapturedEvent>>>,
}

struct CorrelatedEventLayer {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Duplicate of the capture harness in crates/ironclaw_host_runtime/tests/turn_scheduler_contract.rs (see note there). Extracting to a shared test-support module would keep the two in sync.

@think-in-universe

Copy link
Copy Markdown
Collaborator

@claude review

@claude

claude Bot commented Jun 17, 2026

Copy link
Copy Markdown

Code Review PR #4955

Summary

This PR adds tracing instrumentation to correlate operator run logs with their thread/run IDs, enabling scoped log filtering in the operator Logs panel. The changes properly separate stderr (info level) from operator logs (debug level) to prevent debug output from corrupting the REPL/TUI.

Findings

Code Quality

[MEDIUM:75] Test code duplication across two test files

The CorrelatedEventCapture, CorrelatedEventLayer, CaptureVisitor, and related test helper types are duplicated identically in:

  • crates/ironclaw_host_runtime/tests/turn_scheduler_contract.rs (113 lines added)
  • crates/ironclaw_reborn/tests/loop_driver_host.rs (119 lines added)

Recommendation: Extract these test utilities into a shared test module to reduce duplication and maintenance burden.

Architecture & CLAUDE.md Compliance

✅ Logging levels correct: Uses debug! for internal diagnostics as specified in CLAUDE.md
✅ Separate filter hierarchy: Properly decouples stderr filter (info) from operator logs filter (debug)
✅ Async safety: Correctly uses .instrument(span) on async blocks and #[tracing::instrument] macro
✅ No production safety issues: No unwrap()/expect() in production code

Security & Safety

✅ No security vulnerabilities: No command injection, SSRF, or credential leaks
✅ Safe async patterns: All async/await properly handled

Performance & Production

✅ No performance regressions: Minimal overhead from span creation
✅ Proper resource handling: No leaks or unbounded allocations

Result: No blocking issues found

The code is production-ready with a recommendation to refactor test helper duplication in a follow-up PR.

@loopstring
loopstring added this pull request to the merge queue Jun 17, 2026
Merged via the queue into main with commit 4622c9c Jun 17, 2026
78 of 80 checks passed
@loopstring
loopstring deleted the fix/operator-logs-run-correlation branch June 17, 2026 20:36
theredspoon pushed a commit to theredspoon/ironclaw that referenced this pull request Jun 21, 2026
…gs panel (nearai#4955)

* fix(reborn): correlate run logs with thread_id/run_id for operator Logs panel

The operator Logs panel's scoped (thread/run) view showed "0 entries"
during active runs: run-execution code emitted no tracing events carrying
thread_id/run_id, and OperatorLogLayer reads those correlation fields from
the enclosing span, so scoped queries matched nothing.

Instrument both run-executor paths with a thread_id+run_id span plus an
INFO anchor event so every run yields at least one correlated entry:
- ironclaw_reborn::turn_runner::execute_claimed_run (serve/local-dev path)
- ironclaw_host_runtime::turn_scheduler executor task (scheduler path)

Verified via `ironclaw-reborn serve`: sending a chat message now produces a
thread/run-correlated "turn run started" entry in the Logs panel, which was
empty before.

* fix(reborn): keep run log anchors debug scoped

* fix(reborn): keep run log anchors visible at info

* fix(reborn): keep run log anchors at debug; capture operator logs at debug

Addresses review: run lifecycle anchors must be debug! (info!/warn! corrupt
the REPL/TUI per the logging invariant). But debug! anchors were being dropped
by the info-level capture filter, leaving the Logs panel empty again.

Decouple terminal safety from Logs-panel visibility with per-layer filters in
init_tracing: the stderr/fmt layer stays at info (terminal-safe), while
OperatorLogLayer captures ironclaw run-path crates at debug. Both run anchors
move to debug!. Regression tests capture at DEBUG to mirror the operator filter.

Verified via `ironclaw-reborn serve`: stderr no longer prints the anchors, and
the scoped Logs panel shows the run's correlated entries (anchors plus the
model-gateway/loop-exit debug steps), which previously did not appear.

---------

Co-authored-by: Yuting Wang <yuting.wang@near.ai>
Co-authored-by: think-in-universe <46699230+think-in-universe@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: new First-time contributor risk: low Changes to docs, tests, or low-risk modules scope: dependencies Dependency updates size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants