Skip to content

Add Skippy request cache epoch telemetry - #817

Merged
i386 merged 2 commits into
mainfrom
codex/skippy-request-cache-epochs
Jun 13, 2026
Merged

Add Skippy request cache epoch telemetry#817
i386 merged 2 commits into
mainfrom
codex/skippy-request-cache-epochs

Conversation

@i386

@i386 i386 commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add a typed request/cache epoch view for Skippy binary stage messages and emit checkpoint generation in server telemetry.

This PR is about request/cache coordination vocabulary. It does not add protocol fields, change encoded bytes, or reject stale frames yet.

Before

The stage message already carried the pieces needed to identify a cache generation:

  • request_id
  • session_id
  • checkpoint_generation
  • prompt_token_count
  • decode_step

But code treated them as separate fields. Telemetry had prompt/decode information, but not checkpoint generation in the common binary-message attribute set.

How It Works

StageRequestEpoch groups the existing identity fields:

request_id + session_id + checkpoint_generation + prompt_token_count + decode_step

StageWireMessage::request_epoch() derives the value from an existing message.

The helper also supports:

  • same_flow(...) for request/session matching
  • is_stale_for(...) for future stale-frame/cache-epoch checks

skippy-server now uses the epoch helper in binary transport telemetry and emits:

skippy.checkpoint_generation=3
skippy.prompt_token_count=8192
skippy.decode_step=0

Why This Is Good

Skippy is getting more aggressive about prefix/cache reuse, restore, trim, prefill, and decode overlap. Those paths need one shared way to talk about which cache generation a frame belongs to.

This PR creates that vocabulary without changing behavior yet. It makes future stale restore/trim/decode checks smaller and easier to review because the identity comparison is centralized.

Compatibility

This is not a wire-format change.

  • no new encoded fields
  • no stage state version bump
  • no protobuf/gossip change
  • no mixed-version binary framing break

The skippy-protocol crate changes, but the bytes sent between stages do not.

Validation

  • cargo fmt --all -- --check
  • cargo test -p skippy-protocol --lib
  • cargo test -p skippy-server --lib
  • cargo clippy -p skippy-protocol --all-targets -- -D warnings
  • cargo clippy -p skippy-server --all-targets -- -D warnings
  • cargo check -p mesh-llm
  • cargo clippy -p mesh-llm --all-targets -- -D warnings

Summary by CodeRabbit

  • Refactor
    • Improved request-epoch tracking to more reliably identify request/session flows and progression state.
    • Telemetry now reports checkpoint, prompt, and decode progression using consistent attribute keys.
  • New Features
    • Exposed a compact epoch snapshot used for comparing flow identity and staleness.
  • Tests
    • Added unit tests validating flow matching and staleness ordering across progression fields.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e8eab08-34e6-4d62-915c-85750ac8dadc

📥 Commits

Reviewing files that changed from the base of the PR and between e787d6f and bf33153.

📒 Files selected for processing (4)
  • crates/skippy-metrics/src/lib.rs
  • crates/skippy-protocol/src/binary/mod.rs
  • crates/skippy-protocol/src/binary/types.rs
  • crates/skippy-server/src/binary_transport.rs
✅ Files skipped from review due to trivial changes (1)
  • crates/skippy-metrics/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/skippy-server/src/binary_transport.rs
  • crates/skippy-protocol/src/binary/mod.rs
  • crates/skippy-protocol/src/binary/types.rs

📝 Walkthrough

Walkthrough

Adds StageRequestEpoch (identity + checkpoint/prompt/decode fields), epoch extraction on wire messages, staleness/flow-checking methods and tests, metric attribute constants, and refactors server telemetry to use epoch-derived attributes.

Changes

Request Epoch Type and Telemetry Integration

