Skip to content

feat(console): add typed logs ledger and maintenance UI - #1176

Merged
ndizazzo merged 1 commit into
logging-api-v3from
logging-ui-v3
Aug 12, 2026
Merged

feat(console): add typed logs ledger and maintenance UI#1176
ndizazzo merged 1 commit into
logging-api-v3from
logging-ui-v3

Conversation

@ndizazzo

@ndizazzo ndizazzo commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Third and final PR in the logging stack, based on #1175. This layer delivers the operator-facing logs console, request inspector, maintenance workflows, and privacy-safe output projections.

System logs ledger

  • Adds typed API schemas, identifier parsing, query hooks, SSE recovery, and capability-aware live/harness clients.
  • Adds a combined request and operational-event ledger with search, time/category/state filters, sortable/resizable columns, column visibility, pagination, and bounded export.
  • Adds request-volume charts and outcome KPIs with chronological, outcome-specific trends.
  • Caps rendered chart buckets and automatically selects a safe interval for large/all-time windows.
  • Keeps relative live filters rolling and advances the chart clock while the page remains open.

Request Inspector

  • Adds a URL-addressable modal inspector with Overview, Payloads, Timeline, and Diagnostics tabs.
  • Shows canonical request metadata, retained artifact state, lifecycle evidence, routing attempts/retries, stream progress, token counts, and terminal outcomes.
  • Loads retained payload content only on explicit request, renders JSON inertly, and clearly distinguishes redacted, truncated, unavailable, missing, and corrupt artifacts.
  • Aggregates paginated events, artifacts, and attempts with a bounded cap and an explicit incomplete-evidence state.
  • Includes completed, active, failed, retry, empty, malformed, capability-unavailable, delete, and deep-link behavior.

Maintenance and recovery

  • Adds preview/confirm scoped cleanup, per-request deletion, partial-result diagnostics, safe retries, receipts, and authoritative refresh behavior.
  • Adds connection-state presentation for live SSE, polling fallback, replay-gap recovery, pause/resume, and capability-aware unavailable states.
  • Adds direct /logs and request-inspector route serving from the embedded console.

Configuration and terminal output

  • Exposes the canonical [logging.audit] settings in configuration schema/UI and CLI help. Because this feature is unreleased, there is no deprecated top-level [audit] compatibility layer.
  • Adds privacy-safe terminal projections for logging events, including cross-platform Windows drive/UNC/device path redaction and case-insensitive sensitive-key handling.
  • Keeps local trusted output distinct from redacted pretty/JSON projections.

Quality coverage

  • Adds unit and Playwright coverage for ledger workflows, request-inspector states, maintenance receipts, accessibility, responsive layouts, deep links, live recovery, and privacy boundaries.
  • Adds reduced-motion handling and named/keyboard-accessible regions and controls.

Screenshots

Captured from the final branch with deterministic test-harness data. The image assets are hosted separately and are not part of the commit.

Request log

System logs request and operational-event ledger

Request Inspector — overview

Completed request inspector overview

Request Inspector — redacted payload

Explicitly loaded and redacted request JSON

Request Inspector — stream and routing timeline

Stream lifecycle and routing-attempt timeline

Request Inspector — failed request diagnostics

Failed request diagnostics with terminal and retry evidence

Validation

  • PR Quality Checks — passed, including UI quality, formatting, Clippy, CI consistency, and CLI docs sync.
  • PR Builds — passed across affected crate tests, platform products, SDK smokes, and scripted/inference smokes.
  • PR Website Checks — passed.
  • Full UI suite on the final content: 1,299 passed, 3 skipped.
  • Focused request-log UI suite: 73 passed.
  • Config tests: 127 passed; focused host audit tests: 57 passed.
  • UI typecheck/build, cargo check -p mesh-llm, and workspace formatting passed locally.

Stack

Guardrails

This PR is the UI, configuration presentation, and terminal-projection layer. It does not change mesh/protobuf schemas, ALPN labels, the native ABI, or add an OTLP log API. The screenshots are hosted separately and are not committed to this branch.

Summary by CodeRabbit

  • New Features
    • Added a Logs tab with searchable, filterable request and audit history.
    • Added live updates, replay recovery, polling fallback, metrics, charts, pagination, and responsive layouts.
    • Added request inspection with overview, payloads, timeline, diagnostics, artifacts, exports, cleanup, and audited deletion.
    • Added logging configuration controls for retention, artifacts, replay, webhooks, and audit sinks.
  • Privacy
    • Added redacted, bounded log output and safe payload rendering.
  • Documentation
    • Added CLI and operator guidance for request logging and maintenance.
  • Bug Fixes
    • /logs deep links now correctly load the console.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a685450e-3d43-4d78-8684-c0d054d4caa5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds a feature-gated local Logs console with validated APIs, live SSE recovery, request inspection, payload and artifact views, audited maintenance actions, CLI logging projections, documentation, and real-console QA coverage.

Changes

Local logging foundations

