solverforge-cli 3.3.2

CLI for scaffolding and managing SolverForge constraint solver projects
# SolverForge Upstream Feature Audit

Audit date: 2026-09-29

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

## Source Evidence

- Published gate: `cargo info solverforge@0.19.7` resolves the published crate
  on 2026-09-29, with Rust `1.95` and the scaffolded `serde`,
  `console`, and `verbose-logging` feature set still available.
- Upstream local checkout: the workspace and inter-crate dependency baseline is
  `0.19.7`, with `v0.19.7` 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` release surface: `git diff v0.19.6 v0.19.7` touches only the
  workspace `Cargo.toml` dependency baselines, `WIREFRAME.md` release lines, and
  release scripts. The published `0.19.7` crate therefore carries the `0.19.6`
  source, and no CLI contract question is decided by `0.19.7` itself.
- Upstream `0.19.6` feature — entity pinning: `#[planning_pin]` on a boolean
  planning-entity field preserves that entity's input genuine scalar and list
  variables during solver-generated construction and search. A pinned list owner
  keeps its input contents and order, a pinned scalar keeps its input value, a
  pinned required scalar that starts unassigned cannot be completed and fails the
  solve, and an optional pinned scalar may stay unassigned. The macro emits both
  the pin field name and a typed predicate that calls
  `PlanningEntity::is_pinned()`, and solver phases skip pin scanning entirely for
  models that declare no pins.
- Upstream `0.19.6` fixes: pinned list owners survive construction and search,
  scalar edits to pinned entities are rejected, and pinned assignments are
  retained in exhaustive search.
- Upstream `0.19.4` assignment defaults: omitted-phase assignment-backed scalar
  groups commit the hard-first required batch with grouped `FirstFit`, defer
  bounded augmenting rematches to the following required cursor, and keep
  grouped `CheapestInsertion` for optional assignments. Explicit CLI-generated
  scalar-group phases already select `first_fit`, so this remains a
  runtime-owned improvement rather than a new scaffold policy.
- Upstream `0.19.5` fixes: cancellation now retains the complete solution, the
  `late_acceptance` and `diversified_late_acceptance` score histories are
  slice-filled at initialization, and Clarke-Wright construction completes its
  full savings pass. All three are runtime-owned bug fixes; the CLI scaffold
  contract is unchanged.
- Previous upstream releases: `solverforge/CHANGELOG.md` lists `0.17.2`
  dynamic construction primitives and required-assignment streaming, `0.17.0`
  CVRP list-domain profile support, and `0.16.0` split route/savings hooks.
- Earlier upstream release: `solverforge/CHANGELOG.md` lists `0.15.2` directed
  projected self-join scoring work.
- Earlier upstream release: `solverforge/CHANGELOG.md` lists `0.15.1`
  features for the bridge crate, dynamic runtime slots, list precedence hooks,
  fixed-owner list handling, and mandatory list construction.
- Previous upstream release: `solverforge/CHANGELOG.md` lists `0.15.0`
  features for typed shared constraint sets, shared grouped-node state,
  assignment value-pattern neighborhoods, and required scalar assignment
  construction.
- Upstream release: `solverforge/CHANGELOG.md` lists `0.14.1` and `0.14.0`
  features for shared route metric classes, owner-aware route hooks,
  complemented direct cross-join groups, and filtered join preservation.
- Earlier upstream release: `solverforge/CHANGELOG.md` lists features for
  generalized grouped collectors and a scoring fix that preserves joined filter
  source indexes.
- Upstream release: `solverforge/CHANGELOG.md` lists `0.13.0` features 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.md` lists a `0.13.0` breaking
  scoring change: constraint streams removed `penalize_with`, `reward_with`,
  and the hard/soft shortcut variants in favor of `penalize(score)`,
  `reward(score)`, and typed dynamic scoring closures.
- Upstream release: `solverforge/CHANGELOG.md` lists `0.12.1` features for
  folding the former coverage behavior into scalar assignment groups and
  unifying assignment-backed grouped scalar construction.
- Upstream release: `solverforge/CHANGELOG.md` lists `0.12.0` features 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.md` documents scalar candidate,
  nearby, distance-meter, and construction-order hooks on
  `#[planning_variable]`.