Layer / File(s) Summary
StageRequestEpoch type and message extraction
crates/skippy-protocol/src/binary/types.rs
StageRequestEpoch struct with request_id, session_id, checkpoint_generation, prompt_token_count, decode_step; same_flow() and is_stale_for() methods; StageWireMessage::request_epoch() extractor.
Metric attribute constants
crates/skippy-metrics/src/lib.rs
Adds attr::PROMPT_INDEX, attr::MESSAGE_KIND, attr::TOKEN_COUNT, attr::CHECKPOINT_GENERATION, attr::PROMPT_TOKEN_COUNT, attr::DECODE_STEP.
Protocol export and epoch validation tests
crates/skippy-protocol/src/binary/mod.rs
Re-exports StageRequestEpoch; updates stage_message_round_trips_f32 to include checkpoint_generation in assertions; adds tests request_epoch_orders_only_matching_flows and request_epoch_staleness_orders_generation_before_prompt_before_decode.
Server telemetry integration
crates/skippy-server/src/binary_transport.rs
binary_message_attrs and BinaryRequestSummary::emit now derive checkpoint_generation, prompt_token_count, and decode_step from message.request_epoch() and use attr::* constants for telemetry keys.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% 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 accurately summarizes the main change: adding request cache epoch telemetry support to Skippy. It is concise, clear, and directly reflects the PR's primary objective of introducing StageRequestEpoch and emitting checkpoint-related telemetry metrics.
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.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/skippy-request-cache-epochs

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

@i386 i386 changed the title [codex] Add Skippy request cache epoch telemetry Add Skippy request cache epoch telemetry Jun 10, 2026
@i386
i386 marked this pull request as ready for review June 10, 2026 10:42
@i386
i386 requested a review from michaelneale June 10, 2026 10:43

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

🧹 Nitpick comments (2)
crates/skippy-protocol/src/binary/types.rs (1)

360-371: ⚡ Quick win

Consider adding documentation for staleness semantics.

The is_stale_for method uses lexicographic comparison of (checkpoint_generation, prompt_token_count, decode_step) to determine staleness, which gives checkpoint_generation the highest priority, followed by prompt_token_count, then decode_step. While the implementation is correct, a doc comment would clarify the intended semantics and precedence order for future maintainers.

