Contributing
Dev setup, commands, conventions, and the change-control processes that keep the statistics trustworthy. Companion to architecture.md (as-built) and docs/specs/ (design contracts).
pip install -e ".[dev]" # numpy/scipy/statsmodels/pydantic/click/jinja2 + pytest/black/ruff/mypypip install -e ".[dev,all-db]" # + clickhouse-driver / psycopg2 / pymysql (DB work)pre-commit installPython ≥ 3.10. pip package ab-analysis-kit, import package abkit,
terminal command abk.
Commands
Section titled “Commands”| What | Command |
|---|---|
| All tests | python3 -m pytest tests/ |
| Stats unit tests | python3 -m pytest tests/stats/ |
| Golden (legacy-parity) tests | python3 -m pytest tests/golden/ |
Lint/format/types (ruff, black, mypy over abkit/) | pre-commit run --all-files |
| Version | single source: __version__ in abkit/__init__.py |
CI runs the full matrix on every push; keep it green.
Conventions
Section titled “Conventions”- numpy-first, no pandas in core logic. Vectorise; avoid Python loops over units.
- Type hints everywhere;
mypyruns overabkit/in pre-commit. - Docstrings cite the governing spec section (e.g.
docs/specs/declarative-config.md §7) when implementing a contract — the spec is the requirement, the docstring is the pointer. - Commit style: conventional commits scoped by package —
feat(stats): …,fix(stats): …,docs(specs): …,chore: …,ci: …. CHANGELOG.md(Keep a Changelog) is authoritative for behavior changes; update it in the same PR.- Repo docs and code comments are English; keep comments to constraints the code can’t show.
Adding a statistical method (the plugin checklist)
Section titled “Adding a statistical method (the plugin checklist)”- One
BaseMethodsubclass inabkit/stats/parametric/orbootstrap/; decorate with@register(canonicalname, optionalaliases). - Declare params as
ParamSpecs — typed, defaulted, identity-flagged (seedmust be identity-excluded for bootstrap methods). - Implement both entries where the math allows:
from_samplesandfrom_suffstats(dual-entry equivalence is tested). - Tests: known-answer test; dual-entry equivalence; params/identity hash
addition to
tests/stats/test_identity.py; golden test if reproducing a legacy method. - Never touch the pipeline/DB/CLI to make a method work — if you need to, the design is wrong (methods are plugins).
Changing a statistical number (change control — hard rule)
Section titled “Changing a statistical number (change control — hard rule)”Any deviation from the captured baseline (docs/specs/statistics-baseline.md):
- Bump the method’s
ALGORITHM_VERSION. - Record the deviation in
docs/specs/statistics-changes.md(what, why, expected numeric impact). - Entry in
CHANGELOG.md. - A/A validation through
abk validate(shipped in M4): run the matrix on the affected method + metric and confirm FPR ≈ α / power holds. The golden tests still pin the baseline in parallel.
Golden tests pin the baseline, not your improvement: a deliberate deviation gets a new test; the baseline reproduction stays intact behind its original entry (legacy-parity mode). Tolerance is relative 1e-9 — never loosen it to make a test pass.
Porting from detectkit (M2+)
Section titled “Porting from detectkit (M2+)”The donor is /home/aleksei/wsl_analytics/detektkit. Components marked ⟲ in
architecture.md §4 port near-verbatim:
rename dtk→abk, detectkit→abkit, _dtk_*→_ab_*; keep the donor’s
structure/tests where they hold. Anything metric-primary-shaped (detectkit’s
primary entity) must be consciously reshaped to experiment-primary — flag it in
the PR rather than silently diverging.
Release checklist (from M6 onward)
Section titled “Release checklist (from M6 onward)”__version__bumped;CHANGELOG.mdsection cut.docs/,.claude/rules/, and theinit-claudepackaged assets (abkit/cli/assets/claude/) tell the same story.- Website sync (
abkit.pipelab.dev) after docs changes. - PyPI publish is tag-triggered by CI.