Layer / File(s) Summary
Runtime, CLI, and TUI logging
crates/mesh-llm-cli/..., crates/mesh-llm-tui/..., crates/mesh-llm-host-runtime/...
Adds logging help, Logs deep-link routing, privacy-safe TUI projections, canonical request deduplication, and related tests.
Logs API and recovery
crates/mesh-llm-ui/src/features/logs/api/...
Adds validated identifiers, DTO schemas, live and harness clients, bounded pagination, SSE parsing, replay-gap recovery, and polling fallback.
Logs console UI
crates/mesh-llm-ui/src/features/logs/components/...
Adds the ledger, charts, request inspector, timelines, payload rendering, artifact metadata, exports, cleanup, deletion, and accessibility behavior.
Navigation and configuration
crates/mesh-llm-ui/src/app/..., crates/mesh-llm-ui/src/features/configuration/..., crates/mesh-llm-ui/src/features/shell/...
Adds Logs routes, navigation, feature flags, audit configuration settings, provider-filter navigation, and shared UI primitives.
Fixtures, documentation, and QA
crates/mesh-llm-ui/e2e/..., scripts/qa-logging-console-e2e.sh, docs/..., website/...
Adds deterministic fixtures, mocked and real E2E workflows, documentation, snapshots, and a standalone certification harness.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant LogsLedger
  participant LogsApiClient
  participant EventSource
  participant RequestInspector
  Operator->>LogsLedger: Open /logs
  LogsLedger->>LogsApiClient: Load request and audit pages
  LogsLedger->>EventSource: Subscribe to replay streams
  EventSource-->>LogsLedger: Deliver events or replay gaps
  LogsLedger->>LogsApiClient: Hydrate missing data
  Operator->>RequestInspector: Select a request
  RequestInspector->>LogsApiClient: Load request details and artifacts
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change by identifying the typed logs ledger and maintenance UI added to the console.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch logging-ui-v3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This pull request is currently a draft. Reviews will not take place until the PR is marked as ready for review.

@i386 i386 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.

Reviewed the PR head and posted three actionable inline findings: one request-amplification issue in live ledger recovery, one export-download race, and one E2E cleanup false-positive. Focused logs tests, lint, typecheck, build, shell validation, and diff checks passed; the full UI suite has one unrelated DataMode localStorage failure in this checkout, while the PR's Linux quality jobs are green and the wider build matrix is still running.

Comment thread crates/mesh-llm-ui/src/features/logs/api/use-logs-live-recovery.ts
Comment thread crates/mesh-llm-ui/src/features/logs/components/LogOperations.tsx
Comment thread scripts/qa-logging-console-e2e.sh

@coderabbitai coderabbitai 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.

Actionable comments posted: 9

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (27)
crates/mesh-llm-ui/src/features/logs/lib/log-grid.ts-29-39 (1)

29-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject or type unsupported column counts.

The class map supports only two through four columns. For example, trailingRowSpanClass(6, 5, 5, 'xl') calculates span 5 and returns undefined. The final cell does not fill the row. Constrain columns to supported values, or add mappings for every accepted value. Add a regression test for the selected behavior.

Proposed fix
-  if (columns < 2 || index < 0 || index >= count) return undefined
+  if (columns < 2 || columns > 4 || index < 0 || index >= count) return undefined
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/lib/log-grid.ts` around lines 29 - 39,
Constrain trailingRowSpanClass to the supported two-to-four column range,
rejecting unsupported values before span calculation so inputs such as six
columns cannot produce an unmapped span. Add a regression test covering the
selected rejection behavior and retain the existing valid-column span mapping.
crates/mesh-llm-ui/src/features/logs/lib/log-fixtures.test.ts-115-125 (1)

115-125: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Make the clock-dependent tests deterministic.

Use vi.useFakeTimers() and vi.setSystemTime() for these assertions. For fixture initialization, set the fake clock before evaluating the fixture module or inject a reference time.

  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures.test.ts#L115-L125: Remove host-clock dependence from fixture timestamp assertions.
  • crates/mesh-llm-ui/src/features/logs/lib/log-search.test.ts#L47-L70: Pass a fixed nowMs to query and range helpers.
  • crates/mesh-llm-ui/src/features/logs/lib/log-search.test.ts#L227-L243: Freeze the clock before testing relative-time labels.

As per coding guidelines, “Keep tests deterministic; avoid relying on real timers unless using fake timers.”

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/lib/log-fixtures.test.ts` around lines
115 - 125, The clock-dependent tests must be deterministic: in
crates/mesh-llm-ui/src/features/logs/lib/log-fixtures.test.ts:115-125, use
vi.useFakeTimers() and vi.setSystemTime() before fixture evaluation or inject a
fixed reference time, then remove Date.now() dependence; in
crates/mesh-llm-ui/src/features/logs/lib/log-search.test.ts:47-70, pass a fixed
nowMs to the query and range helpers; and in
crates/mesh-llm-ui/src/features/logs/lib/log-search.test.ts:227-243, freeze the
clock before asserting relative-time labels.

Source: Coding guidelines

crates/mesh-llm-ui/src/features/logs/lib/log-search.ts-27-45 (1)

27-45: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use elapsed durations for relative time presets.

setDate() and setHours() use local calendar time. A 24h or 7d range can become 23 or 25 hours across a daylight-saving transition. Calculate from from nowMs - durationMs so the REST scope always matches the selected duration.

Proposed fix
-  const now = new Date(nowMs)
-  const from = new Date(now.getTime())
-
-  switch (preset) {
-    case '1h':
-      from.setHours(from.getHours() - 1)
-      break
-    case '6h':
-      from.setHours(from.getHours() - 6)
-      break
-    case '24h':
-      from.setDate(from.getDate() - 1)
-      break
-    case '7d':
-      from.setDate(from.getDate() - 7)
-      break
-  }
-
-  return { from: from.toISOString(), to: now.toISOString() }
+  const durationMs =
+    preset === '1h' ? 3_600_000 :
+    preset === '6h' ? 6 * 3_600_000 :
+    preset === '24h' ? 24 * 3_600_000 :
+    7 * 24 * 3_600_000
+
+  return {
+    from: new Date(nowMs - durationMs).toISOString(),
+    to: new Date(nowMs).toISOString()
+  }
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/lib/log-search.ts` around lines 27 - 45,
Update the relative-time calculation around `now` and `from` to subtract fixed
millisecond durations from `nowMs` for each preset instead of using `setHours()`
or `setDate()`. Preserve the existing `from`/`to` ISO-string return shape while
ensuring `1h`, `6h`, `24h`, and `7d` always represent exact elapsed durations
across daylight-saving transitions.
crates/mesh-llm-ui/src/features/logs/lib/use-advancing-chart-clock.ts-8-16 (1)

8-16: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Refresh the clock when updates are re-enabled.

At Line 9, the hook returns the old current value until the next minute boundary after enabled changes from false to true. A finite chart range can exclude requests created during that delay. Set current from Date.now() before scheduling the aligned timeout. Add a fake-timer regression test for this transition.

Proposed fix
   useEffect(() => {
     if (!enabled) return
 
+    setCurrent(Date.now())
     let interval: number | undefined

Based on learnings, “Keep tests deterministic; avoid relying on real timers unless using fake timers.”

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/lib/use-advancing-chart-clock.ts` around
lines 8 - 16, Update the enabled branch of the use-advancing-chart-clock hook to
call setCurrent(Date.now()) immediately before calculating or scheduling the
aligned timeout, so re-enabling refreshes the clock without waiting for the next
boundary. Add a deterministic fake-timer regression test covering the
false-to-true enabled transition and verifying the current time updates
immediately.

