Audit date: 2026-08-13
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.19.4 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.
The inclusion bar is starter-safe only: a feature is worth adding to the CLI when it helps generated projects express a current SolverForge capability without turning the neutral scaffold into a domain-specific demo.
- Published gate:
cargo info solverforge@0.19.4resolves the published crate on 2026-08-13, with Rust1.95and the scaffoldedserde,console, andverbose-loggingfeature set still available. - Upstream local checkout: the workspace and inter-crate dependency baseline is
0.19.4, withv0.19.4at the checked-out release commit. The0.19.0release made list variables the sole sequence and route model; the published0.19.1through0.19.4patch line carries the subsequent solver fixes. - Upstream
0.19.4assignment defaults: omitted-phase assignment-backed scalar groups commit the hard-first required batch with groupedFirstFit, defer bounded augmenting rematches to the following required cursor, and keep groupedCheapestInsertionfor optional assignments. Explicit CLI-generated scalar-group phases already selectfirst_fit, so this remains a runtime-owned improvement rather than a new scaffold policy. - Previous upstream releases:
solverforge/CHANGELOG.mdlists0.17.2dynamic construction primitives and required-assignment streaming,0.17.0CVRP list-domain profile support, and0.16.0split route/savings hooks. - Earlier upstream release:
solverforge/CHANGELOG.mdlists0.15.2directed projected self-join scoring work. - Earlier upstream release:
solverforge/CHANGELOG.mdlists0.15.1features for the bridge crate, dynamic runtime slots, list precedence hooks, fixed-owner list handling, and mandatory list construction. - Previous upstream release:
solverforge/CHANGELOG.mdlists0.15.0features for typed shared constraint sets, shared grouped-node state, assignment value-pattern neighborhoods, and required scalar assignment construction. - Upstream release:
solverforge/CHANGELOG.mdlists0.14.1and0.14.0features for shared route metric classes, owner-aware route hooks, complemented direct cross-join groups, and filtered join preservation. - Earlier upstream release:
solverforge/CHANGELOG.mdlists features for generalized grouped collectors and a scoring fix that preserves joined filter source indexes. - Upstream release:
solverforge/CHANGELOG.mdlists0.13.0features for typed model-aware search defaults, streaming-first stock search, grouped assignment ownership/search tuning, bounded grouped scalar and conflict repair streams, explicit score weight wrappers, and collector additions. - Upstream release:
solverforge/CHANGELOG.mdlists a0.13.0breaking scoring change: constraint streams removedpenalize_with,reward_with, and the hard/soft shortcut variants in favor ofpenalize(score),reward(score), and typed dynamic scoring closures. - Upstream release:
solverforge/CHANGELOG.mdlists0.12.1features for folding the former coverage behavior into scalar assignment groups and unifying assignment-backed grouped scalar construction. - Upstream release:
solverforge/CHANGELOG.mdlists0.12.0features for declarative scalar planning contracts, scalar/grouped construction and repair configuration, model-owned grouped scalar declarations, consecutive-run scoring collectors, and the cleaned public constraint stream surface. - Upstream domain docs:
docs/extend-domain.mddocuments scalar candidate, nearby, distance-meter, and construction-order hooks on#[planning_variable]. - Upstream solver docs:
docs/extend-solver.mddocuments capability-routed construction,group_namerouting intoScalarGroup, canonical selector defaults, grouped assignment construction, grouped scalar local search, and scalar candidate limits. - Upstream config docs:
crates/solverforge-config/WIREFRAME.mddocumentsgroup_name,construction_obligation, grouped-scalar construction limits, andgrouped_scalar_move_selector. - Upstream macro docs:
crates/solverforge-macros/WIREFRAME.mddocumentsscalar_groups = "path"on#[planning_solution]and scalar hook arguments on#[planning_variable]. - Upstream example:
examples/minimal-shift-schedulingdemonstratesscalar_groups,ScalarGroup::assignment, grouped scalar construction withgroup_name,construction_obligation = "assign_when_candidate_exists", andgrouped_scalar_move_selector. - CLI coverage today: the scaffold targets
solverforge 0.19.4and includes the retainedSolverManagerlifecycle, typed SSE, snapshots, analysis, pause/resume/cancel/delete, generatedsolverforge.app.toml, scalar/list variable generation, complete executable scalar/list metadata projection, countable scalar ranges, full compact telemetry, bounded candidate-detail retrieval, and qualified trace jobs. - Mixed execution gate: fresh runtime and browser scenarios seed a required scalar variable plus a list variable, start a retained solve, verify scalar assignment and complete list placement, and exercise cancel/terminal cleanup.
- UI release gate:
cargo info solverforge-uiconfirmssolverforge-ui 0.7.0is published; the web scaffold targets its framework-neutral asset release. - Local checkout note:
/srv/lab/dev/solverforge/solverforgeremains the source gate used to inspect the current release notes and feature surface.
| Upstream feature | Current CLI coverage | Starter-safe verdict | Proposed CLI/scaffold change | Required tests |
|---|---|---|---|---|
scalar_groups = "path" on #[planning_solution] |
Implemented as an opt-in solution attribute and app-spec/UI projection surface through solverforge generate scalar-group. |
Included, opt-in only. It is the current model-owned grouped scalar entry point, but it must not appear in the neutral default. | Keep the neutral scaffold unchanged. The command updates the planning solution attribute with scalar_groups = "scalar_groups" and owns a clear domain hook seam. |
Unit tests for solution-attribute parsing/rewrite and rendered group declarations; scaffold coverage should remain neutral by default. |
Assignment-backed ScalarGroup::assignment |
Implemented as solverforge generate scalar-group NAME --assignment Entity.field with explicit hook flags and limits. |
Included. This remains the replacement for the older coverage-group concept and is generic enough for opt-in scaffolding. | The command requires an existing nullable scalar variable target and generates only metadata/wiring plus hook stubs that panic until the user supplies domain logic. | Parser/generator tests; generated-app cargo check after user-owned hook bodies are present; negative tests that neutral scaffolds do not emit scalar groups. |
Candidate-backed ScalarGroup |
Implemented as solverforge generate scalar-group NAME --candidates provider --target Entity.field [...]. |
Included, opt-in only. It is too domain-specific for defaults but valuable as a CLI-owned wiring surface. | The command validates existing scalar targets, wires the candidate provider path, emits an explicit provider stub for local function names, and generates grouped construction plus search config unless --skip-solver-config is passed. |
Unit tests for target rendering and config refs; generated-app cargo check after provider implementation exists. |
Grouped scalar construction through group_name |
Implemented as generated solver.toml phases for assignment-backed and candidate-backed scalar groups unless --skip-solver-config is passed. |
Included only after a scalar group exists. Do not change default solver.toml. |
The command inserts a construction phase with group_name, limits, and construction_obligation = "assign_when_candidate_exists" for both assignment and candidate groups. |
Config graph tests; generated app solverforge check; generated app cargo check; runtime smoke only if the command claims solve behavior. |
grouped_scalar_move_selector |
Implemented as a generated local-search move selector for scalar groups unless --skip-solver-config is passed. |
Included only after a scalar group exists. Do not add to neutral local-search defaults. | The command inserts grouped local-search config with group_name, max_moves_per_step, optional value_candidate_limit, and require_hard_improvement. |
Config generation tests and generated app cargo check; runtime pipeline if used in an end-to-end generated scenario. |
construction_obligation = "assign_when_candidate_exists" |
Implemented as part of generated assignment-backed and candidate-backed scalar-group construction phases. It is not exposed as a standalone config flag. | Include only as part of scalar-group config, not as a neutral scaffold default. | Keep this tied to generate scalar-group; do not add it to neutral solver.toml or generic config set presets. |
TOML assertions and generated app compile checks. |
Scalar candidate_values hook |
Implemented in this worktree: generate variable --kind scalar accepts --candidate-values, renders it into #[planning_variable(...)], parses handwritten attributes, persists it in solverforge.app.toml, and projects it into static/generated/ui-model.json. |
Covered. This is a generic scalar modeling capability and remains starter-safe as metadata only. | No further scaffold change. Keep hook bodies domain-owned and keep tests proving generated apps compile when the user provides the hook. | Existing parser/generator/app-spec/scaffold tests. |
| Scalar nearby hooks and distance meters | Implemented in this worktree for --nearby-value-candidates, --nearby-entity-candidates, --nearby-value-distance-meter, and --nearby-entity-distance-meter. |
Covered. Nearby selectors remain opt-in because the model must bound candidate discovery explicitly. | No further scaffold change. Do not alter solver.toml defaults when these flags are present. |
Existing parser/projection/generation/scaffold tests; keep coverage that no nearby selector is emitted by default. |
| Scalar construction order hooks | Implemented in this worktree for --construction-entity-order-key and --construction-value-order-key. |
Covered. Required by scalar-only order-sensitive construction heuristics, but metadata alone should not switch solver policy. | No further scaffold change. A future config preset can validate that required hooks exist before selecting order-sensitive construction. | Existing parser/projection/generated-attribute tests. |
| Countable scalar value ranges | Implemented as mutually exclusive --countable-range FROM..TO, with non-negative half-open validation, macro emission, domain parsing, app-spec/UI projection, numeric web rendering, and a fresh generated-app compile check. |
Covered. This is a canonical scalar value source and does not require a synthetic fact collection. | Keep the stored macro/app-spec form as from..to; keep the UI projection structured as numeric from/to bounds. |
Parser/validation unit tests, projection assertions, and generated-app cargo check against 0.19.4. |
| Sequence and route modeling | Implemented only through --kind list --elements <collection> and current list metadata. |
Included. One list representation owns assignment and order and is the canonical sequence architecture. | Keep the public CLI, app spec, parser, generated data, UI projection, and runtime gates scalar/list-only. | List generator/parser/projection tests, mixed generated-app compile and runtime gates, and route-profile coverage. |
0.19.4 assignment-backed omitted-phase defaults |
Generated projects consume the runtime compiler through the umbrella solverforge crate; CLI-managed scalar-group phases already use explicit grouped first_fit. |
Covered by the runtime target upgrade. The hard-first required batch and deferred rematch policy are runtime-owned and do not require a new CLI flag or template branch. | Preserve the explicit CLI-managed phase contract and let omitted-phase projects inherit the 0.19.4 runtime defaults. |
Scalar-group config assertions, registry-only generated-app compilation, and upstream required-assignment runtime tests. |
| Current construction heuristic catalog | CLI ships conservative scalar/list template defaults and generic config set. |
Do not mirror every variant in scaffold defaults. | Document which upstream heuristics need opt-in model hooks; keep first_fit and list_cheapest_insertion templates stable until a command explicitly owns a configured preset. |
Docs/audit assertions only unless a preset command is added. |
| Immutable runtime compilation and resolved selector policy | Generated planning macros and solver.toml enter the canonical 0.19.4 runtime compiler; the templates do not assemble phases directly. |
Covered by the runtime dependency upgrade. This is runtime-owned architecture, not a new scaffold family or compatibility path. | Keep the generated model and config contracts unchanged and validate every shell plus scalar, list, and mixed runtime pipelines against 0.19.4. | Registry-only scaffold checks, seeded scalar/mixed generated solves, and browser lifecycle tests. |
| Qualified candidate execution traces | Implemented as an opt-in config setting, complete typed diagnostic DTO, GET /jobs/{id}/telemetry, and additive POST /jobs/qualified entry point carrying all required external digests and producer attestation. Candidate pulls remain absent from ordinary SSE/status/snapshot payloads. |
Included but disabled by default. This preserves the runtime's compact control plane while exposing the complete diagnostic and qualification surface. | Keep the commented [candidate_trace] example, positive-capacity validation, separate detail route, and qualified provenance request aligned with the runtime types. |
Unit config validation, scaffold source assertions, fresh generated-app compile checks, and a runtime pipeline that proves normal and qualified retained traces. |
| CVRP list profile and split route/savings hooks | Implemented through generate variable --kind list: --domain cvrp plus all generic distance, route/savings, metric-class, ownership, construction-order, precedence, and solution-trait metadata. Domain parsing, app spec, and web UI projection preserve the exact values. |
Included as opt-in metadata; the neutral scaffold remains domain-free. The CLI rejects profile-owned overrides alongside --domain cvrp. |
Keep hook bodies and CVRP trait implementation domain-owned. Do not inject fake route logic or a domain-specific default model. | Generator/parser tests, app-spec/UI projection coverage, CVRP conflict validation, upstream macro tests, and generated-app checks for the neutral/list templates. |
| Canonical local-search defaults | CLI templates still specify explicit late-acceptance plus accepted-count local search. | No immediate change. Explicit scaffold defaults are stable and compile; upstream omitted-selector defaults are runtime-owned. | Leave current solver.toml templates alone. Consider a later docs note that deleting move_selector lets runtime choose canonical defaults. |
Existing scaffold/runtime tests. |
Scoring collectors and grouped/complemented stream APIs, including consecutive_runs, indexed_presence, and collect_vec |
Implemented as opt-in advanced constraint skeleton flags while leaving scoring logic to the app. | Include as skeletons only. These APIs are important, but generated neutral constraints should not choose domain-specific collectors. | Keep the skeletons on the public stream surface with explicit panic placeholders. | Existing constraint-generation tests plus focused skeleton assertions. |
Conflict repair providers via conflict_repairs = "path" |
Implemented as solverforge generate conflict-repair CONSTRAINT_ID --provider provider_fn with optional selector config. |
Included, opt-in only. It requires constraint-specific provider code and is not neutral starter behavior. | The command wires conflict_repairs = "conflict_repairs", emits a provider stub for local function names, and stores the exact snake_case constraint ID in generated Rust, app metadata, and solver config. |
Unit tests for rendering and config mutation; generated-app cargo check after provider implementation exists. |
Retained SolverManager lifecycle |
Already represented in templates, routes, DTOs, JS hooks, runtime tests, and E2E tests. | Already covered. | No action. Keep scaffold assertions protecting snapshots, lifecycle metadata, and pause/resume/cancel/delete semantics. | Existing scaffold, runtime, and Playwright lifecycle tests. |
| Clean public stream surface | CLI-generated constraints already use ConstraintFactory::new().for_each(Plan::...) and do not teach generated helper-trait imports. |
Already covered. | No action beyond keeping examples/docs on public SolverForge API only. | Existing constraint-generation compile tests. |
The current starter-safe 0.19.4 surface is implemented. The next high-value slice is domain-specific documentation and executable examples, not more neutral scaffold defaults.
- Keep
solverforge newneutral and continue treating scalar groups and conflict repairs as explicit post-scaffold modeling choices. - Add human-facing examples for list profiles, scalar groups, conflict repair, and qualified diagnostics only with real hook bodies and real provenance.
- Prove any runtime behavior claims with generated apps whose hook bodies are real Rust, not TODO stubs.
- Release state:
solverforge 0.19.4is published on crates.io and matches both the live upstream release checkout and this generated target. Registry-only validation is therefore authoritative.SF_USE_LOCAL_PATCHES=1is only for an explicit future coordinated prerelease check. The audit uses the currentscalar_groups/ScalarGroup::assignmentvocabulary instead of the superseded coverage-group vocabulary from the earlier 0.12.0 candidate surface. - Aligned: the
0.19.4hard-first required-assignment batching and deferred rematch search remain runtime-owned. The CLI continues to emit its existing explicit groupedfirst_fitphase when it owns scalar-group solver config; it does not duplicate the runtime compiler's omitted-phase policy. - Implemented: scalar fact-collection and countable value sources plus
candidate_values, nearby candidate hooks, nearby distance meters, and construction order keys are accepted bysolverforge generate variable --kind scalar, rendered into the#[planning_variable(...)]attribute, parsed from handwritten domain files, persisted insolverforge.app.toml, and projected intostatic/generated/ui-model.json. - Aligned: ordered sequence and route modeling uses list variables end to end. The public CLI, canonical parser, app spec, generated data, UI projection, checks, and runtime scenarios contain only scalar and list variable contracts.
- Implemented: list
domain, distance meters, split route/savings hooks, savings metric class, fixed ownership, construction ordering, precedence hooks, and solution-trait metadata across CLI generation, canonical parsing, app-spec persistence, and web UI projection. The stock CVRP profile is accepted without allowing conflicting profile-owned overrides. - Implemented: every compact
SolverTelemetryfield and nested phase/selector/move/applied-move breakdown is projected into generated status, snapshot, and SSE payloads. Bounded candidate pulls use the separate atomic detail accessor and typed diagnostic DTO. - Implemented: candidate tracing is configurable through
candidate_trace.max_entrieswith positive-capacity validation. Generated web/API apps expose ordinary trace detail and explicitly qualified trace jobs with the five immutable external SHA-256 digests required by the current runtime contract. - Implemented: opt-in scalar groups through
solverforge generate scalar-groupfor assignment-backed and candidate-backed groups, including solution attribute wiring, app-spec/UI metadata, local hook stubs, solver config phase insertion inside a single CLI-managedsolver.tomlregion, and destroy cleanup. - Implemented:
solver.tomlvalidation now treats scalar groups and conflict repairs as exact-ID graph references.solverforge checkand destroy planning inspect construction phases, top-level selectors, neighborhoods, nested selector children, and partition child phases instead of scanning only flat top-level TOML. This is implemented insidesolverforge-cli; no unpublished upstreamsolverforge-configAPI is required. - Implemented: scalar-group model-contract validation is shared by
solverforge checkand destructive commands. Candidate-backed groups reject assignment-only hooks, assignment rules require sequence keys, stale scalar-group targets are reported, solver config group references are checked, anddestroy entity/destroy variablereject targets that are still owned by scalar groups. - Implemented: opt-in conflict repairs through
solverforge generate conflict-repair, including solution attribute wiring, app-spec/UI metadata, local provider stubs, solver config phase insertion, and destroy cleanup. - Implemented:
solverforge config setperforms lossless non-phase TOML edits such astermination.seconds_spent_limit; orderedphasesare edited manually or by future phase-specific commands, not by dotted-key mutation. - Implemented: advanced public collector skeletons for consecutive runs, indexed presence, collected vectors, grouped complement, and projected grouped constraints.
- Hardened: advanced grouped constraint skeletons use named source helpers and typed scoring closures instead of unsupported post-group filters, and fresh generated apps now compile before users replace the TODO predicates.
- Aligned: the list scaffold's built-in soft constraints use the current
typed dynamic
penalize(|item| Score::...)scoring API instead of the removedpenalize_withhelper. - Preserved: the CLI still does not generate real Rust hook bodies. Generated stubs fail fast with TODO panics until the user-owned hook functions are implemented.
- Preserved: neutral
solver.tomlpolicy is unchanged. Its commented candidate trace block documents the opt-in without enabling diagnostic overhead. Scalar/list metadata flags do not select unrelated heuristics automatically. - Not implemented by design: neutral scalar-group, conflict-repair, or grouped solver defaults. These remain opt-in modeling resources.
- Do not add
minimal-shift-schedulingor any domain-specific demo tosolverforge new. - Do not make grouped scalar construction or
grouped_scalar_move_selectorthe neutral default. - Do not generate hook functions that silently return fake business logic. Generated local stubs must panic until the user supplies real logic.
- Do not reintroduce scaffold-family aliases, legacy variable kinds, or compatibility rewrites for old generated project shapes.
- Do not add scalar predecessor topology; ordered sequences and routes belong to list variables.
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 checkagainst the published0.19.4registry target; - runtime pipeline coverage only if the new command claims actual solving behavior;
SF_USE_LOCAL_PATCHES=1only for an explicit future sibling-checkout compatibility check, followed by the same registry-only gate once that target is published.