Foundation hardening verification
Scope: package normalization and quality gates on top of
f9e88a6991add6513c66c6e36ba55985eece7306. Recorded 2026-09-20.
The dependency audit is failing with documented findings; this change is not a
claim of a clean security bill of health.
1. Baseline before changes
The unchanged baseline records 52 passing tests on every Python from 3.8 through 3.14, Ruff, wheel/sdist, outside-checkout installed-wheel CLI, strict MkDocs and a real Python 3.8 Docker smoke test. Branch-aware coverage on Python 3.11 was 55.90%, measured before production edits.
2. Final layout
src/apizr/ installed application package
main.py existing CLI and conversion entry point
extensions/ existing Context, engine and pipeline steps
modules/ existing analyzer, notebook, FastAPI and Docker modules
tests/ maintained executable suite
fixtures/legacy/ all 82 historical fixture files
scripts/ container, wheel and resolved-dependency audit checks
docs/architecture/ baseline, principles and verification records
LICENSE canonical full GPL version 3 text
CONTRIBUTING.md canonical contribution guide
CODE_OF_CONDUCT.md existing conduct policy moved to root
SECURITY.md supported line and verified private reporting route
3. Exact namespace migration
src/* application files moved to src/apizr/*; internal imports, module commands,
Uvicorn examples, test imports and configuration paths now use the new location.
The distribution name remains outerspace-apizr, version remains 0.2.0, the
license remains GPL-3.0-or-later, and Python remains >=3.8,<3.15.
The console script is apizr = "apizr.main:main" and Hatch packages
src/apizr. Existing main.py responsibilities are preserved. No src shim or
path manipulation was added. The baseline documentation did advertise src;
consumers must migrate imports and module invocations as documented in setup.
4. Tests before and after
52 → 55 passed on each of Python 3.8–3.14. Existing tests and golden files remain. Three new cases cover script/notebook deterministic offline generation and the trusted execution boundary (two parameterized cases), plus an unconfigured Context regression. The latter failed with AttributeError before the small fix; it now raises ContextException. Engine control flow, discovery, AST metadata, route generation, dependency inference and Docker algorithms were not redesigned. ArgNode declarations describe existing dynamically assigned fields.
5. Coverage before and after
Comparable Python 3.11 branch-aware coverage: 55.90% → 56.13%. Statement coverage: 57.07% → 57.22%; branch coverage: 50.60% → 51.18%. The final Python 3.14 result is 55.81%; Python 3.9 is 56.07%; Python 3.10–3.13 are 56.13%. Python 3.8 is 69.16% because its older pytest-cov also measures CLI subprocesses; that number is not directly comparable to parent-process results.
Final selected modules: AST analyzer 95.24%, engine 92.86%, Context 81.82%, FastAPI application generator 85.71%. Interactive prompts and old import/service generators remain major gaps. Generated API behavior is exercised with HTTP assertions, but temporary generated code is not included in package coverage.
The 55% floor is deliberately below all measured supported-runtime results. Missing lines are printed in CI. Explicit coverage configuration fixes a real Python 3.8 pytest-cov failure when CLI subprocesses changed directory and mixed statement-only and branch data; the full Python 3.8 rerun passed afterward.
6. Pyright
Standard mode over src/apizr and scripts, targeting Python 3.8: 0 errors,
0 warnings. No blanket ignores, diagnostic suppressions or fake casts.
Configuration encoding has a narrow Protocol; version parsing declares its
major/minor tuple; existing AST argument attributes are declared. Compatibility
backports are installed in the development group for analysis on newer Python.
Dynamic metadata and unannotated legacy interfaces remain typing debt.
7. Ruff and pre-commit
ruff check ., ruff format --check . and all pre-commit hooks pass.
B, C4, PIE and RUF100 augment E4/E7/E9/F/I. FastAPI File defaults have the
specific immutable-call exemption expected by that framework. Golden fixtures
are excluded; template bytes and vendored web assets are protected from
whitespace rewriting. The large-file check has explicit exceptions for the
existing two large images and generated universal lockfile. Black remains a
runtime notebook dependency, not a repository formatter.
8. Package build
Wheel and sdist build successfully from a fresh checkout. The wheel contains
apizr, its templates/configuration/translations and .dist-info/licenses/LICENSE;
it contains no src package. The canonical license text is sourced from
GNU; documentation retains the
project's copyright and GPL-3.0-or-later notice and links to the root license.
9. Installed wheel
Fresh Python 3.8 and 3.14 virtual environments outside the repository passed
import apizr, absence of an installed src namespace, apizr --help, and
pricing-notebook generation. The same checks were repeated from the clean
checkout on Python 3.14. The smoke script inspects actual wheel contents and
the generated output manifest rather than relying on editable imports.
10. Docker
Generated Python 3.8 and 3.14 containers built and ran successfully: health endpoint, POST total = 36, non-root UID. Python 3.8 also passed from the fresh checkout. Other target containers were not run locally during this PR; CI retains all seven targets without repeating lint/build gates in each test job.
11. Security audit
Failed, exit 1, reproduced from the clean checkout. 243 resolved entries were audited. Findings affect 29 package/version entries across 18 packages, with 79 distinct package/version/advisory combinations (the auditor emits 140 records including duplicate advisory IDs). See the complete security baseline for affected versions, advisory IDs, fix versions and verified Python requirements. No ignore list or continue-on-error is used. A separate policy/backport decision is needed to resolve the oldest Python dependency variants without violating this PR's support-range constraint.
12. CodeQL and CI
A Python CodeQL workflow was added with immutable action pins and read-only
repository permission. Existing GitHub default setup already scans Python and
Actions and publishes alerts. The explicit workflow runs analysis with
upload: never and retains SARIF as an artifact for 14 days, avoiding the
default-setup upload conflict.
It does not disable existing security scanning. If maintainers later switch to
advanced setup, enable SARIF upload and grant security-events write permission
in the same change. Analysis was not executed locally; GitHub Actions must
provide that result. CI separates quality, compatibility, build,
containers and security; strict documentation retains its separate workflow.
No historical issue was closed and no runtime sandbox or attestation integration
was introduced.
13. Files moved or removed
All application files moved under src/apizr. All 82 files from test/ moved
unchanged under tests/fixtures/legacy; there is one test hierarchy. Legacy
algorithms/templates were retained. Documentation copies of community/license
text became links to canonical root documents. Old src/__init__.py is removed
from that location; no old namespace package remains in the wheel.
14. Remaining debt
Legacy prompts and generator paths have weak coverage. Context/step results and AST metadata remain dynamically shaped. Standalone CLI subprocess coverage is not unified across pytest-cov versions. Runtime dependency inference depends on the installed environment. Older supported Python versions force vulnerable historical dependencies. CodeQL results and the full hosted container matrix must be assessed in CI. No issue wording was used as grounds for closure.
15. Compatibility risks
The documented src.* import/module paths intentionally change to apizr.*.
The apizr command and supported valid generation behavior remain. Malformed
version strings with other than two numeric components now fail during explicit
major/minor unpacking. Unconfigured Context I/O now reports ContextException
instead of leaking AttributeError. No new product features, AI dependencies,
plugin implementation, license change or Python range change were made.
16. Commands and change statistics
Baseline commands are in the baseline record. The final
verification used a fresh temporary checkout exported from the staged Git tree,
with a new .venv. The following commands ran there (all passed except the
dependency audit; pre-commit passed after the documented narrow large-file
exceptions):
uv sync --locked --python 3.14
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytest
uv run pytest --cov --cov-report=term-missing --cov-report=json:/tmp/apizr-foundation-final/coverage-3.14.json
uv build
uv run --locked --group docs mkdocs build --strict
uv run pre-commit run --all-files
uv run python scripts/smoke_wheel.py dist/outerspace_apizr-0.2.0-py3-none-any.whl
uv run python scripts/smoke_container.py --python-version 3.8
uv run --locked --group security python scripts/audit_dependencies.py --output /tmp/apizr-foundation-final/clean-audit.json
Additional working-checkout verification:
# Each isolated Python 3.8–3.13 environment was first refreshed with:
UV_CACHE_DIR=/tmp/apizr-uv-cache UV_PYTHON_INSTALL_DIR=/tmp/apizr-python UV_PROJECT_ENVIRONMENT=/tmp/apizr-py38 uv sync --locked --python 3.8
# The same command was repeated with py39/3.9 through py313/3.13.
COVERAGE_FILE=/tmp/apizr-foundation-final/coverage38-clean /tmp/apizr-py38/bin/python -m pytest --cov --cov-report=term-missing
# Corresponding py39, py310, py311, py312 and py313 interpreters also ran:
<python> -m pytest --cov --cov-report=term-missing
# Python 3.11 additionally emitted the directly comparable coverage JSON:
/tmp/apizr-py311/bin/python -m pytest --cov --cov-report=term-missing --cov-report=json:/tmp/apizr-foundation-final/coverage-3.11.json
UV_CACHE_DIR=/tmp/apizr-uv-cache uv run --locked python scripts/smoke_wheel.py dist/outerspace_apizr-0.2.0-py3-none-any.whl --python /tmp/apizr-py38/bin/python
UV_CACHE_DIR=/tmp/apizr-uv-cache uv run --locked python scripts/smoke_wheel.py dist/outerspace_apizr-0.2.0-py3-none-any.whl
UV_CACHE_DIR=/tmp/apizr-uv-cache uv run --locked python scripts/smoke_container.py --python-version 3.14
PRE_COMMIT_HOME=/tmp/apizr-pre-commit UV_CACHE_DIR=/tmp/apizr-uv-cache uv run --locked pre-commit run --all-files
git diff --check
git diff --cached --check
/tmp/apizr-foundation-final/clean-commands.json records the exact clean-run
argument arrays, working directory, exit codes and log paths. The delivered
diff-stat.txt is generated directly from git diff --stat against the baseline,
separately from this document so the statistic does not recursively include its
own embedded output.