Files
Amaury Levé 573938df09 Close the remaining dotnet-test eval follow-ups (#899) (#971)
* Close the remaining dotnet-test eval follow-ups from #899

Every non-agent dotnet-test eval now clears the 5-trial floor, the two cost
P1s are addressed, and the reference-skill coverage gap is recorded as a
decision instead of a standing warning.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 024b3241-d7af-418a-b9cd-3bb9ee9bf0ee

* Remove the duplicate block that cloned a grade-tests scenario, and gate it

The 'production code available' scenario carried a leftover tail from the
edit that moved the 'production code unavailable' one. YAML keeps the last
duplicate key, so every field of the new scenario was silently overwritten:
it shipped as a byte-identical rerun of its predecessor and never loaded the
dotnet-production-available fixture it was built around.

Parsing the spec and counting stimuli - which is what verified this PR -
returns the intended 5 names either way, so only the parser can see it. The
eval-quality gate now loads specs with a duplicate-key-strict loader
(failing check 9), with a self-test case and the incident recorded.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 024b3241-d7af-418a-b9cd-3bb9ee9bf0ee

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 024b3241-d7af-418a-b9cd-3bb9ee9bf0ee
2026-07-31 17:59:00 +02:00

33 lines
980 B
Python

"""Slug generation for URL paths."""
import re
from typing import Optional
_SEPARATORS = re.compile(r"[^a-z0-9]+")
def slugify(text: str, max_length: Optional[int] = None) -> str:
"""Return a lowercase, hyphen-separated slug for ``text``.
Runs of non-alphanumeric characters collapse to a single hyphen and
leading/trailing hyphens are trimmed. When ``max_length`` is given the slug
is truncated at a hyphen boundary when one is available, so a slug never
ends mid-word.
Raises:
ValueError: if ``max_length`` is not positive.
"""
if max_length is not None and max_length <= 0:
raise ValueError("max_length must be positive")
slug = _SEPARATORS.sub("-", text.strip().lower()).strip("-")
if max_length is None or len(slug) <= max_length:
return slug
truncated = slug[:max_length]
boundary = truncated.rfind("-")
if boundary > 0:
return truncated[:boundary]
return truncated.strip("-")