From a27ac8f6492d9f2f8bce436b518aec00cb7af4ed Mon Sep 17 00:00:00 2001 From: Vittorio Distefano Date: Mon, 9 Nov 2026 23:19:25 +0100 Subject: [PATCH 1/3] feat(scaffold): target SolverForge 0.25.1 SolverForge 0.25.1 keeps the nearest list destinations in one bounded buffer per nearby cursor, with no API or configuration change. Generated projects now pin the published 0.25.1 crates; the scaffold contract tests assert the new pin and generated apps build and solve against the registry release. --- src/scaffold_target.rs | 12 ++++++------ tests/scaffold_test.rs | 40 ++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/scaffold_target.rs b/src/scaffold_target.rs index 200b6a2..703a3db 100644 --- a/src/scaffold_target.rs +++ b/src/scaffold_target.rs @@ -1,13 +1,13 @@ -pub const RUNTIME_CRATE_VERSION: &str = "0.25.0"; +pub const RUNTIME_CRATE_VERSION: &str = "0.25.1"; pub const UI_CRATE_VERSION: &str = "0.9.1"; pub const MAPS_CRATE_VERSION: &str = "2.3.3"; pub const MCP_CRATE_VERSION: &str = "3.9.0"; -pub const RUNTIME_TARGET_LABEL: &str = "solverforge 0.25.0"; +pub const RUNTIME_TARGET_LABEL: &str = "solverforge 0.25.1"; pub const UI_TARGET_LABEL: &str = "solverforge-ui 0.9.1"; pub const MAPS_TARGET_LABEL: &str = "solverforge-maps 2.3.3"; -pub const RUNTIME_TARGET_DISPLAY: &str = "SolverForge crate target 0.25.0"; -pub const RUNTIME_SOURCE_PATH: &str = "crates.io: solverforge 0.25.0"; +pub const RUNTIME_TARGET_DISPLAY: &str = "SolverForge crate target 0.25.1"; +pub const RUNTIME_SOURCE_PATH: &str = "crates.io: solverforge 0.25.1"; pub const UI_SOURCE_PATH: &str = "crates.io: solverforge-ui 0.9.1"; pub const MAPS_SOURCE_PATH: &str = "crates.io: solverforge-maps 2.3.3"; pub const MCP_SOURCE_PATH: &str = "crates.io: rmcp 3.9.0"; @@ -18,12 +18,12 @@ pub const LONG_VERSION_TEXT: &str = concat!( env!("CARGO_PKG_VERSION"), "\nCLI version: ", env!("CARGO_PKG_VERSION"), - "\nScaffold runtime target: SolverForge crate target 0.25.0", + "\nScaffold runtime target: SolverForge crate target 0.25.1", "\nScaffold UI target: solverforge-ui 0.9.1", "\nScaffold maps target: solverforge-maps 2.3.3", "\nScaffold MCP target: rmcp 3.9.0", "\nRuntime source: ", - "crates.io: solverforge 0.25.0", + "crates.io: solverforge 0.25.1", "\nUI source: ", "crates.io: solverforge-ui 0.9.1", "\nMaps source: ", diff --git a/tests/scaffold_test.rs b/tests/scaffold_test.rs index 1147277..84a1483 100644 --- a/tests/scaffold_test.rs +++ b/tests/scaffold_test.rs @@ -19,13 +19,13 @@ use dependency_overrides::{ use network_retry::cargo_with_network_retry; use scaffold_generated_app::ScaffoldGeneratedApp; -const RUNTIME_DEP_LABEL: &str = "crates.io: solverforge 0.25.0"; +const RUNTIME_DEP_LABEL: &str = "crates.io: solverforge 0.25.1"; const UI_DEP_LABEL: &str = "crates.io: solverforge-ui 0.9.1"; const MAPS_DEP_LABEL: &str = "crates.io: solverforge-maps 2.3.3"; const SOLVERFORGE_DEP_SPEC: &str = - r#"{ version = "0.25.0", features = ["serde", "console", "verbose-logging"] }"#; + r#"{ version = "0.25.1", features = ["serde", "console", "verbose-logging"] }"#; const SOLVERFORGE_UI_DEP_SPEC: &str = r#"{ version = "0.9.1" }"#; -const SOLVERFORGE_MCP_DEP_SPEC: &str = r#"{ version = "0.25.0", features = ["serde"] }"#; +const SOLVERFORGE_MCP_DEP_SPEC: &str = r#"{ version = "0.25.1", features = ["serde"] }"#; const RMCP_DEP_SPEC: &str = r#"{ version = "3.9.0", features = ["server", "macros", "transport-io", "transport-streamable-http-server", "transport-streamable-http-server-session"] }"#; const SOLVERFORGE_MAPS_DEP_SPEC: &str = r#"{ version = "2.3.3" }"#; const GENERATED_RUST_VERSION_SPEC: &str = r#"rust-version = "1.95""#; @@ -300,7 +300,7 @@ fn test_version_output_distinguishes_cli_from_runtime_target() { assert!( stdout.contains(&format!("solverforge-cli {}", CLI_VERSION)) && stdout.contains(&format!("CLI version: {}", CLI_VERSION)) - && stdout.contains("Scaffold runtime target: SolverForge crate target 0.25.0") + && stdout.contains("Scaffold runtime target: SolverForge crate target 0.25.1") && stdout.contains("Scaffold UI target: solverforge-ui 0.9.1") && stdout.contains("Scaffold maps target: solverforge-maps 2.3.3") && stdout.contains(RUNTIME_DEP_LABEL) @@ -435,8 +435,8 @@ fn test_new_creates_neutral_project_files() { assert!( app_spec.contains("starter = \"neutral-shell\"") && app_spec.contains("shell = \"web\"") - && app_spec.contains("target = \"solverforge 0.25.0\"") - && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + && app_spec.contains("target = \"solverforge 0.25.1\"") + && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && app_spec.contains("[demo]") && app_spec.contains("default_size = \"standard\"") && app_spec.contains("available_sizes = [\"small\", \"standard\", \"large\"]") @@ -486,7 +486,7 @@ fn test_new_creates_neutral_project_files() { ); assert!( cargo_toml.contains( - "solverforge = { version = \"0.25.0\", features = [\"serde\", \"console\", \"verbose-logging\"] }" + "solverforge = { version = \"0.25.1\", features = [\"serde\", \"console\", \"verbose-logging\"] }" ) && cargo_toml.contains("solverforge-ui = { version = \"0.9.1\" }") && cargo_toml.contains("solverforge-maps = { version = \"2.3.3\" }") && cargo_toml.contains(GENERATED_RUST_VERSION_SPEC) @@ -706,7 +706,7 @@ fn test_new_readme_records_cli_and_runtime_versions_separately() { readme.contains(&format!( "CLI version used to scaffold this project: `{}`", CLI_VERSION - )) && readme.contains("SolverForge runtime target for this scaffold: `solverforge 0.25.0`") + )) && readme.contains("SolverForge runtime target for this scaffold: `solverforge 0.25.1`") && readme.contains("SolverForge UI target for this scaffold: `solverforge-ui 0.9.1`") && readme .contains("SolverForge maps target for this scaffold: `solverforge-maps 2.3.3`") @@ -777,8 +777,8 @@ fn test_new_api_shell_excludes_frontend_assets() { assert!( app_spec.contains("shell = \"api\"") - && app_spec.contains("target = \"solverforge 0.25.0\"") - && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + && app_spec.contains("target = \"solverforge 0.25.1\"") + && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && !app_spec.contains("ui_source"), "api shell should be recorded in solverforge.app.toml: {app_spec}" ); @@ -813,9 +813,9 @@ fn test_new_api_shell_excludes_frontend_assets() { std::fs::read_to_string(project_dir.join("solverforge.app.toml")).unwrap(); assert!( app_spec_after_generate.contains("shell = \"api\"") - && app_spec_after_generate.contains("target = \"solverforge 0.25.0\"") + && app_spec_after_generate.contains("target = \"solverforge 0.25.1\"") && app_spec_after_generate - .contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + .contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && !app_spec_after_generate.contains("ui_source"), "api shell should preserve runtime metadata without reintroducing ui_source after domain mutations: {app_spec_after_generate}" ); @@ -865,8 +865,8 @@ fn test_new_cli_shell_excludes_axum_frontend_and_compiles() { assert!( app_spec.contains("shell = \"cli\"") - && app_spec.contains("target = \"solverforge 0.25.0\"") - && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + && app_spec.contains("target = \"solverforge 0.25.1\"") + && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && !app_spec.contains("ui_source"), "cli shell should be recorded in solverforge.app.toml: {app_spec}" ); @@ -1006,9 +1006,9 @@ fn test_new_cli_shell_excludes_axum_frontend_and_compiles() { std::fs::read_to_string(project_dir.join("solverforge.app.toml")).unwrap(); assert!( app_spec_after_generate.contains("shell = \"cli\"") - && app_spec_after_generate.contains("target = \"solverforge 0.25.0\"") + && app_spec_after_generate.contains("target = \"solverforge 0.25.1\"") && app_spec_after_generate - .contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + .contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && !app_spec_after_generate.contains("ui_source"), "cli shell should preserve runtime metadata without reintroducing ui_source after domain mutations: {app_spec_after_generate}" ); @@ -1088,8 +1088,8 @@ fn test_new_mcp_shell_exposes_mcp_surface_and_compiles() { assert!( app_spec.contains("shell = \"mcp\"") - && app_spec.contains("target = \"solverforge 0.25.0\"") - && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + && app_spec.contains("target = \"solverforge 0.25.1\"") + && app_spec.contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && !app_spec.contains("ui_source"), "mcp shell should be recorded in solverforge.app.toml: {app_spec}" ); @@ -1276,9 +1276,9 @@ fn test_new_mcp_shell_exposes_mcp_surface_and_compiles() { std::fs::read_to_string(project_dir.join("solverforge.app.toml")).unwrap(); assert!( app_spec_after_generate.contains("shell = \"mcp\"") - && app_spec_after_generate.contains("target = \"solverforge 0.25.0\"") + && app_spec_after_generate.contains("target = \"solverforge 0.25.1\"") && app_spec_after_generate - .contains("runtime_source = \"crates.io: solverforge 0.25.0\"") + .contains("runtime_source = \"crates.io: solverforge 0.25.1\"") && !app_spec_after_generate.contains("ui_source"), "mcp shell should preserve runtime metadata without reintroducing ui_source after domain mutations: {app_spec_after_generate}" ); From cef900d9bf9209b2ffa04b36832b3ad9f0466de1 Mon Sep 17 00:00:00 2001 From: Vittorio Distefano Date: Mon, 9 Nov 2026 23:19:26 +0100 Subject: [PATCH 2/3] docs(scaffold): align the runtime contract with SolverForge 0.25.1 README, WIREFRAME, AGENTS and the modeling skill name the runtime version generated projects target, so they move with the 0.25.1 scaffold pin. --- AGENTS.md | 4 ++-- README.md | 8 ++++---- WIREFRAME.md | 10 +++++----- skills/solverforge-modeling/SKILL.md | 4 ++-- .../references/constraint-patterns.md | 2 +- skills/solverforge-modeling/references/gotchas.md | 2 +- skills/solverforge-modeling/references/verification.md | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7f1fd42..c35285f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,7 @@ Current scaffold policy: - current CLI package version is `3.9.0` - minimum supported Rust version is `1.95`, matching the current SolverForge runtime crates -- generated projects currently target `solverforge 0.25.0`; the default web shell additionally targets `solverforge-ui 0.9.1` and `solverforge-maps 2.3.3`; the MCP shell additionally targets `rmcp 3.9.0` +- generated projects currently target `solverforge 0.25.1`; the default web shell additionally targets `solverforge-ui 0.9.1` and `solverforge-maps 2.3.3`; the MCP shell additionally targets `rmcp 3.9.0` - `solverforge new ` is the only public scaffold path and produces a neutral app shell - `--shell web|api|cli|mcp` is the current public shell selector; `web` is the default, `api` omits frontend assets, `cli` omits Axum/SSE routes and frontend assets, and `mcp` delivers the solver as an MCP server over stdio and stateless Streamable HTTP - API/CLI/MCP app specs omit `ui_source`, and subsequent CLI mutations must preserve that absence @@ -80,7 +80,7 @@ Current end-to-end scenario policy: - the scalar-only runtime scenario covers full compact telemetry, bounded candidate detail, and qualified trace provenance - the MCP scenario models a mixed scalar-plus-list problem, generates the sample data, and drives both stdio and stateless Streamable HTTP through the real `rmcp` client: annotated tool surface, task-backed solve to a terminal snapshot with scalar assignment and complete list placement, retained lifecycle via a legacy client, and byte-level stdio stdout purity during a solve, all with parallel evaluation enabled on a pinned Rayon pool -SolverForge `0.25.0` uses list variables as the sequence and route model. The +SolverForge `0.25.1` uses list variables as the sequence and route model. The generated-app runtime and browser scenarios must continue to start and observe a real mixed scalar/list solve. diff --git a/README.md b/README.md index 37bf103..768e159 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Required Rust version: `1.95` or later. New projects currently target these crate versions: -- `solverforge 0.25.0` +- `solverforge 0.25.1` - `solverforge-ui 0.9.1` for the default web shell - `solverforge-maps 2.3.3` for the default web shell - `rmcp 3.9.0` for the MCP shell @@ -199,7 +199,7 @@ Core commands: - `generate score` and `generate solution --score` accept `HardSoftScore`, `HardSoftDecimalScore`, `HardMediumSoftScore`, and `SoftScore`. `BendableScore` is rejected because `#[planning_solution]` requires a - `ParseableScore`, which SolverForge `0.25.0` does not implement for it. + `ParseableScore`, which SolverForge `0.25.1` does not implement for it. - `solverforge generate scalar-group|conflict-repair` wires opt-in model resources by exact ID. - `solverforge destroy fact|entity|variable|constraint|solution|scalar-group|conflict-repair` @@ -327,7 +327,7 @@ including applied/not-doable/rejected moves, hard-score direction counts, construction counters, one record per started phase (`phases`, in execution order), per-selector and per-move breakdowns, and the bounded applied-move trace. The six `conflictRepair*` counters are run-level totals; selector -records do not carry them because SolverForge `0.25.0` `SelectorTelemetry` +records do not carry them because SolverForge `0.25.1` `SelectorTelemetry` has no such fields. These fields are carried consistently by status, snapshot, and typed SSE payloads. Constraint analysis reports each constraint's `name`, `weightMultiplier` (the bound constraint weight, a @@ -460,7 +460,7 @@ Current scenario coverage: byte-level stdio check that the transport channel stays pure JSON-RPC; every MCP phase runs with parallel evaluation enabled -SolverForge `0.25.0` supports mixed scalar/list construction, canonical mixed +SolverForge `0.25.1` supports mixed scalar/list construction, canonical mixed local-search defaults, and list-based sequence modeling. The CLI suite proves the mixed path in both runtime and browser pipelines; the scalar-only scenario keeps the deeper pause/resume, analysis, reconnect, and qualified-trace checks. diff --git a/WIREFRAME.md b/WIREFRAME.md index 32c7f3b..d3a2b7d 100644 --- a/WIREFRAME.md +++ b/WIREFRAME.md @@ -21,7 +21,7 @@ Required Rust version: `1.95` or later. Current generated projects target: -- `solverforge 0.25.0` +- `solverforge 0.25.1` - `solverforge-ui 0.9.1` for the web shell - `solverforge-maps 2.3.3` for the web shell - `rmcp 3.9.0` for the MCP shell @@ -279,7 +279,7 @@ Generated apps should behave like production references: snapshot revision - status, snapshot, and SSE payloads expose every compact SolverForge telemetry aggregate and phase/selector/move/applied-move breakdown; the six - `conflictRepair*` counters are run-level only, because SolverForge `0.25.0` + `conflictRepair*` counters are run-level only, because SolverForge `0.25.1` `SelectorTelemetry` does not carry them - constraint analysis carries `name`, `weightMultiplier` (the bound constraint weight), `score`, and `matchCount` per constraint @@ -333,7 +333,7 @@ warning, not an error, so the user can define it afterward. `generate score` and `generate solution --score` accept `HardSoftScore`, `HardSoftDecimalScore`, `HardMediumSoftScore`, and `SoftScore`. `BendableScore` is rejected: `#[planning_solution]` requires a -`ParseableScore`, and SolverForge `0.25.0` does not implement it for +`ParseableScore`, and SolverForge `0.25.1` does not implement it for `BendableScore`. Score rewrites change only the bare type name inside `use` items. @@ -348,7 +348,7 @@ functions that panic with the function name and the - `--reward`: `for_each` + `filter(reward_condition)` + `reward` - `--pair`: `for_each` + `filter` (variable assigned) + `join(joiner::equal(key))` self-join, which yields each unordered pair once, + `filter(pair_condition)` - + `penalize`; SolverForge `0.25.0` has no `for_each_unique_pair` + + `penalize`; SolverForge `0.25.1` has no `for_each_unique_pair` Weight helpers return the unit penalty or reward. A solve that reaches a placeholder fails: the job ends `FAILED` and the panic names the file and @@ -446,7 +446,7 @@ Current scenario policy: legacy client, and byte-level stdio stdout purity during a solve, all with parallel evaluation enabled -SolverForge `0.25.0` uses list variables for ordered sequences and routes. Both +SolverForge `0.25.1` uses list variables for ordered sequences and routes. Both generated-app end-to-end suites start and observe the real mixed scalar/list path. diff --git a/skills/solverforge-modeling/SKILL.md b/skills/solverforge-modeling/SKILL.md index 9001c1b..dad8111 100644 --- a/skills/solverforge-modeling/SKILL.md +++ b/skills/solverforge-modeling/SKILL.md @@ -25,7 +25,7 @@ required source/collector rules for the grouped patterns. `solverforge --version`, `solverforge new --help`, `solverforge generate variable --help`. -This skill describes CLI `3.9.0` (scaffold runtime target `solverforge 0.25.0`, +This skill describes CLI `3.9.0` (scaffold runtime target `solverforge 0.25.1`, UI `solverforge-ui 0.9.1`, maps `solverforge-maps 2.3.3`, MCP `rmcp 3.9.0`). Re-derive specifics from the CLI if the version differs. @@ -221,7 +221,7 @@ from a hand-written extractor. The common skeletons are `--unary` = `for_each` + `filter` + `penalize` (hard or soft), `--reward` = `for_each` + `filter` + `reward`, and `--pair` = `for_each` + `filter` (variable assigned) + `joiner::equal` self-join + -`filter` + `penalize`. SolverForge `0.25.0` has no `for_each_unique_pair`; +`filter` + `penalize`. SolverForge `0.25.1` has no `for_each_unique_pair`; the self-join already yields each unordered pair once. `#[planning_solution]` generates a public associated accessor for each diff --git a/skills/solverforge-modeling/references/constraint-patterns.md b/skills/solverforge-modeling/references/constraint-patterns.md index 479780c..c024bea 100644 --- a/skills/solverforge-modeling/references/constraint-patterns.md +++ b/skills/solverforge-modeling/references/constraint-patterns.md @@ -182,7 +182,7 @@ fn pair_weight(_left: &Task, _right: &Task) -> HardSoftScore { } ``` -SolverForge `0.25.0` has no `for_each_unique_pair`; this self-join is the pair +SolverForge `0.25.1` has no `for_each_unique_pair`; this self-join is the pair pattern. A self-join visits each unordered pair **exactly once** and never pairs an entity with itself, so one match is one violation. Do not add a self-pair guard and do not halve the weight. Keep the assigned filter before the join: an diff --git a/skills/solverforge-modeling/references/gotchas.md b/skills/solverforge-modeling/references/gotchas.md index 470301d..8aa2070 100644 --- a/skills/solverforge-modeling/references/gotchas.md +++ b/skills/solverforge-modeling/references/gotchas.md @@ -153,7 +153,7 @@ construction phase covers the group. - `SoftScore` has no hard level: only `--soft` constraints are allowed. - `generate score ` must name a supported type, or the CLI rejects it. - `BendableScore` is rejected: SolverForge `0.25.0` has no + `BendableScore` is rejected: SolverForge `0.25.1` has no `ParseableScore` for it, which `#[planning_solution]` requires. ## `solverforge.app.toml` is a projection, not an input diff --git a/skills/solverforge-modeling/references/verification.md b/skills/solverforge-modeling/references/verification.md index cfff315..d005c49 100644 --- a/skills/solverforge-modeling/references/verification.md +++ b/skills/solverforge-modeling/references/verification.md @@ -23,7 +23,7 @@ cargo check Catches wrong field names, missing imports, wrong score types, and closure signature mismatches. It will **not** catch the runtime localizing-source panic (that is a runtime assertion, not a compile error). The generated scaffolds -target `solverforge 0.25.0`; the first build downloads and compiles the runtime +target `solverforge 0.25.1`; the first build downloads and compiles the runtime and web dependencies, which can take a few minutes. `SF_USE_LOCAL_PATCHES=1` exists in the CLI's own test harness for prerelease targets — do not set it for ordinary app builds. From 7917a408cf2d9f2ee2f42dc50c54c32dc861c0ec Mon Sep 17 00:00:00 2001 From: Vittorio Distefano Date: Mon, 9 Nov 2026 23:19:27 +0100 Subject: [PATCH 3/3] docs(audit): refresh the audit to SolverForge 0.25.1 The audit records the published release generated projects target and the upstream surface since the previous target. 0.25.1 adds no API or configuration surface; references to the releases that introduced earlier features stay as they were. --- UPSTREAM_FEATURE_AUDIT.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/UPSTREAM_FEATURE_AUDIT.md b/UPSTREAM_FEATURE_AUDIT.md index 0f41487..f203123 100644 --- a/UPSTREAM_FEATURE_AUDIT.md +++ b/UPSTREAM_FEATURE_AUDIT.md @@ -5,7 +5,7 @@ Audit date: 2026-11-09 This audit compares the current `solverforge-cli` scaffold surface against the live SolverForge upstream checkout at `/srv/lab/dev/solverforge/solverforge` and the crates.io release state. Generated projects now target the published -SolverForge `0.25.0` release. Registry-only generated-app validation is the +SolverForge `0.25.1` release. Registry-only generated-app validation is the release gate; `SF_USE_LOCAL_PATCHES=1` remains reserved for explicit future prerelease checks against sibling checkouts. @@ -15,13 +15,13 @@ without turning the neutral scaffold into a domain-specific demo. ## Source Evidence -- Published gate: `cargo info solverforge@0.25.0` resolves the published crate +- Published gate: `cargo info solverforge@0.25.1` resolves the published crate on 2026-11-09, with Rust `1.95` and the `serde`, `console`, and `verbose-logging` features; `verbose-logging` is `[console, solverforge-console/verbose-logging]`, so the web, API, and CLI shells keep all three and the MCP shell enables only `serde`. - Upstream local checkout: the workspace and inter-crate dependency baseline is - `0.25.0`, with `v0.25.0` (`3115b4dd`) at the checked-out release commit. The `0.19.0` + `0.25.1`, with `v0.25.1` (`6069763d`) at the checked-out release commit. The `0.19.0` release made list variables the sole sequence and route model; the published `0.19.1` through `0.19.7` patch line carries the subsequent solver fixes. - Upstream `0.19.7..0.22.0` release surface: `0.19.8` through `0.19.14` are @@ -179,6 +179,11 @@ without turning the neutral scaffold into a domain-specific demo. - Upstream macro docs: `crates/solverforge-macros/WIREFRAME.md` documents `scalar_groups = "path"` on `#[planning_solution]` and scalar hook arguments on `#[planning_variable]`. +- Upstream `0.25.0..0.25.1` release surface: the nearby list change and swap + cursors keep the nearest destinations in one bounded buffer per cursor, and + the zero-regression gate runs both sides from equal-length paths and grades + cache and branch behaviour on Cachegrind's simulation. No public API or + configuration changes; generated apps pick it up through the version pin. - Upstream `0.24.0..0.25.0` release surface (source-carrying, breaking): configuration semantics made literal and validated, partitioned search run by the framework, the `auto` parallel-evaluation policy, and construction and @@ -212,7 +217,7 @@ without turning the neutral scaffold into a domain-specific demo. `scalar_groups`, `ScalarGroup::assignment`, grouped scalar construction with `group_name`, `construction_obligation = "assign_when_candidate_exists"`, and `grouped_scalar_move_selector`. -- CLI coverage today: the scaffold targets `solverforge 0.25.0`, exposes the +- CLI coverage today: the scaffold targets `solverforge 0.25.1`, exposes the `web`, `api`, `cli`, and `mcp` shells, and includes the retained `SolverManager` lifecycle, typed SSE, snapshots, analysis, pause/resume/cancel/delete, generated `solverforge.app.toml`, scalar/list @@ -336,7 +341,7 @@ without turning the neutral scaffold into a domain-specific demo. ## Recommended Follow-Up Implementation Slice -The current starter-safe 0.25.0 surface is implemented, apart from the +The current starter-safe 0.25.1 surface is implemented, apart from the unknown-key `solver.toml` validation gap recorded in the matrix. The next high-value slice is domain-specific documentation and executable examples, not more neutral scaffold defaults. @@ -353,16 +358,16 @@ scaffold defaults. ## Implementation Status -- Release state: `solverforge 0.25.0` is published on crates.io and matches +- Release state: `solverforge 0.25.1` is published on crates.io and matches the live upstream release checkout and this generated target. The - `0.19.8..0.25.0` line is source-carrying (grouped-scalar search/perf work, + `0.19.8..0.25.1` line is source-carrying (grouped-scalar search/perf work, the `0.20.3` search-order hooks, the `0.21.0` scoring `group_by` joins, the `0.21.2` selector-subgraph edge rebase fix, the `0.21.3` precedence route delta fix, the `0.22.0` grouped-stream accumulator-kernel rework, the `0.23.0` parallel local-search evaluation, the `0.24.0` constraint weights and API cleanup, the `0.25.0` configuration audit, framework partitioned - search and `auto` evaluation policy), and the published crate, the `v0.25.0` - tag, and this + search and `auto` evaluation policy, and the `0.25.1` bounded nearby list + candidate buffer), and the published crate, the `v0.25.1` tag, and this generated target are the same code. Registry-only validation is therefore authoritative. `SF_USE_LOCAL_PATCHES=1` is only for an explicit future coordinated prerelease check. The audit uses the current `scalar_groups` / `ScalarGroup::assignment` @@ -462,7 +467,7 @@ scaffold defaults. help says: unary is `for_each` + `filter` + `penalize` for both hardness levels, reward is `for_each` + `filter` + `reward`, and pair filters out unassigned entities before a `joiner::equal` self-join (each unordered pair - once; `0.25.0` has no `for_each_unique_pair`) and selects conflicts with a + once; `0.25.1` has no `for_each_unique_pair`) and selects conflicts with a filter. - Changed: the neutral `solver.toml` declares no `[[phases]]` and defers to the runtime's model-aware default pipeline; its explicit phases remain as a @@ -492,7 +497,7 @@ Any implementation from this audit should pass: - focused parser/generator/app-spec tests for the new metadata; - scaffold contract tests proving fresh generated projects include only the opt-in scalar-group surface requested by the user; -- generated app `cargo check` against the published `0.25.0` registry target; +- generated app `cargo check` against the published `0.25.1` registry target; - runtime pipeline coverage only if the new command claims actual solving behavior; - `SF_USE_LOCAL_PATCHES=1` only for an explicit future sibling-checkout