- Upstream solver docs: `docs/extend-solver.md` documents capability-routed
  construction, `group_name` routing into `ScalarGroup`, canonical selector
  defaults, grouped assignment construction, grouped scalar local search, and
  scalar candidate limits.
- Upstream config docs: `crates/solverforge-config/WIREFRAME.md` documents
  `group_name`, `construction_obligation`, grouped-scalar construction limits,
  and `grouped_scalar_move_selector`.
- Upstream macro docs: `crates/solverforge-macros/WIREFRAME.md` documents
  `scalar_groups = "path"` on `#[planning_solution]` and scalar hook arguments
  on `#[planning_variable]`.
- Upstream example: `examples/minimal-shift-scheduling` demonstrates
  `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.19.7`, 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
  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 that
  every required scalar is assigned inside its range and that each list element
  index appears exactly once, and exercise cancel/terminal cleanup.
- UI and companion release gates: `cargo info solverforge-ui` confirms
  `solverforge-ui 0.9.0` is published; the web scaffold targets its
  framework-neutral asset release and additionally targets the published
  `solverforge-maps 2.1.4`. The MCP scaffold targets the published `rmcp 3.5.0`.
  The UI, maps, and MCP versions are independent of the `solverforge` runtime
  target.
- MCP SDK upgrade (`rmcp 3.4.0` to `3.5.0`, through `3.4.1`): the SDK-wide
  changes are additive transport/model fixes (JSON discover fallback, duplicate
  `sep-2243` header rejection, Origin allowlist default ports, explicit null
  `structuredContent` preservation) plus macro support for const paths and
  `concat!` in tool descriptions. One runtime-visible change matters here:
  `ProtocolVersion::LATEST` moves from `2025-11-25` to `2026-07-28` and a new
  `LATEST_WITH_INITIALIZE` keeps the initialize-capable version, so a client that
  lets the server choose now negotiates the task-capable `2026-07-28` version and
  receives a task handle from `solve` instead of the immediate job summary. Both
  outcomes stay covered because the CLI's acceptance client drives an explicit
  task-capable client (`2026-07-28`) and a legacy client (`2025-11-25`) in the
  MCP pipeline. The generated MCP surface itself is unchanged: no protocol
  constant, `ServerConfig`, or `ClientConfig` is pinned by the templates.
- Local checkout note: `/srv/lab/dev/solverforge/solverforge` remains the
  source gate used to inspect the current release notes and feature surface.

## Inclusion Matrix

| 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.7. |
| 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 CVRP metadata generation/projection assertions (no generated CVRP app is built or solved). |
| `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. |
| `0.19.5` runtime fixes (cancellation retention, score-history fill, complete Clarke-Wright construction) | Generated projects consume the runtime through the umbrella `solverforge` crate; the retained cancellation and local-search paths are exercised by the scalar and mixed runtime/browser scenarios. The CVRP list profile has generator, projection, and conflict-validation coverage only; no generated CVRP app is built or solved. | Covered by the runtime target upgrade. These are runtime-owned bug fixes and require no CLI flag, template branch, 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.7`. | Registry-only scaffold checks, seeded scalar/mixed generated solves, browser lifecycle tests, and CVRP generation/projection assertions (no generated CVRP runtime solve today). |
| 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.7 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.7`. | Registry-only scaffold checks, seeded scalar/mixed generated solves, and browser lifecycle tests. |
| `0.19.6` entity pinning (`#[planning_pin]`) | Not emitted by the CLI. The neutral scaffold declares no pin field and no `generate` surface writes `#[planning_pin]`; the attribute is user-authored domain metadata. The CLI's managed-block rewrites and model-contract check leave it in place: a generated app with a hand-added `#[planning_pin] bool` field passes `solverforge check` and `cargo check` against the published `0.19.7` registry. | Covered by the runtime target upgrade as opt-in domain metadata. Pinning is a per-entity modeling decision, not a scaffold family or a neutral default. | No scaffold change. Keep the neutral scaffold pin-free; if pinning is ever exposed it belongs in an explicit post-scaffold modeling command, in the same class as scalar groups and conflict repairs. | Generated-app `solverforge check` and registry-only `cargo check` with a hand-added pin field. Pinned solve semantics stay runtime-owned and are not exercised by this suite. |
| 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. |

## Recommended Follow-Up Implementation Slice

