Thanks for your interest. processbehavior is an implementation of Thomas A. Bishop's Variation Analysis System (VAS); methodology fidelity is more important than feature volume. Smaller, well-validated changes are preferred.
processbehavior is the computational engine for VAS. It provides the building blocks and leaves the analysis to the analyst:
- design-state detection and the PDS / ODS / ADS lineage
- the residual system (R1–R6) and variance decomposition
- chart computation and control limits
- signal detection, capability, loss function, maximum information
What it deliberately does not provide is the layer above those: an ordered, gated analytical workflow — which analyses to run for a given study, in what sequence, under what conditions, and how to read the result of one before deciding the next. That sequencing is Dr. Bishop's methodology. It is taught, and it is the subject of his published work; it is not part of this library and will not be added to it.
Concretely, pull requests along these lines will be declined regardless of implementation quality:
- a "run the standard analysis" entry point that executes a fixed sequence of analyses and returns a narrative report
- ordering, naming, or gating rules that encode which analysis follows which
- helpers whose purpose is to relieve the caller of deciding what to run next
This is a scope boundary, not a missing feature or an oversight. The library's job is to make each analysis correct and each result inspectable; deciding which analysis answers the question in front of you is the analyst's job, and learning to make that decision well is what the methodology teaches. Building blocks stay here. Judgement stays with the practitioner.
If you are unsure which side of that line a contribution falls on, open an issue before writing code and we will work it out there.
git clone https://github.com/cnicholas/processbehavior.git
cd processbehavior
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pre-commit installThe [dev] extra pulls in [test], [lint], [images], and [excel].
If you only need a subset, install them directly:
pip install -e ".[test]" # pytest + pyarrow + openpyxl
pip install -e ".[lint]" # ruff + mypy + pre-commit
pip install -e ".[docs]" # jupyter-book + ipykernelpytest tests/ # full suite
pytest tests/ -m "not slow" # skip the perf benchmarks
ruff check .
mypy processbehaviorThe full test suite is the gate: if it fails, the change is not ready.
The file validation/PBTESTDATABASE_T100.csv is ground-truth Minitab output
for DS 1–6 from Bishop's reference materials. Numerical changes that touch
residuals (R1–R5), DS detection, limit calculations, or variance
decomposition must keep the relevant Bishop-reference tests green:
pytest tests/test_bishop_reference.py -v # skips unless Bishop's residual workbooks are presentThere is also a full end-to-end check that compares every chart center, control limit, capability index and loss component against Bishop's VAS runs for the 10-12-2026 manual (PM SDS 1–6, PM INERT, his known-effects data and the Medicare data):
python validation/e2e_bishop_report.pyIt runs on every push in CI, writes the summary page at
docs/reference/validation.md, and CI fails if that page no longer matches what
the run produces. So a change that moves any validated number cannot land
quietly: it either fails the assertions or visibly rewrites the published
summary.
If a Bishop check fails after your change, the change is wrong — not the reference.
Code and docs cite Bishop's VAS documentation manual by edition and equation number:
(10-12 manual Eq 14-8), Eqs 14-4..14-13, Eqs 11-16/17. Name the edition once per file and use
the chapter-number form; tests/test_manual_citations.py checks both. The citations are read
against the manual itself, so a new edition reports every place in the library whose equation
changed or moved.
Cite an equation only where the code computes exactly that equation. Where it computes something close (a different weighting, an approximation, a different sequence), say how it differs instead of citing it.
The docs have one live version, deliberately, until 1.0:
- The site tracks
main— it always describes the latest release plus any unreleased changes. There are no per-version documentation archives before 1.0;CHANGELOG.mdis the only version-history surface. - No version strings in docs prose. A hand-written "as of version X"
drifts silently. The only pages that may state a version are generated or
drift-guarded ones —
docs/reference/validation.mdis regenerated in CI and checked withgit diff --exit-code. Everything else should describe behavior, not versions (the installation page printsprocessbehavior.__version__with a placeholder expected output for exactly this reason). - Deploys are
main-only via.github/workflows/docs.yml; PR builds verify the site compiles but do not deploy. - The
mystmdversion is pinned by hand indocs.yml(annpm install -g mystmd@<version>run step Dependabot cannot see). Bumping it is release housekeeping: build locally with the new version, eyeball the rendered site, then update the pin.
Revisit at 1.0: if breaking releases start, versioned deploy paths (e.g.
/v1.0/) with a switcher become worth the CI work. Not before.
The current public surface is the two-step analyst workflow:
import processbehavior as pb
study = pb.ProcessBehavior(df).formulate(response=..., time=..., factors=[...])
result = study.execute()Anything exported from processbehavior/__init__.py is part of the public
API. Breaking changes to those symbols require a ## [Unreleased] entry in
CHANGELOG.md flagged as Breaking.
- Branch off
main, keep PRs focused on one concern - Add or update tests for behavioral changes
- Update
CHANGELOG.mdunder## [Unreleased] - Confirm
pytest tests/,ruff check ., andmypy processbehaviorpass - Fill in the PR template (
.github/pull_request_template.md); it is a checklist of the invariants most easily broken by accident
Open an issue at https://github.com/cnicholas/processbehavior/issues with:
- a minimal reproducer (DataFrame snippet or
pb.make_design(state=..., seed=...)call) - the version of processbehavior, pandas, and Python
- the full traceback or wrong output
For security-sensitive issues, use the private disclosure path in
SECURITY.md instead of opening a public issue.
Releases are published to PyPI by the Publish workflow on tag push.
- Confirm CI is green on
main, including theauditandsmoke-testjobs. - Move
## [Unreleased]content into a new## [X.Y.Z] - YYYY-MM-DDsection inCHANGELOG.mdand update the compare links at the bottom. - Bump the version in
processbehavior/__init__.py(__version__).pyproject.tomlreads it via[tool.hatch.version]. - Run
python validation/e2e_bishop_report.pyand commit the regenerateddocs/reference/validation.md. Its header carries the version string, and the publish workflow fails if the committed page has drifted from what the validator writes. - Commit with subject
Release vX.Y.Z, push tomain. - Tag and push:
The tag push triggers
git tag -s vX.Y.Z -m "Release vX.Y.Z" git push origin vX.Y.Z.github/workflows/publish.yml, which builds, verifies withtwine check, and uploads to PyPI via OIDC trusted publishing — no API tokens. - Verify the release on https://pypi.org/project/processbehavior/ and run
pip install processbehavior==X.Y.Zin a fresh venv to confirm the README quickstart still runs end-to-end.
The PyPI trusted publisher must be configured once at
https://pypi.org/manage/project/processbehavior/settings/publishing/
before the first release. Configure repository
cnicholas/processbehavior, workflow publish.yml, environment pypi.
By participating, you agree to follow the Code of Conduct.