Skip to content

fix(algorithms): fold and suggest near-miss parameter names - #877

Merged
Birfy merged 1 commit into
mainfrom
fix/876-param-did-you-mean
Nov 8, 2026
Merged

Birfy merged 1 commit into
mainfrom
fix/876-param-did-you-mean

Conversation

@Birfy

@Birfy Birfy commented Nov 8, 2026

Copy link
Copy Markdown
Collaborator

Closes #876

What changed

Unknown algorithm parameter names now behave like algorithm names: a key that matches exactly one declared parameter once case and -/_ are ignored resolves to it (--param batch-size=1 writes batch_size), and a remaining close typo appends ; did you mean 'batch_size'?. Unrelated names like nope still get the full list and no guess. CLI --param, specs, and MCP share resolve_params.

Verification at the tip

Tip SHA: ea77629
Ran:

  • pytest -q tests/test_algorithms.py tests/test_cli_algorithms_run.py tests/test_mcp_algorithm_spec.py tests/test_algorithm_entry_points.py tests/test_skill_library_example.py tests/test_skill_library_kind.py tests/test_changelog_fragments.py tests/test_demo.py → passed
    Not run:
  • full suite — CI

Parameter keys now resolve like algorithm names: case and -/_ aliases
(batch-size, NOISE_BAND) map to the declared name, and a close typo
ends with "did you mean 'batch_size'?". Closes #876.
@Birfy

Birfy commented Nov 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review at ea776292e0a4b2da5be06cf8a2ead31087eada4c

Verdict: PASS

  • Parameter aliases reuse the existing name folder (_fold / _resolve_alias); batch-size and NOISE_BAND resolve silently, and a collision of both spellings of the same parameter is refused.
  • Suggestion only fires for a single unknown key that is a close match (cutoff 0.75) to the folded name; nope gets none, so existing regex/substring assertions stay valid.
  • algorithm_override writes the canonical key into the spec, and the evoskill batch_size=1 starter default folds first so --param batch-size=2 is not treated as a duplicate.
  • Tests: alias fold, collision, near-miss, no-guess, CLI hyphen --param, and CLI typo hint; algorithm / run / MCP / skill_library / demo / changelog suites passed locally.

risk_gate: pending (this comment).

@Birfy
Birfy enabled auto-merge (squash) November 8, 2026 00:12
@Birfy

Birfy commented Nov 8, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS
Tip SHA: ea77629
Ran: pytest tests/test_algorithms.py tests/test_cli_algorithms_run.py tests/test_cli_algorithms_bare.py tests/test_mcp_algorithm_spec.py tests/test_algorithm_entry_points.py tests/test_cli_init_policy_slot.py tests/test_skill_library_kind.py tests/test_changelog_fragments.py at the tip → 215 passed; manual probes of resolve_params(evoskill, …) with Batch-Size (resolves to batch_size), bacthsize and batchsize (both end with "did you mean 'batch_size'?"); risk_gate.py from main → T2.
Not run: full suite (CI covers 3.9–3.13).

Correctness. _canonical_param_map reuses _resolve_alias, so parameter names fold exactly like algorithm names (#696): case and -/_ only, and an ambiguous fold stays unknown instead of silently picking one. Collisions after folding (batch_size + batch-size) are refused with a message naming both spellings, which is better than last-write-wins. The near-miss hint only fires for a single unknown key and uses the same 0.75 cutoff as #874, so nope still gets the plain list. All three entry points end up canonical: evolvespec goes through resolve_params, and the CLI's algorithm_override canonicalises before it builds the written spec, so --param batch-size=2 writes batch_size (the test checks the spec on disk).

Design fit. Good catch in starter_spec: without canonicalising first, setdefault("batch_size", 1) next to a user-supplied batch-size would have produced a collision error on init. A collision there is swallowed and then re-raised by algorithm_override, so the user still sees it.

Tests/docs. These cover the alias, the collision, three typo/meant pairs across evoskill, skillopt and rrsi, the no-guess case, and the CLI end to end, including "no spec written on error". The changelog fragment is present.

Non-blocking nits:

  • cli.py now calls the private algorithms._canonical_param_map from two places. If more callers turn up, consider a public name, for example canonical_params, added to __all__.
  • The import difflib inside the function is fine but differs from module-top imports elsewhere. Just a style point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

algorithms: unknown parameter names don't fold hyphens or suggest a near-miss (batch-size / bacth_size → batch_size)

1 participant