Skip to content

fix(server): review-fix sweep - #175

Open
Bnjoroge1 wants to merge 4 commits into
pr/5-otlp-exportfrom
pr/6-review-fixes
Open

fix(server): review-fix sweep#175
Bnjoroge1 wants to merge 4 commits into
pr/5-otlp-exportfrom
pr/6-review-fixes

Conversation

@Bnjoroge1

@Bnjoroge1 Bnjoroge1 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

The bot-review findings: classification can't be flipped by crafted runs-on labels (anchored prefix first), unreachable JobCompleted counter arm deleted, reason.detail bounded, store-backend label honors URL precedence, directory sizes no longer faked, scheduler heartbeat proves scan progress (not a self-beating timer), session-delete metric only on real deletes, one staleness constant across /readyz and /api/v1/status, real queue-wait latency at claim, InstrumentedStore deduped into one record() helper, unmeasured VM host usage serialized as absent not zero.

Top of the stacked series:

  1. log hardening
  2. foundation crate
  3. status endpoints
  4. metrics
  5. OTLP export
  6. this PR (review-fix sweep)

Summary by cubic

Fixes classification, metrics, and readiness semantics across the runner server so telemetry is accurate and health checks reflect real progress. Old behavior included misclassified terminations, synthetic metrics, and a timer-based heartbeat; new behavior enforces correct classification, measures real queue latency, and ties readiness to actual scheduler scans.

  • Binds termination reason classification to an anchored prefix first; crafted runs-on labels can’t flip “starvation” into “no_platform_runner”. Also bounds reason.detail to 512 chars on a character boundary.
  • Removes unreachable NdjsonEvent::JobCompleted counter; terminal transitions are recorded once via JobStatus.
  • Labels store backend by effective URL (explicit store_url overrides PRELOOP_STORE_URL), matching open_store and preventing mislabeling.
  • Reports only the database file as a storage component; drops inode-sized cache/artifacts placeholders until the recursive walker lands.
  • Replaces timer-based scheduler heartbeat with per-scan beats and deregistration on completion; a hung scan stops beating and readiness goes 503.
  • Records session-delete metrics only when an actual session is removed; no-op 204s no longer count.
  • Records true queue wait at claim using the enqueue timestamp; removes the 1s placeholder from the acquire path.
  • Deduplicates InstrumentedStore timing via a single record() helper so new methods cannot skip instrumentation.
  • Introduces preloop-vm::telemetry re-exports from preloop-observability and uses build_fleet_snapshot during bootstrap; unmeasured VM host usage is serialized as absent, not zero.

Written for commit 652fa67. Summary will update on new commits.

Review in cubic

Note

Fix metrics, heartbeat wiring, and snapshot construction in runner-server

  • Builds the operational VM fleet snapshot from the observability VM registry instead of a hardcoded Unavailable placeholder in bootstrap.rs
  • Replaces the external timer-based scheduler heartbeat with a registered HeartbeatHandle passed into Scheduler::scan_workspace and scan_remote, so beats fire per workflow entry and deregister on completion
  • Records real queue-wait duration at job claim sites using enqueued_at_unix_nanos instead of a fixed 1s value in broker.rs; stops emitting a delete ok session-transition metric when no session is found
  • Fixes bounded_termination_reason check order so starvation messages containing user labels are not misclassified as no_platform_runner; bounds exported reason detail to 512 chars and removes a redundant JobCompleted counter that double-counted terminal transitions in state.rs
  • Risk: store_url backend detection now prefers explicit config.store_url over PRELOOP_STORE_URL env var, so deployments relying solely on the env var while also setting store_url will see the config value take precedence
📊 Macroscope summarized 652fa67. 7 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted

🗂️ Filtered Issues

Bnjoroge and others added 4 commits August 20, 2026 21:39
… real queue wait

- The termination-reason classifier checked the interpolated platform
  substring before the anchored starvation prefix; a crafted runs-on label
  could flip its own classification. The anchored prefix now wins.
- The unreachable NdjsonEvent::JobCompleted counter arm is gone — the
  variant has no constructor anywhere, so the counter is single-sourced on
  terminal JobStatus.
- reason.detail (free-form prose interpolating workflow input) is bounded
  to 512 bytes on a character boundary.
- Store backend label mirrors open_store precedence: the environment is
  consulted only when no explicit URL was supplied.
- cache/artifacts directory sizes are no longer reported as inode size; the
  database file is the only component until the recursive walk lands.
- The scheduler heartbeat now proves scan progress: the scan tasks beat per
  workflow file and deregister on completion, so a hung or panicked scan
  goes stale and /readyz reports 503.
- Session-delete transitions record only when a session was actually
  removed.
- One STALENESS_THRESHOLD constant feeds /readyz and /api/v1/status.
- Claim path records true queue latency from the enqueue timestamp instead
  of a hardcoded 1s placeholder.
- InstrumentedStore collapsed into one record() helper so a new Store
  method cannot silently skip instrumentation.

Entire-Checkpoint: 01M0GZJX756GZ2SZ14BS9M4RPW
preloop-vm and preloop-orchestrator share the fleet registry through
preloop-observability instead of owning their own, avoiding a circular
dependency. The host sampler itself is a stub until the cgroup/process
parser lands.

Entire-Checkpoint: 01M0GZN3CAJJM3NXHQ4Q9QHKC4
Entire-Checkpoint: 01M0GZPVH9X85W3FJMQR7512W8
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

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: 27c37e2f-7519-4ead-89dc-679298917375

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

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

@Bnjoroge1 Bnjoroge1 mentioned this pull request Aug 21, 2026
9 tasks
Comment on lines +410 to +414
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos() as i64)
.unwrap_or(0);
let elapsed = std::time::Duration::from_nanos((now - queued.enqueued_at_unix_nanos) as u64);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium src/broker.rs:410

A backward wall-clock adjustment makes record_claim_queue_wait panic in debug builds or record a huge queue wait in release builds, corrupting the queue-wait histogram. now - queued.enqueued_at_unix_nanos can be negative when the clock rolls back or a persisted timestamp is ahead of now; use checked subtraction and skip negative results.

        .duration_since(std::time::UNIX_EPOCH)
-        .map(|d| d.as_nanos() as i64)
-        .unwrap_or(0);
-    let elapsed = std::time::Duration::from_nanos((now - queued.enqueued_at_unix_nanos) as u64);
+        .map(|d| d.as_nanos() as i64)
+        .unwrap_or(0);
+    let elapsed_nanos = match now.checked_sub(queued.enqueued_at_unix_nanos) {
+        Some(value) if value >= 0 => value,
+        _ => return,
+    };
+    let elapsed = std::time::Duration::from_nanos(elapsed_nanos as u64);
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @crates/preloop-runner-server/src/broker.rs around lines 410-414:

A backward wall-clock adjustment makes `record_claim_queue_wait` panic in debug builds or record a huge queue wait in release builds, corrupting the queue-wait histogram. `now - queued.enqueued_at_unix_nanos` can be negative when the clock rolls back or a persisted timestamp is ahead of `now`; use checked subtraction and skip negative results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant