From 4557e7506ea93b2093f47e89075f2a587e456709 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 22:22:50 +0000 Subject: [PATCH] =?UTF-8?q?fix(hygiene):=20correct=20the=20extras=20remedy?= =?UTF-8?q?=20=E2=80=94=20pin=20the=20package,=20not=20the=20extra?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `extras` mode shipped in #190 told the reader to prefer installing the declaring library's whole [optional] extra over pinning the single package, "so a future addition to that extra is covered too". Acting on that advice in PyAutoHeart#136 introduced a regression: pip install "nufftax>=0.6.1,<0.7.0" -> nufftax-0.6.1 pip install "autoarray[optional]" -> Collecting nufftax<0.5.0,>=0.4.0 Uninstalling nufftax-0.6.1 -> nufftax-0.4.0 The smoke leg installs PUBLISHED wheels — source only shadows the PyAuto packages via PYTHONPATH — so a library extra resolves the RELEASED metadata, which lags the source pyproject this scan reads. The self-healing property the advice claimed does not exist there, and a stale pin inside the extra can silently downgrade a package the step pinned deliberately. Correct the remedy text in both the scan output and the skill body: pin the package. This scan is what covers future additions — that is the point of it. Detection logic is unchanged; both remedies already resolve to clean, and the "pinned directly" case has had a test since #190. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016FceDqU3q1PRWrqN42R2p1 --- agents/conductors/hygiene/_hygiene_extras.py | 11 +++++++---- skills/hygiene/hygiene.md | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/agents/conductors/hygiene/_hygiene_extras.py b/agents/conductors/hygiene/_hygiene_extras.py index 359d900..6162e53 100644 --- a/agents/conductors/hygiene/_hygiene_extras.py +++ b/agents/conductors/hygiene/_hygiene_extras.py @@ -315,10 +315,13 @@ def main() -> int: f"absent in mode=smoke" ) print( - f"\nAdd each to the smoke install step in {WORKFLOW}, mirroring the " - "`autofit[optional]` line already there — prefer installing the declaring\n" - "library's [optional] extra over pinning the single package, so a future\n" - "addition to that extra is covered too.\n\n" + f"\nAdd each to the smoke install step in {WORKFLOW}.\n\n" + "PIN THE PACKAGE, don't add the declaring library's [optional] extra: this\n" + "leg installs PUBLISHED wheels, so a library extra resolves the RELEASED\n" + "metadata, which lags the source pyproject this scan reads. A stale pin in\n" + "that extra can silently downgrade a package the step pinned deliberately\n" + "(autoarray 2026.7.29.2[optional] pinning nufftax<0.5.0 did exactly that).\n" + "This scan is what covers future additions — that is why it exists.\n\n" "Do NOT skip-guard or park the failing script: it passes mode=release, so " "the script is correct and the install set is the defect. Route to /bug." ) diff --git a/skills/hygiene/hygiene.md b/skills/hygiene/hygiene.md index f166304..1c1e761 100644 --- a/skills/hygiene/hygiene.md +++ b/skills/hygiene/hygiene.md @@ -41,8 +41,10 @@ Shared routing context: `PyAutoBrain/skills/COMMANDS.md`. sibling repo) before re-pointing it. Route `optdeps` findings to `/refactor` too (add the skip guard), but route `extras` findings to `/bug`: a script that fails only in `mode=smoke` and **passes `mode=release`** is correct, so - the defect is the CI install set — add the missing install (prefer the - declaring library's whole `[optional]` extra). Never "fix" such a script by + the defect is the CI install set — add the missing install, pinning the + package itself rather than the declaring library's whole `[optional]` extra + (that leg installs published wheels, whose extras lag the source pyproject + and can silently downgrade a deliberate pin). Never "fix" such a script by skip-guarding or parking it; both silently delete coverage that release validation still depends on. Source changes ship via `ship_library` / `ship_workspace`.