Skip to content

v0.19.0 — ship athf.metrics

Latest

Choose a tag to compare

@sydney-nebulock sydney-nebulock released this 19 Aug 22:27
· 7 commits to main since this release
d92c052

Packaging-only release. No changes to hunt logic, CLI commands, or LLM providers.

Read this before upgrading

athf.metrics was missing from every published wheel from 0.15.0 through 0.18.0.

pyproject.toml used an explicit [tool.setuptools] packages = [...] list that was never updated when the subpackage was added. Anyone who installed from PyPI got a distribution with no athf/metrics/ directory at all. pip install -e . and twine check both hid this: the editable install resolves against the source tree, and twine check validates metadata rather than archive contents.

What this did and did not affect — the two halves of the metrics system were packaged differently:

  • The athf metrics CLI kept working. athf/commands/metrics.py and athf/core/metrics.py shipped normally in every affected release; only the athf/metrics/ recording facade was dropped. So show, summary, and extract were never broken, which is part of why the gap went unnoticed.
  • Automatic recording was silently inert. The three instrumentation call sites import athf.metrics lazily inside a try and swallow the failure — athf/agents/base.py catches ImportError and logs at debug level, while athf/core/web_search.py and athf/commands/similar.py use a bare except Exception: pass. No warning ever surfaced.

Installing 0.19.0 starts emitting LLM-call, web-search, and similarity-search metrics for the first time on any environment that installed from PyPI. That is a behavior change, not only a packaging repair. If you relied on the previous (accidental) absence of automatic metric emission, review athf/metrics/ before upgrading.

Fixed

  • Ship athf.metrics. [tool.setuptools.packages.find] with include = ["athf*"] discovers subpackages instead of relying on a hand-maintained list, so a newly added subpackage can no longer be silently dropped from the artifact. (#54)

    Scope of the drift, measured against the real artifacts: the 0.18.0 wheel carried 9 subpackages and this one carries 10. The diff is exactly athf.metrics — nothing else was missing, and nothing was lost.

Changed — release engineering

  • The published artifact is now verified, not just the reviewed one. publish.yml previously built its own artifact and gated it on twine check alone, so it had neither of the guards added to tests.yml. Both workflows now call scripts/verify_packaging.py, which asserts every source subpackage is present in the wheel and the sdist, and that each one imports from the installed wheel — checked via __file__ provenance from a working directory outside the checkout, because otherwise sys.path[0] lets the source tree satisfy the import and the check passes hollow. (#54)

  • One implementation, not two copies. The guards live in a single script invoked by both workflows. A declaration in one place drifting out of step with reality in another is the exact failure mode that lost athf.metrics for four releases. (#54)

  • The version has a single source. pyproject.toml now declares dynamic = ["version"] reading athf.__version__, so the second literal that could disagree with it is gone. tests/test_packaging.py locks the declaration in place, and publish.yml additionally asserts the version baked into the built wheel's METADATA matches the tag — something twine check does not do. (#54)

  • The guard checks both directions. Subpackage comparison is now bidirectional, so an artifact that ships a package deleted from the source tree fails too — a stale build/ or *.egg-info is enough to produce one. The no-literal-version test also rejects single-quoted values, which are valid TOML and previously slipped through. (#55)

Upgrade

pip install --upgrade agentic-threat-hunting-framework==0.19.0

Full Changelog: v0.18.0...v0.19.0