📝 Suggested documentation
+    /// Returns true if this epoch is stale (outdated) compared to `current`.
+    ///
+    /// Two epochs can only be compared if they belong to the same flow (same request_id and session_id).
+    /// Staleness is determined by lexicographic comparison of (checkpoint_generation, prompt_token_count, decode_step),
+    /// meaning checkpoint_generation takes precedence, followed by prompt_token_count, then decode_step.
     pub fn is_stale_for(self, current: Self) -> bool {
🤖 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/skippy-protocol/src/binary/types.rs` around lines 360 - 371, Add a doc
comment to the is_stale_for method that explains the staleness semantics: state
is considered stale only if same_flow(current) is true and the tuple
(checkpoint_generation, prompt_token_count, decode_step) is lexicographically
less than the current tuple, meaning checkpoint_generation has highest
precedence, then prompt_token_count, then decode_step; mention what each field
represents for staleness comparison and that the comparison is strict (<), and
reference same_flow to clarify flow matching is required before comparing
generations/steps.
crates/skippy-protocol/src/binary/mod.rs (1)

217-243: 💤 Low value

Consider expanding test coverage for lexicographic ordering.

The test verifies decode_step ordering but doesn't test that checkpoint_generation takes precedence over prompt_token_count, or that prompt_token_count takes precedence over decode_step. While the implementation uses standard Rust tuple comparison (which is well-defined), explicit tests would document the intended behavior more clearly.

🧪 Example additional test cases
// Verify checkpoint_generation takes precedence
let lower_checkpoint = StageRequestEpoch {
    request_id: 7,
    session_id: 11,
    checkpoint_generation: 0,
    prompt_token_count: 100,
    decode_step: 100,
};
let higher_checkpoint = StageRequestEpoch {
    request_id: 7,
    session_id: 11,
    checkpoint_generation: 1,
    prompt_token_count: 0,
    decode_step: 0,
};
assert!(lower_checkpoint.is_stale_for(higher_checkpoint));
assert!(!higher_checkpoint.is_stale_for(lower_checkpoint));
🤖 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/skippy-protocol/src/binary/mod.rs` around lines 217 - 243, Add
explicit unit tests to cover lexicographic ordering precedence for
StageRequestEpoch: add cases that verify checkpoint_generation dominates
prompt_token_count and prompt_token_count dominates decode_step by constructing
StageRequestEpoch instances with differing
checkpoint_generation/prompt_token_count/decode_step (while keeping request_id
and session_id equal) and asserting expected results from is_stale_for and
same_flow; reference the StageRequestEpoch struct and its methods is_stale_for
and same_flow and add tests similar to the existing
request_epoch_orders_only_matching_flows test to document and validate the
intended ordering (checkpoint_generation > prompt_token_count > decode_step).
🤖 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.

Nitpick comments:
In `@crates/skippy-protocol/src/binary/mod.rs`:
- Around line 217-243: Add explicit unit tests to cover lexicographic ordering
precedence for StageRequestEpoch: add cases that verify checkpoint_generation
dominates prompt_token_count and prompt_token_count dominates decode_step by
constructing StageRequestEpoch instances with differing
checkpoint_generation/prompt_token_count/decode_step (while keeping request_id
and session_id equal) and asserting expected results from is_stale_for and
same_flow; reference the StageRequestEpoch struct and its methods is_stale_for
and same_flow and add tests similar to the existing
request_epoch_orders_only_matching_flows test to document and validate the
intended ordering (checkpoint_generation > prompt_token_count > decode_step).

In `@crates/skippy-protocol/src/binary/types.rs`:
- Around line 360-371: Add a doc comment to the is_stale_for method that
explains the staleness semantics: state is considered stale only if
same_flow(current) is true and the tuple (checkpoint_generation,
prompt_token_count, decode_step) is lexicographically less than the current
tuple, meaning checkpoint_generation has highest precedence, then
prompt_token_count, then decode_step; mention what each field represents for
staleness comparison and that the comparison is strict (<), and reference
same_flow to clarify flow matching is required before comparing
generations/steps.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 49ff12c1-b515-4473-a3ab-4a97d4ece819

📥 Commits

Reviewing files that changed from the base of the PR and between ef40600 and e787d6f.

📒 Files selected for processing (3)
  • crates/skippy-protocol/src/binary/mod.rs
  • crates/skippy-protocol/src/binary/types.rs
  • crates/skippy-server/src/binary_transport.rs

@i386

i386 commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator Author

@michaelneale could you review this one when you get a chance?

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

seems fine small sug

Comment thread crates/skippy-server/src/binary_transport.rs Outdated
@i386
i386 merged commit 4175aa6 into main Jun 13, 2026
25 checks passed
@i386
i386 deleted the codex/skippy-request-cache-epochs branch June 13, 2026 02:45
michaelneale added a commit that referenced this pull request Jun 13, 2026
* origin/main:
  Add transport-aware Skippy stage ordering (#814)
  Share Skippy stage wire byte accounting (#818)
  Report Skippy artifact cold-start costs (#815)
  fix: debug output capturing for TUI / panics (#827)
  fix(hero): visual corrections for iPhone SE size devices (#838)
  Add Skippy stage role metadata (#816)
  Add Skippy request cache epoch telemetry (#817)
  Consolidate agent skills and fix stale docs (Windows deploy, repo map, design docs) (#836)
  feature(version): normalize version markers for different build types (#831)
  fix(website): fix visual regressions (#835)
  fix(gh): change micn to michaelneale in auto_assign.yml
  Revert "fix(gh): replace micn with IvGolovach in auto_assign.yml (not a collaborator)"
  fix(gh): replace micn with IvGolovach in auto_assign.yml (not a collaborator)
michaelneale added a commit that referenced this pull request Jun 14, 2026
* origin/main: (29 commits)
  MoA: don't let small-model consensus pre-empt a still-running large model (#837)
  fix(console): render thinking traces as markdown
  Add bounded direct path repair (#846)
  Fix skippy smoke PR gate (#850)
  Stabilize skippy smoke chain startup (#849)
  fix(ci): switch back to auto-assign workflow
  fix(website): polish longform visual explainer (#843)
  fix: gemma thinking
  Carry GLM llama MTP patches (#840)
  Refresh llama.cpp canary patch queue (#839)
  Add transport-aware Skippy stage ordering (#814)
  Share Skippy stage wire byte accounting (#818)
  Report Skippy artifact cold-start costs (#815)
  fix: debug output capturing for TUI / panics (#827)
  fix(hero): visual corrections for iPhone SE size devices (#838)
  Add Skippy stage role metadata (#816)
  Add Skippy request cache epoch telemetry (#817)
  Consolidate agent skills and fix stale docs (Windows deploy, repo map, design docs) (#836)
  feature(version): normalize version markers for different build types (#831)
  fix(website): fix visual regressions (#835)
  ...

# Conflicts:
#	AGENTS.md
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