Source: Learnings

scripts/qa-logging-console-e2e.sh-46-46 (1)

46-46: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reserve ports for all harness listeners.

--base-port 65534 and --base-port 65535 pass validation. The derived CONSOLE_PORT or BIND_PORT then exceeds 65535. Limit BASE_PORT to 65533.

Proposed fix
-[[ "$BASE_PORT" =~ ^[0-9]+$ && "$BASE_PORT" -gt 1024 ]] || { echo "error: invalid --base-port" >&2; exit 2; }
+[[ "$BASE_PORT" =~ ^[0-9]+$ && "$BASE_PORT" -gt 1024 && "$BASE_PORT" -le 65533 ]] || {
+    echo "error: invalid --base-port" >&2
+    exit 2
+}
🤖 Prompt for 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.

In `@scripts/qa-logging-console-e2e.sh` at line 46, Update the BASE_PORT
validation in the script’s argument-checking condition to reject values above
65533 while preserving the existing numeric and minimum-port checks, ensuring
derived CONSOLE_PORT and BIND_PORT values remain within the valid port range.
crates/mesh-llm-cli/src/parser/logging_help.rs-51-57 (1)

51-57: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Make the home-directory assertion portable.

Line 54 panics when HOME is unset. An empty HOME value also makes help.contains(&home) match every string. Read HOME and USERPROFILE conditionally, and compare only a non-empty absolute expanded path.

The PR objective requires cross-platform path redaction, so this test must not depend on one Unix environment variable.

Proposed fix
-        let home = std::env::var("HOME").expect("HOME should be available");
-
-        assert!(!help.contains(&home));
+        for variable in ["HOME", "USERPROFILE"] {
+            if let Ok(home) = std::env::var(variable) {
+                let home_path = std::path::Path::new(&home);
+                if !home.is_empty() && home_path.is_absolute() {
+                    let expanded = home_path.join(".mesh-llm/logging");
+                    let expanded = expanded.to_string_lossy();
+                    assert!(!help.contains(expanded.as_ref()));
+                }
+            }
+        }
🤖 Prompt for 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.

In `@crates/mesh-llm-cli/src/parser/logging_help.rs` around lines 51 - 57, Update
the test logging_help_does_not_expand_the_private_home_directory to
conditionally read HOME and USERPROFILE, filter out missing or empty values, and
assert only against non-empty absolute expanded paths so it remains portable
across platforms.
crates/mesh-llm-host-runtime/src/runtime/local/native_runtime_events/tests.rs-114-114 (1)

114-114: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Serialize every test that mutates the output sink.

The test at native_runtime_events/tests.rs:246 also calls set_output_sink and uses OutputSinkResetGuard, but it is not annotated with #[serial_test::serial]. Add the attribute to that test.

🤖 Prompt for 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.

In
`@crates/mesh-llm-host-runtime/src/runtime/local/native_runtime_events/tests.rs`
at line 114, Add #[serial_test::serial] to the test around set_output_sink and
OutputSinkResetGuard in native_runtime_events/tests.rs, matching the existing
annotation pattern and serializing all tests that mutate the output sink.
Justfile-17-21 (1)

17-21: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Restrict qa-logging-console-e2e to Unix hosts.

Windows is a supported platform, but this recipe requires a Bash script and the Unix binary path ./target/debug/mesh-llm. Add [unix] before the recipe or provide Windows-specific commands.

🤖 Prompt for 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.

In `@Justfile` around lines 17 - 21, Restrict the qa-logging-console-e2e recipe to
Unix hosts by adding the Justfile [unix] attribute before it, since its Bash
harness and ./target/debug/mesh-llm path are Unix-specific.
crates/mesh-llm-tui/src/output/logging_projection/privacy.rs-424-479 (1)

424-479: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the test portability and the doubled backslashes.

Two problems in these tests:

  1. Lines 425 and 467 call std::env::var("HOME").expect(...). HOME is not set on Windows, so both tests panic there instead of failing on a real privacy regression. Skip the home-path case when the variable is absent, or read USERPROFILE as a fallback.
  2. Line 470 uses r"startup failed opening C:\\Users\\operator\\config.toml". The string is raw, so the doubled backslashes are literal. The test therefore asserts on C:\\Users\\..., not the C:\Users\... form used at line 410. Use a single backslash.
💚 Proposed fix
-            r"startup failed opening C:\\Users\\operator\\config.toml".to_owned(),
+            r"startup failed opening C:\Users\operator\config.toml".to_owned(),
🤖 Prompt for 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.

In `@crates/mesh-llm-tui/src/output/logging_projection/privacy.rs` around lines
424 - 479, Make both privacy tests portable by replacing the mandatory HOME
lookups with an optional HOME value or a USERPROFILE fallback, and only include
the home-path case when a value is available. In
preserves_fatal_context_while_selectively_redacting_credentials_and_paths,
change the raw Windows path case to use single literal backslashes, matching the
path form used in redacts_the_operator_logging_privacy_corpus.
crates/mesh-llm-ui/src/features/logs/components/LogMaintenanceReceiptDiagnostics.tsx-6-6 (1)

