Commit 0a55a88
Harden packaging: audit out-of-package runtime data + clean-install smoke test (#82)
* Harden packaging: audit out-of-package runtime data, add clean-install smoke test
Audit (no runtime change): traced every user-reachable CLI entry point
(permea, permea bench, permea bench diagnose, and the separate permea-drylab
script) for reads of data living outside the shipped package trees
(permea_core, permea_explain, permea_ui). Verdict: none. `permea bench
diagnose` reads only user-supplied dataset/clusters; its downstream
run()/diagnose()/warnings registry are pure Python. The many repo-root-relative
path constants (ROOT = parents[3], Path("docs/examples/generated"),
Path("benchmarks/*.yaml"), ...) all live in artifact-generation modules driven
by scripts/, not exposed through the CLI. A clean-venv sweep from outside the
repo confirmed no FileNotFoundError / ModuleNotFoundError / missing-resource on
any command. Because nothing broke, no files were moved and no package-data rule
was added -- moving unused data would ship files nothing needs.
Changes:
- pyproject.toml: add a `dev` optional-dependency group (build, twine, pytest)
so a canonical sdist+wheel can be produced and CI can run the suite. No upload.
- pyproject.toml: register `slow` and `packaging` pytest markers.
- tests/test_packaging_smoke.py: one clean-install smoke test (marked
slow+packaging) that builds a real wheel, installs it into a throwaway venv,
and drives `permea bench diagnose` from outside the repo on files produced by
permea_ui.fixtures.write_example, asserting exit 0 and a fired warning code.
The existing 562 tests run against an editable install and structurally cannot
catch a packaging regression; this closes that gap. It gates on a real
`python -m build` capability probe (not `import build`) so it skips cleanly
when the dev extra is absent and runs in CI where `.[dev]` is installed.
Hygiene:
- Remove stray src/permea_core/.DS_Store (untracked; .DS_Store already ignored).
- Delete finished untracked doc docs/pr/PR-permea-explain-and-packaging.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add CI so the packaging smoke test actually runs
The prior commit's tests/test_packaging_smoke.py claimed "CI installs the dev
extra", but the repo had no .github/workflows. The test skips whenever
`python -m build` is absent, so on the maintainer machine it skipped and ran
nowhere else -- it guarded nothing and that comment was not verifiable. This
adds the CI that makes the claim true.
Audit (Phase A): the suite is fully offline -- no test makes a live LLM provider
call and none requires a secret. The provider tests clear/monkeypatch
PERMEA_LLM_* and use fakes; test_explain_provider_configured is "strictly
offline" by construction; test_explain_boundary asserts openai/anthropic/httpx
are NOT imported. So CI needs no secrets.
Findings while wiring CI (pip install ".[dev]" alone could not even COLLECT the
suite):
- The test suite imports feature-extra deps unconditionally (fastapi in
test_ui_drylab, jsonschema in several test_explain_*), and PyYAML -- an
OPTIONAL runtime dep of permea_core guarded behind `try: import yaml` -- is
declared in no extra at all. With only `.[dev]` these produced 14 collection
errors, not skips.
- Fix: make `dev` a self-referential superset -- `permea-core[explain,ui]` plus
pyyaml plus build/twine/pytest -- so `pip install .[dev]` yields an
environment that can run the ENTIRE suite in one command. Base `dependencies`
are untouched: PyYAML stays optional for CLI users; the diagnose path never
needs it.
Changes:
- .github/workflows/ci.yml: CI on pull_request + push to main, ubuntu-latest,
matrix over Python 3.11/3.12/3.13 (per requires-python >=3.11). Steps:
checkout, setup-python, `pip install ".[dev]"`, then two pytest steps --
`-m "not packaging"` (fast) and `-m packaging` (the wheel build/install test,
kept separate so a packaging regression is distinguishable in the log). No
secrets; only actions/checkout and actions/setup-python.
- pyproject.toml: expand the `dev` extra as above.
- tests/test_packaging_smoke.py: the "CI installs the dev extra" statement is now
true (workflow added); docstring now states plainly that the test SKIPS when
`python -m build` is unavailable, so a green local run does not imply it ran,
and points at the CI workflow where it actually executes. Test not weakened.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 08bfdeb commit 0a55a88
3 files changed
Lines changed: 172 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
44 | 65 | | |
45 | 66 | | |
46 | 67 | | |
| |||
59 | 80 | | |
60 | 81 | | |
61 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
0 commit comments