Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d34dadd
feat(skippy): add run-ahead verify-window admission
danielwinterw Aug 22, 2026
df357f4
feat(skippy): discard stale run-ahead windows
danielwinterw Aug 22, 2026
0a39fce
fix(config): record verify_window_runahead_tokens in the defaults UI …
danielwinterw Aug 22, 2026
08c267c
chore: rustfmt, move StaleWindowDiscard above the test module, regen …
danielwinterw Aug 22, 2026
cf6409f
fix(skippy): gate discard frames and join inbound readers
danielwinterw Aug 23, 2026
600c8e1
fix(skippy): enforce run-ahead budgets and bound shutdown
danielwinterw Aug 25, 2026
07123c5
fix(skippy): serialize discard writes and bound read-ahead
danielwinterw Aug 26, 2026
da7c38f
fix(skippy): unblock readers parked at the byte ceiling
danielwinterw Aug 26, 2026
ec078f7
fix(skippy): isolate jitter streams and bound read-ahead
danielwinterw Aug 26, 2026
bad6c10
fix(skippy): update discard generation and cap bandwidth delays
danielwinterw Sep 2, 2026
48692e3
fix(skippy): interrupt readers stalled mid-frame
danielwinterw Sep 2, 2026
11cabab
chore: merge current main into run-ahead windows
Sep 12, 2026
d4038f3
docs(skippy): name the combined generation 10 contract
Sep 12, 2026
7282f83
chore: merge current main into run-ahead windows
Sep 13, 2026
7753a8c
fix(skippy): resolve run-ahead review follow-ups
Sep 13, 2026
3832a18
chore: merge current main into run-ahead windows
Sep 13, 2026
bba22db
fix(ci): authorize runtime-event gate model
Sep 13, 2026
a4d8b41
fix(ci): preserve native gate evidence path
Sep 13, 2026
0771b04
refactor(skippy): bound embedded generation module
Sep 13, 2026
c317a20
Merge remote-tracking branch 'origin/main' into HEAD
Sep 15, 2026
1e2f5b9
fix(ci): reconcile model registry after main sync
Sep 15, 2026
a2acf7f
chore(ci): refresh console print ratchet after main sync
Sep 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions crates/mesh-llm-config/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ pub struct SpeculativeConfig {
pub verify_window_min_tokens: Option<u32>,
pub verify_window_max_tokens: Option<u32>,
pub verify_window_pipeline_depth: Option<u32>,
pub verify_window_runahead_tokens: Option<u32>,
pub spec_default: Option<BoolOrAuto>,
pub(crate) legacy_draft_model_path_used: bool,
}
Expand Down Expand Up @@ -652,6 +653,7 @@ impl SpeculativeConfig {
verify_window_min_tokens: pick!(verify_window_min_tokens),
verify_window_max_tokens: pick!(verify_window_max_tokens),
verify_window_pipeline_depth: pick!(verify_window_pipeline_depth),
verify_window_runahead_tokens: pick!(verify_window_runahead_tokens),
spec_default: pick!(spec_default),
legacy_draft_model_path_used: overrides
.filter(|config| config.draft_model.is_some())
Expand Down Expand Up @@ -725,6 +727,8 @@ struct SpeculativeConfigRaw {
#[serde(default)]
verify_window_pipeline_depth: Option<u32>,
#[serde(default)]
verify_window_runahead_tokens: Option<u32>,
#[serde(default)]
spec_default: Option<BoolOrAuto>,
}

Expand Down Expand Up @@ -769,6 +773,7 @@ impl<'de> Deserialize<'de> for SpeculativeConfig {
verify_window_min_tokens: raw.verify_window_min_tokens,
verify_window_max_tokens: raw.verify_window_max_tokens,
verify_window_pipeline_depth: raw.verify_window_pipeline_depth,
verify_window_runahead_tokens: raw.verify_window_runahead_tokens,
spec_default: raw.spec_default,
legacy_draft_model_path_used: legacy_used,
})
Expand Down Expand Up @@ -831,6 +836,10 @@ impl Serialize for SpeculativeConfig {
"verify_window_pipeline_depth",
&self.verify_window_pipeline_depth,
)?;
map.serialize_entry(
"verify_window_runahead_tokens",
&self.verify_window_runahead_tokens,
)?;
map.serialize_entry("spec_default", &self.spec_default)?;
map.end()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ pub(super) fn apply_speculative_behavior(
| "native_mtp_suppress_cooldown_draft_limit"
| "verify_window_min_tokens"
| "verify_window_max_tokens"
| "verify_window_pipeline_depth" => {}
| "verify_window_pipeline_depth"
| "verify_window_runahead_tokens" => {}
_ => {}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,10 @@ fn speculative_settings(prefix: &str) -> Vec<ConfigSettingSchema> {
&format!("{prefix}.verify_window_pipeline_depth"),
ConfigValueSchema::Integer,
),
basic_setting(
&format!("{prefix}.verify_window_runahead_tokens"),
ConfigValueSchema::Integer,
),
basic_setting(&format!("{prefix}.spec_default"), bool_or_auto_schema()),
]
}
Expand Down
10 changes: 9 additions & 1 deletion crates/mesh-llm-config/src/model_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::model::{
SkippyConfig, SpeculativeConfig, StringOrStringList, merge_hardware, merge_model_fit,
merge_multimodal, merge_throughput,
};
use skippy_protocol::MAX_VERIFY_WINDOW_PIPELINE_DEPTH;
use skippy_protocol::{MAX_VERIFY_WINDOW_PIPELINE_DEPTH, MAX_VERIFY_WINDOW_RUNAHEAD_TOKENS};