6-6: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the partial-cascade condition with retry eligibility.

Line 6 treats a receipt as partial when state === 'partial' or artifactDeletion.failed > 0. hasRetryableArtifactWork in LogMaintenanceReceiptEligibility.ts (line 4) requires both conditions. A completed receipt that reports failed artifact files therefore shows "Partial cascade: … could not be removed", but no retry control appears. The operator sees a failure with no available action.

Either use the same predicate here, or state explicitly in the message that no retry is available for a completed receipt.

Also applies to: 25-31

🤖 Prompt for 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.

In
`@crates/mesh-llm-ui/src/features/logs/components/LogMaintenanceReceiptDiagnostics.tsx`
at line 6, Align the partial-cascade predicate in
LogMaintenanceReceiptDiagnostics with hasRetryableArtifactWork from
LogMaintenanceReceiptEligibility, requiring both a partial receipt state and
failed artifact deletions before showing the retry-related diagnostic. Preserve
the existing message for receipts that satisfy this retryable condition.
crates/mesh-llm-ui/src/features/logs/components/LogRoutingAttemptsTimeline.test.tsx-63-69 (1)

63-69: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the duration assertion locale-independent.

durationMs.toLocaleString() has no locale override, and the test setup does not pin one. Under de_DE.UTF-8, 1,000 ms renders as 1.000 ms; use an explicit locale or a separator-tolerant matcher.

🤖 Prompt for 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.

In
`@crates/mesh-llm-ui/src/features/logs/components/LogRoutingAttemptsTimeline.test.tsx`
around lines 63 - 69, Update the duration assertion in the
LogRoutingAttemptsTimeline test to avoid assuming a locale-specific thousands
separator. Use an explicit locale when formatting the expected value or a
matcher that accepts both comma and period separators, while preserving
validation of the 1,000 ms duration.
crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewDerivations.ts-26-38 (1)

26-38: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard formatDurationMs against NaN.

NaN passes every comparison as false, so execution reaches line 32. Math.floor(NaN / 60_000) returns NaN, and the function returns the string "NaNm NaNs". NaN reaches this function when Date.parse fails on a retained timestamp, which happens in formatRequestDuration at line 42 and in attemptDurationMs at line 80. Both results render directly in the Overview panel and the routing-attempt list. Treat a non-finite value as unrecorded.