The current starter-safe 0.19.7 surface is implemented. The next high-value slice
is domain-specific documentation and executable examples, not more neutral
scaffold defaults.

1. Keep `solverforge new` neutral and continue treating scalar groups and
   conflict repairs as explicit post-scaffold modeling choices.
2. Add human-facing examples for list profiles, scalar groups, conflict repair,
   and qualified diagnostics only with real hook bodies and real provenance.
3. Prove any runtime behavior claims with generated apps whose hook bodies are
   real Rust, not TODO stubs.
4. Treat entity pinning the same way: the runtime owns the semantics, the neutral
   scaffold stays pin-free, and any future CLI surface must target an existing
   boolean entity field rather than inventing one.

## Implementation Status

- Release state: `solverforge 0.19.7` is published on crates.io and matches both
  the live upstream release checkout and this generated target. `0.19.6` is the
  source-carrying release in this range and `0.19.7` differs only in release
  version surfaces, so the published crate, the `v0.19.7` 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`
  vocabulary instead of the superseded coverage-group vocabulary from the earlier
  0.12.0 candidate surface.
- Aligned: the `0.19.4` hard-first required-assignment batching and deferred
  rematch search remain runtime-owned. The CLI continues to emit its existing
  explicit grouped `first_fit` phase when it owns scalar-group solver config;
  it does not duplicate the runtime compiler's omitted-phase policy.
- Aligned: the `0.19.5` cancellation, score-history, and Clarke-Wright
  construction fixes are runtime-owned. The retained lifecycle returns the
  terminal snapshot on cancel, local-search acceptors initialize through the
  runtime, and the CLI emits no parallel policy or post-solve repair. The
  cancellation path is exercised by the scalar and mixed scenarios; the CVRP
  list-profile construction path is not exercised by a generated app in this
  suite, so it rests on the runtime dependency and generator metadata tests.
- Aligned: the `0.19.6` pinning capability is runtime-owned. The CLI neither
  emits `#[planning_pin]` nor rewrites it away, no neutral template declares a pin
  field, and the model-contract check accepts a hand-added pin field on a
  generated app. Pinned construction, search, and the pinned-required failure
  semantics are exercised upstream, not by this suite.
- Implemented: scalar fact-collection and countable value sources plus
  `candidate_values`, nearby candidate hooks, nearby distance meters, and
  construction order keys are accepted by
  `solverforge generate variable --kind scalar`, rendered into the
  `#[planning_variable(...)]` attribute, parsed from handwritten domain files,
  persisted in `solverforge.app.toml`, and projected into
  `static/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 `SolverTelemetry` field 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_entries` with 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-group`
  for 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-managed `solver.toml` region, and destroy
  cleanup.
- Implemented: `solver.toml` validation now treats scalar groups and conflict
  repairs as exact-ID graph references. `solverforge check` and 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 inside `solverforge-cli`; no
  unpublished upstream `solverforge-config` API is required.
- Implemented: scalar-group model-contract validation is shared by
  `solverforge check` and 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,
  and `destroy entity` / `destroy variable` reject 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: the `mcp` shell delivers the solver as an MCP server over stdio
  and stateless Streamable HTTP with task-backed solving, and
  `solverforge connect --write <harness>` writes in-project client config for
  opencode, Claude Code, Cursor, and VS Code. The repository ships the portable
  `solverforge-modeling` and `solverforge-ui` agent skills through
  `scripts/install-skill`.
- Known limitation, accepted: the MCP HTTP transport has no authentication and
  no per-caller isolation. Every connection shares one solver and task store, so
  a non-loopback `--host` lets anyone who can reach the port start solves and
  read, cancel, or delete jobs; rmcp Host validation only rejects DNS-rebinding
  `Host` headers and is not access control. This is documented on every
  user-facing surface and left unmitigated by decision, not overlooked.
- Implemented: `solverforge config set` performs lossless non-phase TOML edits
  such as `termination.seconds_spent_limit`; ordered `phases` are 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 removed
  `penalize_with` helper.
- 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.toml` policy 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.

## Non-Goals

- Do not add `minimal-shift-scheduling` or any domain-specific demo to
  `solverforge new`.
- Do not make grouped scalar construction or `grouped_scalar_move_selector` the
  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.

## Validation Gate For Future Code Changes

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.19.7` 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
  compatibility check, followed by the same registry-only gate once that target
  is published.