use crate::validation_support::{
looks_like_model_identifier, validate_allowed, validate_bool_or_auto, validate_hf_pair,
Expand Down Expand Up @@ -687,6 +687,14 @@ fn validate_verify_window_controls(
&format!("{base_path}.verify_window_pipeline_depth"),
1,
u32::try_from(MAX_VERIFY_WINDOW_PIPELINE_DEPTH).expect("verify depth limit fits u32"),
)?;
validate_optional_u32_range(
config.verify_window_runahead_tokens,
&format!("{base_path}.verify_window_runahead_tokens"),
// Zero is the documented fixed-depth sentinel, so a model-level block
// can switch run-ahead back off when the global defaults enable it.
0,
u32::try_from(MAX_VERIFY_WINDOW_RUNAHEAD_TOKENS).expect("runahead limit fits u32"),
)
}

Expand Down
7 changes: 7 additions & 0 deletions crates/mesh-llm-config/src/wiring_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,13 @@ pub const WIRING_MANIFEST: &[WiringEntry] = &[
reason: "",
behavior: WiringBehavior::None,
},
WiringEntry {
path: "speculative.verify_window_runahead_tokens",
status: WiringStatus::Wired,
owner: "n/a",
reason: "",
behavior: WiringBehavior::None,
},
WiringEntry {
path: "speculative.spec_default",
status: WiringStatus::Wired,
Expand Down
45 changes: 29 additions & 16 deletions crates/mesh-llm-host-runtime/src/inference/skippy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,26 +102,36 @@ pub(crate) use stage::{
pub(crate) use topology::{StageTopologyParticipant, plan_package_identity_topology};

const BENCH_DOWNSTREAM_WIRE_DELAY_MS_ENV: &str = "MESH_LLM_BENCH_DOWNSTREAM_WIRE_DELAY_MS";
const BENCH_DOWNSTREAM_WIRE_JITTER_MS_ENV: &str = "MESH_LLM_BENCH_DOWNSTREAM_WIRE_JITTER_MS";
const BENCH_DOWNSTREAM_WIRE_STALL_MS_ENV: &str = "MESH_LLM_BENCH_DOWNSTREAM_WIRE_STALL_MS";
const BENCH_DOWNSTREAM_WIRE_STALL_P_ENV: &str = "MESH_LLM_BENCH_DOWNSTREAM_WIRE_STALL_P";

fn benchmark_downstream_wire_condition() -> Result<WireCondition> {
let delay_ms = match env::var(BENCH_DOWNSTREAM_WIRE_DELAY_MS_ENV) {
Ok(value) => parse_benchmark_downstream_wire_delay_ms(&value)?,
Err(env::VarError::NotPresent) => 0.0,
let delay_ms = parse_benchmark_wire_env(BENCH_DOWNSTREAM_WIRE_DELAY_MS_ENV)?;
let jitter_ms = parse_benchmark_wire_env(BENCH_DOWNSTREAM_WIRE_JITTER_MS_ENV)?;
let stall_ms = parse_benchmark_wire_env(BENCH_DOWNSTREAM_WIRE_STALL_MS_ENV)?;
let stall_p = parse_benchmark_wire_env(BENCH_DOWNSTREAM_WIRE_STALL_P_ENV)?;
WireCondition::with_jitter(delay_ms, None, jitter_ms, stall_ms, stall_p)
}

fn parse_benchmark_wire_env(name: &'static str) -> Result<f64> {
match env::var(name) {
Ok(value) => parse_benchmark_downstream_wire_value(name, &value),
Err(env::VarError::NotPresent) => Ok(0.0),
Err(env::VarError::NotUnicode(_)) => {
anyhow::bail!("{BENCH_DOWNSTREAM_WIRE_DELAY_MS_ENV} must be valid UTF-8")
anyhow::bail!("{name} must be valid UTF-8")
}
};
WireCondition::new(delay_ms, None)
}
}

fn parse_benchmark_downstream_wire_delay_ms(value: &str) -> Result<f64> {
let delay_ms = value.parse::<f64>().with_context(|| {
format!("{BENCH_DOWNSTREAM_WIRE_DELAY_MS_ENV} must be a finite non-negative number")
})?;
if !delay_ms.is_finite() || delay_ms < 0.0 {
anyhow::bail!("{BENCH_DOWNSTREAM_WIRE_DELAY_MS_ENV} must be a finite non-negative number");
fn parse_benchmark_downstream_wire_value(name: &str, value: &str) -> Result<f64> {
let parsed = value
.parse::<f64>()
.with_context(|| format!("{name} must be a finite non-negative number"))?;
if !parsed.is_finite() || parsed < 0.0 {
anyhow::bail!("{name} must be a finite non-negative number");
}
Ok(delay_ms)
Ok(parsed)
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -1482,17 +1492,20 @@ mod tests {

#[test]
fn benchmark_wire_delay_accepts_finite_non_negative_values() {
assert_eq!(parse_benchmark_downstream_wire_delay_ms("0").unwrap(), 0.0);
assert_eq!(
parse_benchmark_downstream_wire_delay_ms("25.5").unwrap(),
parse_benchmark_downstream_wire_value("test", "0").unwrap(),
0.0
);
assert_eq!(
parse_benchmark_downstream_wire_value("test", "25.5").unwrap(),
25.5
);
}

#[test]
fn benchmark_wire_delay_rejects_invalid_values() {
for value in ["-1", "NaN", "inf", "not-a-number"] {
assert!(parse_benchmark_downstream_wire_delay_ms(value).is_err());
assert!(parse_benchmark_downstream_wire_value("test", value).is_err());
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/mesh-llm-host-runtime/src/inference/skippy/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ pub struct SkippyPackageSourceFile {

/// Resolve a validated package-v2 directory into the existing host planning
/// identity. The content-derived package ID remains in the v2 manifest and is
/// carried into split control by the generation-9 admission descriptor.
/// carried into split control by the generation-10 admission descriptor.
pub fn identity_from_package_v2(package_dir: &Path) -> Result<SkippyPackageIdentity> {
let package_dir = package_dir.canonicalize().with_context(|| {
format!(
Expand Down Expand Up @@ -964,7 +964,7 @@ pub(crate) fn direct_gguf_source_paths(model_path: &Path) -> Result<Vec<PathBuf>
.collect()
}

/// Build the source-complete metadata envelope required by generation-9
/// Build the source-complete metadata envelope required by generation-10
/// planning directly from local GGUF shards. The envelope is in memory: the
/// source files remain at their original paths and no package or layer shard
/// is written.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,17 @@ fn resolve_decode_config(input: DecodeResolutionInput<'_>) -> Result<Speculative
.and_then(|config| config.verify_window_pipeline_depth),
)
.map_or(config.verify_window.pipeline_depth, |value| value as usize);
config.verify_window.runahead_max_tokens = pick_optional_u32(
input
.model_config
.and_then(|config| config.verify_window_runahead_tokens),
input
.global_config
.and_then(|config| config.verify_window_runahead_tokens),
)
.map_or(config.verify_window.runahead_max_tokens, |value| {
value as usize
});
if config.verify_window.min_tokens > config.verify_window.max_tokens {
bail!("skippy speculative verify window requires min_tokens <= max_tokens");
}
Expand Down Expand Up @@ -545,6 +556,7 @@ fn package_decode_config(
min_tokens: 1,
max_tokens: 4,
pipeline_depth: 1,
runahead_max_tokens: 0,
});
let effective_strategy = match (native_mtp.enabled, ngram.as_ref().map(|value| value.kind)) {
(true, Some(NgramProposerKind::Cache)) => "native-mtp+ngram-cache",
Expand Down Expand Up @@ -631,6 +643,7 @@ fn verify_window_config(policy: &PackageWindowPolicyInfo) -> VerifyWindowConfig
min_tokens: policy.min_window as usize,
max_tokens: policy.max_window as usize,
pipeline_depth: policy.pipeline_depth.unwrap_or(1) as usize,
runahead_max_tokens: 0,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2216,3 +2216,46 @@ placement = "auto"

assert!(error.contains("defaults.hardware.placement"));
}

#[test]
fn model_level_zero_runahead_overrides_a_positive_global_default() {
use crate::plugin::SpeculativeConfig;
let global: SpeculativeConfig = toml::from_str(
r#"
strategy = "ngram-suffix"
ngram_proposer = "suffix"
ngram_min = 5
ngram_max = 32
verify_window_pipeline_depth = 2
verify_window_runahead_tokens = 256
"#,
)
.expect("parse global speculative config");
let model: SpeculativeConfig = toml::from_str(
r#"
verify_window_runahead_tokens = 0
"#,
)
.expect("parse model speculative config");
let inherited = super::speculative::resolve_speculative_config(
None,
Some(&global),
"meshllm/test-model",
std::path::Path::new("/nonexistent/test-model.gguf"),
None,
)
.expect("global run-ahead must resolve");
assert_eq!(inherited.decode.verify_window.runahead_max_tokens, 256);
let overridden = super::speculative::resolve_speculative_config(
Some(&model),
Some(&global),
"meshllm/test-model",
std::path::Path::new("/nonexistent/test-model.gguf"),
None,
)
.expect("model-level zero must resolve to fixed-depth mode");
assert_eq!(
overridden.decode.verify_window.runahead_max_tokens, 0,
"Some(0) at the model level must win over the inherited positive default"
);
}
10 changes: 5 additions & 5 deletions crates/mesh-llm-host-runtime/src/mesh/stage_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ pub(super) fn stage_load_mode_from_proto(value: i32) -> anyhow::Result<skippy_pr
Ok(skippy_protocol::LoadMode::ArtifactSlice)
}
Ok(skippy_stage_proto::StageLoadMode::Unspecified) | Err(_) => {
anyhow::bail!("unsupported generation-9 stage load mode {value}")
anyhow::bail!("unsupported generation-10 stage load mode {value}")
}
}
}
Expand Down Expand Up @@ -672,7 +672,7 @@ fn stage_activation_codec_from_proto(
Ok(skippy_stage_proto::StageActivationCodec::S8RowF32RneV1) => {
Ok(skippy_protocol::StageActivationCodec::S8RowF32RneV1)
}
_ => anyhow::bail!("unsupported generation-9 activation codec {value}"),
_ => anyhow::bail!("unsupported generation-10 activation codec {value}"),
}
}

Expand All @@ -694,15 +694,15 @@ fn stage_activation_codec_policy_from_proto(
) -> anyhow::Result<skippy_protocol::StageActivationCodecPolicy> {
match skippy_stage_proto::StageActivationCodecPolicy::try_from(value) {
Ok(skippy_stage_proto::StageActivationCodecPolicy::Unspecified) => {
anyhow::bail!("generation-9 activation codec policy must be explicit")
anyhow::bail!("generation-10 activation codec policy must be explicit")
}
Ok(skippy_stage_proto::StageActivationCodecPolicy::FixedV1) => {
Ok(skippy_protocol::StageActivationCodecPolicy::Fixed)
}
Ok(skippy_stage_proto::StageActivationCodecPolicy::AutoLosslessV1) => {
Ok(skippy_protocol::StageActivationCodecPolicy::AutoLosslessV1)
}
_ => anyhow::bail!("unsupported generation-9 activation codec policy {value}"),
_ => anyhow::bail!("unsupported generation-10 activation codec policy {value}"),
}
}

Expand Down Expand Up @@ -1007,7 +1007,7 @@ fn source_resolution_policy_from_proto(value: i32) -> anyhow::Result<bool> {
Ok(skippy_stage_proto::SourceResolutionPolicy::Fallback) => Ok(false),
Ok(skippy_stage_proto::SourceResolutionPolicy::LocalRequired) => Ok(true),
Ok(skippy_stage_proto::SourceResolutionPolicy::Unspecified) | Err(_) => {
anyhow::bail!("unsupported generation-9 stage source resolution policy {value}")
anyhow::bail!("unsupported generation-10 stage source resolution policy {value}")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ async fn stage_control_bundle_gate_rejects_legacy_peer() -> Result<()> {
assert!(
error
.to_string()
.contains("does not advertise the required generation-9 control bundle"),
.contains("does not advertise the required generation-10 control bundle"),
"unexpected error: {error:#}"
);

Expand Down
4 changes: 2 additions & 2 deletions crates/mesh-llm-host-runtime/src/protocol/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn skippy_stage_subprotocols(
}
if stage_protocol_generation_supported {
features.push(
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V9.to_string(),
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V10.to_string(),
);
}
if artifact_transfer_supported {
Expand Down Expand Up @@ -61,7 +61,7 @@ fn supports_local_gguf_content_id(subprotocols: &[crate::proto::node::MeshSubpro

fn supports_skippy_stage_generation(subprotocols: &[crate::proto::node::MeshSubprotocol]) -> bool {
let required_features = [
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V9,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V10,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_CONTROL,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STATUS_LIST,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_LOCAL_GGUF_CONTENT_ID_V1,
Expand Down
10 changes: 5 additions & 5 deletions crates/mesh-llm-host-runtime/src/protocol/tests/announcements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn owner_fields_roundtrip_through_proto_announcement() {
.any(|feature| feature == skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STATUS_LIST)
);
assert!(skippy.features.iter().any(|feature| feature
== skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V9));
== skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V10));
assert_eq!(
proto_pa
.owner_attestation
Expand Down Expand Up @@ -441,13 +441,13 @@ fn proto_announcement_without_required_generation_bundle_is_not_stage_compatible
let peer_id = EndpointId::from(SecretKey::from_bytes(&[0xD0; 32]).public());
for missing in [
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_CONTROL,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V9,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V10,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STATUS_LIST,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_LOCAL_GGUF_CONTENT_ID_V1,
] {
let features = [
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_CONTROL,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V9,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V10,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STATUS_LIST,
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_LOCAL_GGUF_CONTENT_ID_V1,
]
Expand All @@ -469,7 +469,7 @@ fn proto_announcement_without_required_generation_bundle_is_not_stage_compatible
let (_, ann) = proto_ann_to_local(&proto_pa).expect("proto announcement should decode");
assert!(
!ann.stage_protocol_generation_supported,
"missing {missing} must reject the generation-7 bundle"
"missing {missing} must reject the generation-10 bundle"
);
}
}
Expand All @@ -486,7 +486,7 @@ fn partial_duplicate_stage_records_do_not_form_a_generation_bundle() {
major: skippy_protocol::STAGE_SUBPROTOCOL_MAJOR,
features: vec![
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_CONTROL.to_string(),
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V9
skippy_protocol::STAGE_SUBPROTOCOL_FEATURE_STAGE_PROTOCOL_GENERATION_V10
.to_string(),
],
},
Expand Down
2 changes: 1 addition & 1 deletion crates/mesh-llm-host-runtime/src/runtime/local_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub(super) async fn resolve_split_runtime_package(
}
anyhow::ensure!(
model_path.is_file(),
"generation-9 split source must be a package-v2 directory or direct GGUF file: {}",
"generation-10 split source must be a package-v2 directory or direct GGUF file: {}",
model_path.display()
);
if local_source_required {
Expand Down
Loading
Loading