🐛 Proposed fix
 export function formatDurationMs(durationMs: number | undefined): string {
-  if (durationMs === undefined || durationMs < 0) return 'Not recorded'
+  if (durationMs === undefined || !Number.isFinite(durationMs) || durationMs < 0) return 'Not recorded'
   if (durationMs < 1_000) return `${durationMs} ms`
🤖 Prompt for 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.

In
`@crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewDerivations.ts`
around lines 26 - 38, Update formatDurationMs to treat any non-finite duration,
including NaN, as unrecorded alongside undefined and negative values. Use a
finite-number guard before the existing formatting branches so invalid
Date.parse-derived values return “Not recorded” and valid durations retain their
current formatting.
crates/mesh-llm-ui/src/features/logs/components/LogRequestDeleteControl.tsx-129-140 (1)

129-140: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace the hard-coded log-delete-reason id with a generated id.

The id is static. If two LogRequestDeleteControl instances mount at the same time, for example one control in a ledger row and one control in the inspector footer, the document contains duplicate ids. The htmlFor association then resolves to the first match, and screen readers and getByLabelText queries target the wrong input. Use useId as LogPayloadPane.tsx does.

♿ Proposed fix using `useId`
-import { useRef, useState } from 'react'
+import { useId, useRef, useState } from 'react'
   const [pending, setPending] = useState(false)
   const triggerRef = useRef<HTMLButtonElement | null>(null)
+  const reasonId = useId()
               <label
                 className="grid gap-1.5 text-[length:var(--density-type-caption)] text-fg-dim"
-                htmlFor="log-delete-reason"
+                htmlFor={reasonId}
               >
                 <span className="type-label text-fg-faint">Required audit reason</span>
                 <Input
-                  id="log-delete-reason"
+                  id={reasonId}
                   onChange={(event) => setReason(event.currentTarget.value)}
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/components/LogRequestDeleteControl.tsx`
around lines 129 - 140, Update LogRequestDeleteControl to generate the reason
input identifier with React’s useId, following the existing pattern in
LogPayloadPane.tsx, and reuse that generated value for both the input id and
label htmlFor instead of the hard-coded “log-delete-reason”.
crates/mesh-llm-ui/e2e/logs/real-console.spec.ts-58-67 (1)

58-67: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Do not assert inside the expect.poll callback.

expect(response.ok()).toBeTruthy() on line 61 throws when the ledger returns a transient non-OK response. An exception inside the poll callback fails the test immediately; it does not trigger another poll attempt. Return a sentinel instead and let the outer matcher retry.

🐛 Proposed fix
     await expect
       .poll(async () => {
         const response = await page.request.get('/api/logs/requests?limit=10')
-        expect(response.ok()).toBeTruthy()
+        if (!response.ok()) return undefined
         const body = (await response.json()) as LogPage
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/e2e/logs/real-console.spec.ts` around lines 58 - 67,
Update the polling callback in the real-console request-log test to remove the
inner expect assertion on response.ok(). Return a falsy sentinel when the
response is non-OK so the outer toBeTruthy matcher retries, while preserving the
existing JSON parsing and request-ID matching for successful responses.
crates/mesh-llm-ui/src/components/ui/chart.tsx-129-138 (1)

129-138: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include the index in the tooltip item key.

dataKey comes from payload[0], so it is the same for every rendered item. If two payload entries share the same name, or both names are undefined, the keys collide and React logs a duplicate-key warning and can reuse the wrong node. Add the index.

🐛 Proposed fix
-              key={`chart-item-${String(itemName ?? '')}-${String(dataKey ?? '')}`}
+              key={`chart-item-${index}-${String(itemName ?? '')}`}
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/components/ui/chart.tsx` around lines 129 - 138,
Update the tooltip item key in the payload map to include the existing index
alongside itemName and dataKey, ensuring entries with duplicate or undefined
names receive unique React keys.
crates/mesh-llm-ui/src/components/ui/data-table-pagination.tsx-39-41 (1)

39-41: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

"Page 0 of 1" appears when the table is empty.

When pageCount is 0, the first expression renders 0 and Math.max(pageCount, 1) renders 1. The label reads "Page 0 of 1", which contradicts itself. Render both values from the same empty check.

🐛 Proposed fix
         <span className="type-caption text-fg-faint">
-          Page {pageCount === 0 ? 0 : pageIndex + 1} of {Math.max(pageCount, 1)}
+          Page {pageCount === 0 ? 0 : pageIndex + 1} of {pageCount}
         </span>
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/components/ui/data-table-pagination.tsx` around lines
39 - 41, Update the pagination label in the data table component so the
empty-table case uses consistent values for both the current page and total
pages, avoiding “Page 0 of 1.” Reuse the existing pageCount empty check in the
Page display and preserve the current one-based pagination values when pages
exist.
crates/mesh-llm-ui/e2e/logs/log-workflows.spec.ts-94-97 (1)

94-97: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

artifactDeletion reports removed equal to failed.

For completed the helper returns { removed: 0, failed: 0 }, and for partial it returns { removed: 1, failed: 1 }. A completed cleanup that removes nothing is an unusual fixture, and it can hide a rendering bug in the receipt counters. Set removed from the planned artifact count instead.

♻️ Suggested fixture change
 function artifactDeletion(state: 'previewed' | 'completed' | 'partial') {
   const failed = state === 'partial' ? 1 : 0
-  return { removed: failed, failed, ...(failed > 0 ? { failureClass: 'unsafe_path' } : {}) }
+  const removed = state === 'previewed' ? 0 : 2 - failed
+  return { removed, failed, ...(failed > 0 ? { failureClass: 'unsafe_path' } : {}) }
 }
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/e2e/logs/log-workflows.spec.ts` around lines 94 - 97,
Update artifactDeletion so removed reflects the planned artifact count for each
cleanup state rather than the failed count; keep failed derived from the partial
state and retain failureClass only when failures occur.
crates/mesh-llm-ui/e2e/configuration/schema-controls.spec.ts-313-333 (1)

313-333: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

auditSetting discards the category and label metadata it computes.

auditSetting calls setting(...) with category_id: 'logs-audit' and category_label: 'Security Audit', then replaces presentation with only control_hint. setting places label, help, category_id, and category_label inside presentation, so all of that metadata is dropped. The label and help options therefore have no effect on the fixture payload, and the "Security Audit" category is never sent.

If the intent is to exercise the fallback presentation path, keep the fixture minimal and remove the unused inputs. If the intent is to send category metadata, keep the presentation object from setting.

♻️ Option A: keep the fixture explicit about what it sends
 function auditSetting(
   canonicalPath: string,
   options: {
-    label: string
-    help: string
     value_schema: JsonRecord
     control_hint?: string
     apply_mode?: string
     restart_scope?: string
   }
 ) {
   const entry = setting(canonicalPath, {
     ...options,
+    label: canonicalPath,
+    help: canonicalPath,
     category_id: 'logs-audit',
     category_label: 'Security Audit'
   })
   return {
     ...entry,
     presentation: options.control_hint ? { control_hint: options.control_hint } : undefined
   }
 }
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/e2e/configuration/schema-controls.spec.ts` around lines
313 - 333, Update auditSetting to preserve the presentation object returned by
setting, including label, help, category_id, and category_label, while adding
control_hint without discarding existing metadata. If the fixture is
intentionally meant to test the fallback presentation path instead, remove the
unused label, help, and category inputs and keep the minimal payload explicit.
crates/mesh-llm-ui/src/components/ui/data-table-column-header.tsx-32-45 (1)

32-45: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Expose the current sort state to assistive technology

The sort icons are aria-hidden, and DataTable does not set aria-sort on <TableHead>. Extend the trigger's accessible name with the current sort state.

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/components/ui/data-table-column-header.tsx` around
lines 32 - 45, Update the sort trigger in the data-table column header to
include the current sort state in its accessible name, using the existing
column.getIsSorted() value to distinguish ascending, descending, and unsorted
states while preserving the visual icon behavior.
crates/mesh-llm-ui/e2e/logs/real-console.spec.ts-2-6 (1)

2-6: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Seed live data mode in the real-console test.

The harness runs target/debug/mesh-llm, and debug UI bundles default to harness. Set mesh-llm-ui-preview:data-mode:v2 to live before /logs loads so the certification uses real DTOs.

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/e2e/logs/real-console.spec.ts` around lines 2 - 6, Update
the real-console test setup before the /logs page loads to seed local storage
key mesh-llm-ui-preview:data-mode:v2 with the value live. Ensure this
initialization is applied in the harness-driven setup used by the real-console
test so the certification consumes live DTOs instead of the default harness
mode.
crates/mesh-llm-ui/src/components/ui/data-table.test.tsx-34-36 (1)

34-36: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Replace the real-time waits with fake timers.

These assertions depend on a 100 ms wall-clock delay. Slow or loaded CI workers can make these tests flaky. Use Vitest fake timers and restore real timers after each test.

Based on learnings: “Keep tests deterministic; avoid relying on real timers unless using fake timers.”

Also applies to: 60-62

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/components/ui/data-table.test.tsx` around lines 34 -
36, Replace the real-time setTimeout waits in the affected render-stability
assertions with Vitest fake-timer advancement, and configure fake timers for the
tests while restoring real timers after each test. Preserve the existing
settled-render expectations in both locations.

Source: Learnings

crates/mesh-llm-ui/src/features/configuration/components/DefaultsTab.tsx-222-228 (1)

222-228: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the dynamic-validation label reachable.

For schema-derived settings, dynamic_validation_only always reaches Line 226 before Line 227. crates/mesh-llm-ui/src/features/configuration/api/config-adapter.ts Lines 647-649 assign restart-required to every setting that is not dynamic_apply with no restart scope. Therefore, Validated on save never renders.

Place the dynamic-validation check before the mutability check if it is the intended status. If restart is also required, render a label that reports both states. Add regression coverage for dynamic_validation_only.

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/configuration/components/DefaultsTab.tsx`
around lines 222 - 228, Update applyModeLabel so the dynamic_validation_only
case is evaluated before the mutability === 'restart-required' fallback, making
“Validated on save” reachable for schema-derived settings. If both validation
and restart are required, return a label that communicates both states, and add
regression coverage for dynamic_validation_only.
crates/mesh-llm-ui/src/components/ui/data-table.tsx-147-153 (1)

147-153: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the visible leaf-column count for the empty-state span.

When columns are hidden, use Math.max(table.getVisibleLeafColumns().length, 1) instead of columns.length. Add a regression test for an empty table after hiding a column.

🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/components/ui/data-table.tsx` around lines 147 - 153,
Update the empty-state TableCell in the data table rendering to set colSpan from
Math.max(table.getVisibleLeafColumns().length, 1) instead of columns.length,
preserving at least one visible span when all columns are hidden. Add a
regression test covering an empty table after hiding a column.
crates/mesh-llm-ui/src/features/logs/api/client.ts-219-232 (1)

219-232: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Compare outcome by equality, not by substring.

Line 228 uses item.outcome.includes(query.outcome). outcome is a single enum value, not a list. A partial value such as cancel or ed matches unrelated rows. Every other filter on lines 223-229 uses equality. Use equality here so harness filtering matches the live endpoint contract.

🐛 Proposed fix
-    if (query.outcome && !item.outcome.includes(query.outcome)) return false
+    if (query.outcome && item.outcome !== query.outcome) return false
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/api/client.ts` around lines 219 - 232,
Update filterHarnessRequests to compare item.outcome and query.outcome with
equality rather than substring matching, preserving the existing optional-filter
behavior and aligning outcome filtering with the live endpoint contract.
crates/mesh-llm-ui/src/features/logs/api/client.ts-321-332 (1)

321-332: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Harness mode does not cover the whole logs read surface. LogsApiClient short-circuits harness mode for listRequests, getRequest, listRequestEvents, listRequestArtifacts, and listAudits, but two read paths still reach the network in harness mode. The shared root cause is a missing harness branch on those paths.

  • crates/mesh-llm-ui/src/features/logs/api/client.ts#L321-L332: the harness branch requires query.requestId. Add a harness result for listProxy when requestId is absent, so the method never calls this.#fetch in harness mode.
  • crates/mesh-llm-ui/src/features/logs/api/use-log-artifact-content-query.ts#L12-L21: getArtifact accepts no mode parameter, so the hook issues a live request even though dataMode.mode is part of the query key. Add a mode parameter with a harness branch to getArtifact, or drop mode from the key.
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/api/client.ts` around lines 321 - 332,
Update LogsApiClient.listProxy in
crates/mesh-llm-ui/src/features/logs/api/client.ts (lines 321-332) so harness
mode returns generated or otherwise appropriate local results even when
query.requestId is absent, and never reaches this.#fetch. Update getArtifact in
crates/mesh-llm-ui/src/features/logs/api/use-log-artifact-content-query.ts
(lines 12-21) to accept the query’s mode and provide a harness branch, or remove
mode from the query key; ensure harness-mode artifact reads do not issue live
requests.
crates/mesh-llm-ui/src/features/logs/api/use-logs-audit-query.ts-30-38 (1)

30-38: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Truncated results are reported as complete when the last page has no nextCursor.

Line 34 breaks out of the inner loop once items.length reaches AUDIT_MAX_RECORDS. The remaining entries in result.value.items are discarded. Line 38 then returns { items, nextCursor: undefined } with no incomplete flag if the server sent no nextCursor. The caller reads a truncated window as a complete one. Set incomplete when the cap stopped consumption.

🐛 Proposed fix
     for (const entry of result.value.items) {
       if (entryIds.has(entry.entryId)) continue
       entryIds.add(entry.entryId)
       items.push(entry)
       if (items.length === AUDIT_MAX_RECORDS) break
     }
 
+    const capped = items.length === AUDIT_MAX_RECORDS
     cursor = result.value.nextCursor
-    if (cursor === undefined) return { state: 'supported', value: { items, nextCursor: undefined } }
+    if (cursor === undefined) {
+      return capped
+        ? { state: 'supported', value: { items, nextCursor: undefined, incomplete: true } }
+        : { state: 'supported', value: { items, nextCursor: undefined } }
+    }
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/api/use-logs-audit-query.ts` around
lines 30 - 38, Track whether the loop in the audit query pagination flow stopped
because items.length reached AUDIT_MAX_RECORDS, and mark the returned result as
incomplete when that cap truncates result.value.items. Preserve the existing
nextCursor handling, but ensure the no-nextCursor return from the cursor loop
includes the incomplete state whenever entries were discarded due to the limit.
crates/mesh-llm-ui/src/features/logs/api/schemas.ts-766-784 (1)

766-784: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Validate the audit gap sequence ordering like the replay gap.

Line 768 rejects a replay gap where toSequence < fromSequence. parseAuditGap on lines 782-784 forwards the wire value with no equivalent check, so an inverted audit gap reaches useLogsLiveRecovery. Both gap kinds carry the same fromSequence/toSequence contract. Apply the same check.

🐛 Proposed fix
 export function parseAuditGap(input: unknown) {
-  return parseAuditGapWire(input)
+  const gap = parseAuditGapWire(input)
+  if (gap.toSequence < gap.fromSequence) throw new LogsDtoError()
+  return gap
 }
🤖 Prompt for 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.

In `@crates/mesh-llm-ui/src/features/logs/api/schemas.ts` around lines 766 - 784,
Update parseAuditGap to validate that toSequence is not less than fromSequence,
matching the ordering check in parseReplayGap; throw LogsDtoError for inverted
audit gaps before returning the parsed wire value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4cf4ec40-a34f-410e-bf64-eeb0fbac71eb

📥 Commits

Reviewing files that changed from the base of the PR and between d25681e and a04274b.

⛔ Files ignored due to path filters (7)
  • crates/mesh-llm-ui/package-lock.json is excluded by !**/package-lock.json
  • crates/mesh-llm-ui/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • logs-banner-mobile.png is excluded by !**/*.png
  • logs-desktop.png is excluded by !**/*.png
  • logs-history-mobile.png is excluded by !**/*.png
  • logs-populated-desktop.png is excluded by !**/*.png
  • logs-populated-mobile.png is excluded by !**/*.png
📒 Files selected for processing (186)
  • Justfile
  • crates/mesh-llm-cli/src/parser.rs
  • crates/mesh-llm-cli/src/parser/logging_help.rs
  • crates/mesh-llm-console-server/src/lib.rs
  • crates/mesh-llm-host-runtime/src/api/server.rs
  • crates/mesh-llm-host-runtime/src/api/tests/ui_routes.rs
  • crates/mesh-llm-host-runtime/src/logging/raw_mesh_lifecycle/tests.rs
  • crates/mesh-llm-host-runtime/src/runtime/local/native_runtime_events/tests.rs
  • crates/mesh-llm-tui/src/output/EVENTS.md
  • crates/mesh-llm-tui/src/output/dashboard.rs
  • crates/mesh-llm-tui/src/output/formatting.rs
  • crates/mesh-llm-tui/src/output/logging_projection.rs
  • crates/mesh-llm-tui/src/output/logging_projection/privacy.rs
  • crates/mesh-llm-tui/src/output/mod.rs
  • crates/mesh-llm-tui/src/output/state.rs
  • crates/mesh-llm-tui/src/output/tests/logging_projection.rs
  • crates/mesh-llm-tui/src/output/tests/mod.rs
  • crates/mesh-llm-ui/e2e/a11y/logs-a11y.spec.ts
  • crates/mesh-llm-ui/e2e/configuration/schema-controls.spec.ts
  • crates/mesh-llm-ui/e2e/logs/log-workflows.spec.ts
  • crates/mesh-llm-ui/e2e/logs/real-console.spec.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-capability.spec.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-fixtures.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-helpers.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-overview.spec.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-payloads.spec.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-routes.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector-test.ts
  • crates/mesh-llm-ui/e2e/logs/request-inspector.spec.ts
  • crates/mesh-llm-ui/package.json
  • crates/mesh-llm-ui/playwright.config.ts
  • crates/mesh-llm-ui/src/app/layout/RootLayout.test.tsx
  • crates/mesh-llm-ui/src/app/layout/RootLayout.tsx
  • crates/mesh-llm-ui/src/app/router/router.test.tsx
  • crates/mesh-llm-ui/src/app/router/router.tsx
  • crates/mesh-llm-ui/src/components/ui/CopyInstructionRow.test.tsx
  • crates/mesh-llm-ui/src/components/ui/CopyInstructionRow.tsx
  • crates/mesh-llm-ui/src/components/ui/DropdownMenu.tsx
  • crates/mesh-llm-ui/src/components/ui/FilterPopover.tsx
  • crates/mesh-llm-ui/src/components/ui/StatusBadge.tsx
  • crates/mesh-llm-ui/src/components/ui/chart.tsx
  • crates/mesh-llm-ui/src/components/ui/collapsible.tsx
  • crates/mesh-llm-ui/src/components/ui/data-table-column-header.tsx
  • crates/mesh-llm-ui/src/components/ui/data-table-pagination.tsx
  • crates/mesh-llm-ui/src/components/ui/data-table-view-options.tsx
  • crates/mesh-llm-ui/src/components/ui/data-table.test.tsx
  • crates/mesh-llm-ui/src/components/ui/data-table.tsx
  • crates/mesh-llm-ui/src/components/ui/scroll-area.tsx
  • crates/mesh-llm-ui/src/features/app-tabs/data.ts
  • crates/mesh-llm-ui/src/features/app-tabs/types.ts
  • crates/mesh-llm-ui/src/features/chat/pages/ChatPage.tsx
  • crates/mesh-llm-ui/src/features/configuration/api/config-adapter.test.ts
  • crates/mesh-llm-ui/src/features/configuration/api/config-adapter.ts
  • crates/mesh-llm-ui/src/features/configuration/api/runtime-settings.ts
  • crates/mesh-llm-ui/src/features/configuration/components/DefaultsTab.test.tsx
  • crates/mesh-llm-ui/src/features/configuration/components/DefaultsTab.tsx
  • crates/mesh-llm-ui/src/features/configuration/components/configuration-tab-ids.test.ts
  • crates/mesh-llm-ui/src/features/configuration/components/configuration-tab-ids.ts
  • crates/mesh-llm-ui/src/features/configuration/pages/ConfigurationPage.tsx
  • crates/mesh-llm-ui/src/features/configuration/pages/ConfigurationRoutePage.test.tsx
  • crates/mesh-llm-ui/src/features/configuration/pages/ConfigurationRoutePage.tsx
  • crates/mesh-llm-ui/src/features/logs/api/client.test.ts
  • crates/mesh-llm-ui/src/features/logs/api/client.ts
  • crates/mesh-llm-ui/src/features/logs/api/ids.ts
  • crates/mesh-llm-ui/src/features/logs/api/schemas.test.ts
  • crates/mesh-llm-ui/src/features/logs/api/schemas.ts
  • crates/mesh-llm-ui/src/features/logs/api/sse.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-log-artifact-content-query.test.tsx
  • crates/mesh-llm-ui/src/features/logs/api/use-log-artifact-content-query.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-log-request-details-query.test.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-log-request-details-query.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-logs-audit-query.test.tsx
  • crates/mesh-llm-ui/src/features/logs/api/use-logs-audit-query.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-logs-ledger-query.test.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-logs-ledger-query.ts
  • crates/mesh-llm-ui/src/features/logs/api/use-logs-live-recovery.test.tsx
  • crates/mesh-llm-ui/src/features/logs/api/use-logs-live-recovery.ts
  • crates/mesh-llm-ui/src/features/logs/components/CopyRequestIdButton.tsx
  • crates/mesh-llm-ui/src/features/logs/components/JsonPayloadView.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/JsonPayloadView.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogArtifactDownloadControl.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogArtifactMetadata.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogArtifactMetadata.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogArtifactStateBadges.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogCleanupDialog.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogCleanupScope.ts
  • crates/mesh-llm-ui/src/features/logs/components/LogDiagnosticArtifactList.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogEventInspector.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogEventInspector.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogEventLedgerColumns.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogMaintenanceReceiptDiagnostics.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogMaintenanceReceiptEligibility.ts
  • crates/mesh-llm-ui/src/features/logs/components/LogOperations.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogOperations.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogPayloadContent.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogPayloadPane.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDeleteControl.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDetails.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDetails.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDetailsDiagnosticsQueries.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDetailsOverviewQueries.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDiagnosticSummary.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDiagnostics.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestDiagnostics.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestEvidenceTimeline.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestEvidenceTimeline.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestInspectorFooter.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestInspectorFooter.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestInspectorHeader.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverview.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverview.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewDerivations.ts
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewEvidence.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewMetadata.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewOrdering.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestOverviewPanel.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestPayloads.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestPayloads.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRequestTimeline.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRoutingAttemptsTimeline.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogRoutingAttemptsTimeline.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogStreamTimeline.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogStreamTimeline.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogsEventLedger.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogsLedger.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogsLedger.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogsLedgerFilterPersistence.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/LogsLedgerInspectorCapability.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/RequestsOverTimeChart.test.tsx
  • crates/mesh-llm-ui/src/features/logs/components/RequestsOverTimeChart.tsx
  • crates/mesh-llm-ui/src/features/logs/lib/log-audit-fixtures.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-event-ledger.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-event-ledger.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/artifacts.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/audits.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/lifecycle-events.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/proxy-attempts.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/requests.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/support.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-grid.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-grid.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-inspector.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-instant.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-instant.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-kpis.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-kpis.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-payload-content.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-payload-content.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-request-details.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-request-details.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-search.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-search.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-timeline.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-timeline.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-token-usage.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-volume.test.ts
  • crates/mesh-llm-ui/src/features/logs/lib/log-volume.ts
  • crates/mesh-llm-ui/src/features/logs/lib/use-advancing-chart-clock.ts
  • crates/mesh-llm-ui/src/features/logs/pages/LogMaintenanceInvalidation.test.tsx
  • crates/mesh-llm-ui/src/features/logs/pages/LogRequestDetailsPage.test.tsx
  • crates/mesh-llm-ui/src/features/logs/pages/LogRequestDetailsPage.tsx
  • crates/mesh-llm-ui/src/features/logs/pages/LogsFeatureGate.tsx
  • crates/mesh-llm-ui/src/features/logs/pages/LogsLedgerPage.tsx
  • crates/mesh-llm-ui/src/features/reserves/components/ReservesSurface.tsx
  • crates/mesh-llm-ui/src/features/reserves/pages/ReservesPage.test.tsx
  • crates/mesh-llm-ui/src/features/shell/components/TopNav.test.tsx
  • crates/mesh-llm-ui/src/features/shell/components/TopNav.tsx
  • crates/mesh-llm-ui/src/lib/env.ts
  • crates/mesh-llm-ui/src/lib/feature-flags/definitions.ts
  • crates/mesh-llm-ui/src/lib/i18n/index.tsx
  • crates/mesh-llm-ui/src/styles/globals.css
  • crates/mesh-llm/src/lib.rs
  • docs/CLI.md
  • docs/LOGGING.md
  • docs/README.md
  • docs/USAGE.md
  • docs/design/DESIGN.md
  • docs/design/TESTING.md
  • docs/plugins/telemetry.md
  • logs-desktop-snapshot.md
  • logs-populated-desktop.md
  • logs-populated-mobile.md
  • scripts/qa-logging-console-e2e.sh
  • website/src/docs/pages/CLI.md

Comment thread crates/mesh-llm-tui/src/output/formatting.rs
Comment thread crates/mesh-llm-ui/e2e/logs/log-workflows.spec.ts Outdated
Comment thread crates/mesh-llm-ui/e2e/logs/request-inspector-fixtures.ts
Comment thread crates/mesh-llm-ui/src/components/ui/DropdownMenu.tsx
Comment thread crates/mesh-llm-ui/src/features/logs/api/use-logs-ledger-query.ts
Comment thread crates/mesh-llm-ui/src/features/logs/components/LogsLedger.tsx
Comment thread crates/mesh-llm-ui/src/features/logs/lib/log-fixtures/support.ts Outdated
Comment thread crates/mesh-llm-ui/src/features/logs/lib/log-search.ts
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