calm-benchmark 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calm_benchmark-0.1.3/.github/workflows/ci.yml +18 -0
- calm_benchmark-0.1.3/.github/workflows/publish-pypi.yml +45 -0
- calm_benchmark-0.1.3/.gitignore +19 -0
- calm_benchmark-0.1.3/.hypothesis/.gitignore +9 -0
- calm_benchmark-0.1.3/.hypothesis/constants/0c4ab3f4807b1659 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/0fc300e77578a183 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/12d99eb2fb0e31cc +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/14075edae418ffe6 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/15208dff27bebba0 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/1c43ea5aad69db0f +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/1de1c580569e9cea +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/2170d90bc85b3eb8 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/24be4ab7866beb98 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/2a676ced37d4cce1 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/31dd52fcb4e2a2b3 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/39073abd55cb81c8 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/3ad8f61b62a82266 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/42cb07f95690e4b3 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/4446fa7afd69f802 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/570fa43e156bc904 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/5c3118ac0156bb09 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/6166398d30c22845 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/71e00ec495499f44 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/736d6fe7be657c15 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/743c6e1dfb631705 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/76508aa4a4175b66 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/7662d704b8d35622 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/76bc977e7eb5cd52 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/7afaf1638e6eb750 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/7c805b6af0508d82 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/803886b0ec08beb9 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/8a6e0aa798244d9c +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/8fba44fbd7419531 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/92f6bd8fa9a6a6a0 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/ac61764b214cded0 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/b7273513001c7382 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/c3d801b66e25d28e +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/cb383feb990bc16b +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/cc255fd23cd54b1b +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/d1e39bf8bc23207e +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/d920e5be5304d03b +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/e00e778e1fc5a182 +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/e56700b7fce7099f +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/f573a9d979b3995e +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/fa19d69dfd8d556c +4 -0
- calm_benchmark-0.1.3/.hypothesis/constants/fa99e419bd9005fc +4 -0
- calm_benchmark-0.1.3/.hypothesis/unicode_data/16.0.0/charmap.json.gz +0 -0
- calm_benchmark-0.1.3/.hypothesis/unicode_data/16.0.0/codec-utf-8.json.gz +0 -0
- calm_benchmark-0.1.3/.pre-commit-config.yaml +12 -0
- calm_benchmark-0.1.3/.python-version +1 -0
- calm_benchmark-0.1.3/AGENT.md +155 -0
- calm_benchmark-0.1.3/CHANGELOG.md +75 -0
- calm_benchmark-0.1.3/CITATION.cff +12 -0
- calm_benchmark-0.1.3/DESIGN.md +255 -0
- calm_benchmark-0.1.3/LICENSE +21 -0
- calm_benchmark-0.1.3/PKG-INFO +180 -0
- calm_benchmark-0.1.3/README.md +164 -0
- calm_benchmark-0.1.3/TODOS.md +184 -0
- calm_benchmark-0.1.3/configs/default.toml +46 -0
- calm_benchmark-0.1.3/docs/api.md +15 -0
- calm_benchmark-0.1.3/docs/extending.md +21 -0
- calm_benchmark-0.1.3/docs/index.md +8 -0
- calm_benchmark-0.1.3/docs/usage.md +26 -0
- calm_benchmark-0.1.3/mkdocs.yml +15 -0
- calm_benchmark-0.1.3/notebooks/README.md +11 -0
- calm_benchmark-0.1.3/notebooks/inspect_nhanes_2017_2018.ipynb +173 -0
- calm_benchmark-0.1.3/pyproject.toml +68 -0
- calm_benchmark-0.1.3/services/__init__.py +1 -0
- calm_benchmark-0.1.3/services/explainer/README.md +11 -0
- calm_benchmark-0.1.3/services/explainer/__init__.py +1 -0
- calm_benchmark-0.1.3/services/explainer/calm_explainer/__init__.py +6 -0
- calm_benchmark-0.1.3/services/explainer/calm_explainer/contracts.py +40 -0
- calm_benchmark-0.1.3/services/explainer/calm_explainer/openai_client.py +59 -0
- calm_benchmark-0.1.3/services/explainer/calm_explainer/service.py +49 -0
- calm_benchmark-0.1.3/services/explainer/pyproject.toml +9 -0
- calm_benchmark-0.1.3/src/calm/__init__.py +41 -0
- calm_benchmark-0.1.3/src/calm/adapters/__init__.py +6 -0
- calm_benchmark-0.1.3/src/calm/adapters/codebook.py +30 -0
- calm_benchmark-0.1.3/src/calm/adapters/nhanes.py +70 -0
- calm_benchmark-0.1.3/src/calm/adapters/nhanes_2017_2018.py +118 -0
- calm_benchmark-0.1.3/src/calm/adapters/synthetic.py +109 -0
- calm_benchmark-0.1.3/src/calm/cli.py +86 -0
- calm_benchmark-0.1.3/src/calm/config/__init__.py +6 -0
- calm_benchmark-0.1.3/src/calm/config/loading.py +19 -0
- calm_benchmark-0.1.3/src/calm/config/models.py +132 -0
- calm_benchmark-0.1.3/src/calm/domain/__init__.py +5 -0
- calm_benchmark-0.1.3/src/calm/domain/entities.py +211 -0
- calm_benchmark-0.1.3/src/calm/domain/errors.py +5 -0
- calm_benchmark-0.1.3/src/calm/domain/leakage.py +13 -0
- calm_benchmark-0.1.3/src/calm/observability/__init__.py +14 -0
- calm_benchmark-0.1.3/src/calm/observability/hashing.py +49 -0
- calm_benchmark-0.1.3/src/calm/observability/logging.py +17 -0
- calm_benchmark-0.1.3/src/calm/observability/provenance.py +46 -0
- calm_benchmark-0.1.3/src/calm/orchestration/__init__.py +6 -0
- calm_benchmark-0.1.3/src/calm/orchestration/benchmark.py +364 -0
- calm_benchmark-0.1.3/src/calm/orchestration/manifest.py +54 -0
- calm_benchmark-0.1.3/src/calm/orchestration/runner.py +59 -0
- calm_benchmark-0.1.3/src/calm/pipeline/__init__.py +1 -0
- calm_benchmark-0.1.3/src/calm/pipeline/attribution.py +62 -0
- calm_benchmark-0.1.3/src/calm/pipeline/calibrate.py +118 -0
- calm_benchmark-0.1.3/src/calm/pipeline/cohort.py +49 -0
- calm_benchmark-0.1.3/src/calm/pipeline/evaluate.py +315 -0
- calm_benchmark-0.1.3/src/calm/pipeline/features.py +52 -0
- calm_benchmark-0.1.3/src/calm/pipeline/ingest.py +100 -0
- calm_benchmark-0.1.3/src/calm/pipeline/labels.py +346 -0
- calm_benchmark-0.1.3/src/calm/pipeline/report.py +211 -0
- calm_benchmark-0.1.3/src/calm/pipeline/split.py +76 -0
- calm_benchmark-0.1.3/src/calm/pipeline/train.py +151 -0
- calm_benchmark-0.1.3/src/calm/pipeline/verification.py +79 -0
- calm_benchmark-0.1.3/src/calm/ports/__init__.py +5 -0
- calm_benchmark-0.1.3/src/calm/ports/data_source.py +12 -0
- calm_benchmark-0.1.3/tests/property/test_partitioning.py +53 -0
- calm_benchmark-0.1.3/tests/unit/adapters/test_codebook.py +14 -0
- calm_benchmark-0.1.3/tests/unit/adapters/test_nhanes.py +26 -0
- calm_benchmark-0.1.3/tests/unit/adapters/test_nhanes_2017_2018.py +65 -0
- calm_benchmark-0.1.3/tests/unit/config/test_models.py +113 -0
- calm_benchmark-0.1.3/tests/unit/domain/test_entities.py +72 -0
- calm_benchmark-0.1.3/tests/unit/domain/test_leakage.py +13 -0
- calm_benchmark-0.1.3/tests/unit/observability/test_hashing.py +44 -0
- calm_benchmark-0.1.3/tests/unit/orchestration/test_manifest_shape.py +50 -0
- calm_benchmark-0.1.3/tests/unit/orchestration/test_runner.py +60 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_attribution.py +48 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_calibrate.py +138 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_cohort.py +29 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_evaluate.py +93 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_features.py +58 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_ingest.py +34 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_labels.py +153 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_report.py +113 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_split.py +28 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_train.py +66 -0
- calm_benchmark-0.1.3/tests/unit/pipeline/test_verification.py +60 -0
- calm_benchmark-0.1.3/tests/unit/test_cli.py +99 -0
- calm_benchmark-0.1.3/tests/unit/test_docs.py +17 -0
- calm_benchmark-0.1.3/tests/unit/test_explainer.py +68 -0
- calm_benchmark-0.1.3/tests/unit/test_public_api.py +41 -0
- calm_benchmark-0.1.3/uv.lock +2356 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v6
|
|
13
|
+
- uses: astral-sh/setup-uv@v7
|
|
14
|
+
- run: uv sync --all-groups
|
|
15
|
+
- run: uv run ruff check
|
|
16
|
+
- run: uv run ruff format --check
|
|
17
|
+
- run: uv run mypy
|
|
18
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: pypi
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
id-token: write
|
|
18
|
+
steps:
|
|
19
|
+
- name: Check out source
|
|
20
|
+
uses: actions/checkout@v7
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
|
|
27
|
+
- name: Install Python
|
|
28
|
+
run: uv python install 3.14
|
|
29
|
+
|
|
30
|
+
- name: Verify release version
|
|
31
|
+
run: test "v$(uv version --short)" = "$GITHUB_REF_NAME"
|
|
32
|
+
|
|
33
|
+
- name: Run release gate
|
|
34
|
+
run: |
|
|
35
|
+
uv sync --locked
|
|
36
|
+
uv run ruff check
|
|
37
|
+
uv run ruff format --check
|
|
38
|
+
uv run mypy
|
|
39
|
+
uv run pytest --cov=calm
|
|
40
|
+
|
|
41
|
+
- name: Build distributions
|
|
42
|
+
run: uv build
|
|
43
|
+
|
|
44
|
+
- name: Publish distributions
|
|
45
|
+
run: uv publish
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# This .gitignore file was automatically created by Hypothesis. Hypothesis gitignores
|
|
2
|
+
# .hypothesis by default, because we generally recommend that .hypothesis not be checked
|
|
3
|
+
# into version control.
|
|
4
|
+
#
|
|
5
|
+
# If you *would* like to check .hypothesis into version control, you should delete this
|
|
6
|
+
# file. Hypothesis will not re-create this .gitignore unless .hypothesis is deleted (and
|
|
7
|
+
# if it does, that's a bug - please report it!)
|
|
8
|
+
|
|
9
|
+
*
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/orchestration/benchmark.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
['0.1.3', '2017-2018', 'AGE', 'RHD043', 'RHQ031', 'RIAGENDR', 'RIDAGEYR', 'SEQN', 'SEX', 'acquire', 'attribute', 'calibrate', 'calm', 'cohort', 'demographics', 'evaluate', 'features', 'full_range', 'ingest', 'labels', 'questionnaire', 'real-data', 'report', 'split', 'synthetic', 'synthetic://', 'train', 'unavailable']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/config/models.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
[0.95, 100, 120, 200, '1', '^\\d{4}-\\d{4}$', 'after', 'demographics', 'examination', 'exclude', 'forbid', 'full_range', 'gradient_boosting', 'isotonic', 'laboratory', 'logistic_regression', 'natural_menopause', 'premenopausal', 'preselected', 'questionnaire', 'restricted', 'sigmoid']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/__init__.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
['0.1.3', 'CalibratedModel', 'EvaluationResult', 'FeatureAttribution', 'FrozenSplit', 'LabelResult', 'PredictionResult', 'ReportArtifacts', 'ReportWriter', 'RunConfig', 'Subgroup', 'TrainedModel', 'app', 'attribute', 'build_labels', 'calibrate', 'evaluate', 'get_label_rule', 'load_config', 'predict', 'select_features', 'stratified_split', 'train']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/cli.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
[0.2, 0.45, 0.55, 200, '--config', '.cache', '.raw', '2017-2018', 'calm', 'exclude', 'logistic_regression', 'marker_one', 'marker_two', 'max_iter', 'nhanes-2017-2018', 'public_cessation', 'restricted', 'run-nhanes', 'run-synthetic', 'runs', 'sigmoid', 'synthetic-demo', 'synthetic-run']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/pipeline/labels.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
['1', '2', '3', '7', 'RHD043', 'RHD143', 'RHD280', 'RHQ031', 'RHQ200', 'RHQ305', 'RHQ540', 'SEQN', 'exclude', 'exogenous_hormones', 'hysterectomy', 'lactation', 'natural-menopause-1', 'natural_menopause', 'no', 'perimenopause', 'pregnancy', 'premenopausal', 'public_cessation', 'surgical_menopause', 'yes']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/adapters/synthetic.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
[2026, 'AGE', 'Age', 'Female', 'Hysterectomy', 'Male', 'No', 'RHD043', 'RHD143', 'RHD280', 'RHQ031', 'RHQ200', 'RHQ305', 'RHQ540', 'SEQN', 'SEX', 'STATUS', 'Sex', 'Synthetic marker one', 'Synthetic marker two', 'Yes', 'demographics', 'demographics.sav', 'laboratory', 'laboratory.sav', 'marker_one', 'marker_two', 'questionnaire', 'questionnaire.sav']
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# file: /home/runner/work/calm/calm/src/calm/adapters/nhanes_2017_2018.py
|
|
2
|
+
# hypothesis_version: 6.156.7
|
|
3
|
+
|
|
4
|
+
['1', '2', '2017-2018', '3', '7', 'BMX_J.XPT', 'BPX_J.XPT', 'Breast feeding', 'CBC_J.XPT', 'DEMO_J.XPT', 'GHB_J.XPT', 'HDL_J.XPT', 'Hysterectomy', 'No', 'Pregnancy', 'RHD043', 'RHQ031', 'RHQ_J.XPT', 'RIAGENDR', 'RIDAGEYR', 'SEQN', 'TCHOL_J.XPT', 'Yes', 'blood_pressure', 'body_measures', 'complete_blood_count', 'demographics', 'glycated_hemoglobin', 'hdl', 'questionnaire', 'total_cholesterol']
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.15.22
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff-check
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
9
|
+
rev: v1.19.1
|
|
10
|
+
hooks:
|
|
11
|
+
- id: mypy
|
|
12
|
+
additional_dependencies: [pydantic, typer]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# CALM
|
|
2
|
+
|
|
3
|
+
This document governs how the autonomous engineering agent builds **CALM**. It is binding. When this
|
|
4
|
+
document and any instinct to move faster conflict, this document wins.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Mission
|
|
9
|
+
|
|
10
|
+
Build **CALM** (Calibrated Menopausal-status benchmark): an open, reproducible, rigorously tested
|
|
11
|
+
benchmark that predicts premenopausal vs. postmenopausal status from routine, low-cost markers derived
|
|
12
|
+
from NHANES. CALM is a **library and CLI** application. It produces versioned, provenance-tracked
|
|
13
|
+
artifacts that downstream systems consume.
|
|
14
|
+
|
|
15
|
+
Read `DESIGN.md` for the architecture and `TODOS.md` for the phased plan before writing code.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. Prime directives (non-negotiable)
|
|
20
|
+
|
|
21
|
+
1. **Reproducibility over speed.** Any result must be regenerable from config plus pinned inputs. A change
|
|
22
|
+
that breaks reproducibility is a defect, not a trade-off.
|
|
23
|
+
2. **Determinism.** All randomness flows from a single injected RNG seeded by config. No wall-clock and no
|
|
24
|
+
ambient state in domain logic.
|
|
25
|
+
3. **No fabrication.** Never invent data, variable codes, response codings, or metric values.
|
|
26
|
+
Unknown is not a licence to guess.
|
|
27
|
+
4. **Verify domain facts from source metadata, not memory.** NHANES variable codes and value codings are
|
|
28
|
+
read from ingested `.XPT` value-label metadata and asserted. If a required code or coding cannot be
|
|
29
|
+
verified from metadata, **stop and escalate** (§10). Do not assume `1 = yes`.
|
|
30
|
+
5. **The leakage boundary is sacred.** Variables used to construct the label must never reach the feature
|
|
31
|
+
layer. Enforce with a runtime invariant and a property-based test.
|
|
32
|
+
6. **Tests gate every change.** No implementation is done without unit tests. Pipeline invariants get
|
|
33
|
+
property-based tests. Metrics get golden tests.
|
|
34
|
+
7. **No unnecessary comments.** Types and names document structure; Google-style docstrings document the
|
|
35
|
+
public API. Inline comments exist only to justify a non-obvious *why*, and rarely.
|
|
36
|
+
8. **Small, verifiable increments.** One task at a time, each ending green. Never advance a phase with a
|
|
37
|
+
red gate.
|
|
38
|
+
9. **Every step is recorded.** Each pipeline stage is instrumented (timing, input/output content hashes,
|
|
39
|
+
emitted metrics), and each run writes a durable manifest.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 3. Operating loop (repeat per task)
|
|
44
|
+
|
|
45
|
+
1. Open `TODOS.md`; select the next unblocked task in the lowest incomplete phase.
|
|
46
|
+
2. Write the failing test(s) that define the task's success.
|
|
47
|
+
3. Implement the **minimal** typed code to pass them, respecting layer boundaries (§6).
|
|
48
|
+
4. Run the gate:
|
|
49
|
+
`uv run ruff check && uv run ruff format --check && uv run mypy && uv run pytest --cov=calm`.
|
|
50
|
+
All must pass; coverage must not regress.
|
|
51
|
+
5. Add a `CHANGELOG.md` entry under `Unreleased`.
|
|
52
|
+
6. Emit a checkpoint report (§5) and check the task box.
|
|
53
|
+
7. Stop. Do not chain tasks silently.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 4. Definition of done
|
|
58
|
+
|
|
59
|
+
- **Global:** gates green (lint, format, types, tests, coverage ≥ threshold); docstrings on public
|
|
60
|
+
symbols; changelog updated; no undocumented TODO/FIXME left in the tree.
|
|
61
|
+
- **Per stage:** typed input/output contract; unit tests; relevant invariants tested; provenance emitted;
|
|
62
|
+
instrumented by the orchestrator.
|
|
63
|
+
- **Per phase:** all phase tasks checked **and** the phase acceptance tests pass.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 5. Monitoring & reporting
|
|
68
|
+
|
|
69
|
+
After every task, emit exactly:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
[phase X · task Y] <what changed>
|
|
73
|
+
tests: +N (unit/property/golden) | gates: ruff ✓ mypy ✓ pytest ✓ | cov: A% (Δ)
|
|
74
|
+
artifacts / manifests touched: <...>
|
|
75
|
+
next: <task> blockers: <none | ...>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Never report a phase complete unless its acceptance criteria in `TODOS.md` pass. Surface coverage or type
|
|
79
|
+
regressions immediately instead of proceeding.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 6. Coding standards
|
|
84
|
+
|
|
85
|
+
- Target **Python 3.14**, managed with **uv**. Source under `src/calm/`.
|
|
86
|
+
- **Full type hints**; no `Any` in public signatures. Prefer `Protocol` for ports and
|
|
87
|
+
`@dataclass(frozen=True)` or pydantic for data.
|
|
88
|
+
- **Layer purity:** `calm/domain/` imports no I/O, no framework, and nothing from `calm/adapters`.
|
|
89
|
+
Dependencies point inward (domain ← pipeline ← orchestration ← adapters / CLI).
|
|
90
|
+
- **Docstrings:** Google style, on public modules, classes, and functions only. Enforced via Ruff `D`
|
|
91
|
+
rules.
|
|
92
|
+
- **Config** is pydantic; never read environment or files inside domain logic.
|
|
93
|
+
- **Errors** are typed exceptions with actionable messages. Domain uncertainty raises a dedicated
|
|
94
|
+
`DomainVerificationError` that halts the run.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 7. Determinism rules
|
|
99
|
+
|
|
100
|
+
- One RNG (numpy `Generator`) constructed from `config.seed`, injected where needed.
|
|
101
|
+
- Artifacts are content-addressed: the hash of (normalized config + input hashes) identifies an output.
|
|
102
|
+
- Splits, model initialization, and any sampling use only the injected RNG.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 8. Domain guardrails
|
|
107
|
+
|
|
108
|
+
- **Label construction** from the Reproductive Health questionnaire: read the value-label metadata and
|
|
109
|
+
assert the response coding before applying it. Apply and log exclusions (surgical menopause, pregnancy
|
|
110
|
+
and lactation, exogenous hormones) with counts.
|
|
111
|
+
- **Age confounding:** honor the configured policy — restricted transition window, or full range with
|
|
112
|
+
mandatory age-band reporting. Never headline a full-range AUROC without the age-band breakdown.
|
|
113
|
+
- **Survey weights:** CALM models at the individual level; weights are not applied to metrics unless
|
|
114
|
+
explicitly configured, and the choice is recorded in the artifacts.
|
|
115
|
+
- **No clinical claims** anywhere in code, docstrings, or artifacts. CALM predicts and evaluates; it never
|
|
116
|
+
diagnoses.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 9. Tooling
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
uv sync # install
|
|
124
|
+
uv run calm-benchmark --help # CLI
|
|
125
|
+
uv run ruff check # lint
|
|
126
|
+
uv run ruff format --check # format
|
|
127
|
+
uv run mypy # types
|
|
128
|
+
uv run pytest --cov=calm # tests + coverage
|
|
129
|
+
uv run pre-commit run -a # all hooks
|
|
130
|
+
uv run mkdocs serve # docs preview
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 10. Escalation / stop conditions
|
|
136
|
+
|
|
137
|
+
Halt and surface a concise decision request when:
|
|
138
|
+
|
|
139
|
+
- a required NHANES code or response coding cannot be verified from ingested metadata;
|
|
140
|
+
- the specification is ambiguous in a way that changes results (for example, an undefined perimenopause
|
|
141
|
+
policy for the data at hand);
|
|
142
|
+
- a gate cannot pass without weakening a guarantee (reproducibility, leakage boundary, determinism);
|
|
143
|
+
- proceeding would require inventing data or numbers.
|
|
144
|
+
|
|
145
|
+
Escalation is success, not failure. Guessing on any of the above is a defect.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 11. Prohibited
|
|
150
|
+
|
|
151
|
+
- Committing red gates or skipping tests to "unblock."
|
|
152
|
+
- Placing I/O in the domain layer or bypassing ports.
|
|
153
|
+
- Hardcoding variable codes without metadata verification.
|
|
154
|
+
- Emitting a metric computed outside the evaluation stage.
|
|
155
|
+
- Adding UI, serving, or LLM features to CALM core.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Aligned package metadata, runtime provenance, citation, and release artifacts to version 0.1.3.
|
|
13
|
+
|
|
14
|
+
- Renamed the PyPI distribution to `calm-benchmark` to avoid collision with the unrelated `calm`
|
|
15
|
+
package, renamed the CLI to `calm-benchmark`, and added tag-driven uv Trusted Publishing automation.
|
|
16
|
+
|
|
17
|
+
- Completed Phase 10: added provenance-bound feature-association exports and an isolated OpenAI
|
|
18
|
+
Structured-Outputs explanation service with immutable hand-offs and adversarial safety refusals.
|
|
19
|
+
|
|
20
|
+
- Completed Phase 9 methodological validation: withheld out-of-range predictions; deterministic bootstrap
|
|
21
|
+
confidence intervals; subgroup denominators and eligibility; enforced full-range age-band context;
|
|
22
|
+
calibration feasibility and preselected-method recording; and run-derived benchmark-card disclosures.
|
|
23
|
+
|
|
24
|
+
- Require a configured minimum number of validation examples per outcome class for calibration and retain fit sample
|
|
25
|
+
counts on calibrated model artifacts.
|
|
26
|
+
|
|
27
|
+
- Added source-derived age-band subgroups to every benchmark evaluation, with a full-range guard against
|
|
28
|
+
reporting an aggregate without age context.
|
|
29
|
+
|
|
30
|
+
- Made the no-call execution boundary explicit: out-of-range or low-confidence scores have no
|
|
31
|
+
actionable class label, and documented the range-checking limitation.
|
|
32
|
+
|
|
33
|
+
- Added the pinned public NHANES 2017–2018 CLI run, checksum-verified local input adapter, versioned
|
|
34
|
+
RHQ metadata contract, and real `SEQN`-joined multi-component feature assembly.
|
|
35
|
+
|
|
36
|
+
- Added an architecture and delivery audit to the roadmap, distinguishing implemented unit-level
|
|
37
|
+
safeguards from the remaining end-to-end benchmark, methodological, attribution, and separate LLM
|
|
38
|
+
communication-layer work.
|
|
39
|
+
- Replaced the hand-assembled CLI demo with a config-driven synthetic execution of every benchmark stage,
|
|
40
|
+
including a required complete run manifest.
|
|
41
|
+
- Added a validated TOML-driven synthetic CLI command and a default run configuration.
|
|
42
|
+
- Made the range-based out-of-distribution safeguard a mandatory no-call condition.
|
|
43
|
+
- Corrected the 2017–2018 NHANES access note: `RHQ031` and `RHD043` are public-use fields; only the
|
|
44
|
+
clean surgical-menopause exclusion for women aged 45 and older requires the optional RDC variant.
|
|
45
|
+
- Added a separately versioned public-use cessation label rule that avoids claiming unavailable natural-
|
|
46
|
+
menopause exclusions.
|
|
47
|
+
- Reconciled README and architecture claims with shipped artifacts, marking NHANES production runs,
|
|
48
|
+
stored model artifacts, generated model cards, and SHAP attribution as planned.
|
|
49
|
+
- Added branch-tested public NHANES age-band coverage verification for label-variant selection.
|
|
50
|
+
|
|
51
|
+
## [0.1.3] - 2026-07-19
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- Initial project scaffold and development tooling.
|
|
56
|
+
- Immutable Pydantic run-configuration contracts and TOML loading.
|
|
57
|
+
- Frozen domain value objects and entities with alignment and shape invariants.
|
|
58
|
+
- Deterministic content hashing, normalized configuration hashes, and immutable provenance records.
|
|
59
|
+
- Structured JSON logging, injected-clock stage instrumentation, and durable run-manifest writing.
|
|
60
|
+
- Phase 1 acceptance tests for configuration failures, hash stability, and no-op manifest shape.
|
|
61
|
+
- Configurable NHANES raw-file acquisition port with byte checksums and source lineage.
|
|
62
|
+
- Deterministic offline synthetic source and pyreadstat ingestion with recoverable value-label metadata.
|
|
63
|
+
- Configurable cohort selection with participant drop-count accounting.
|
|
64
|
+
- Registered natural-menopause label construction with metadata-verified response codings,
|
|
65
|
+
auditable exclusion and class-balance counts, configurable perimenopause treatment, and an optional
|
|
66
|
+
early-natural-menopause secondary outcome.
|
|
67
|
+
- Leakage-safe allowlist feature selection and deterministic, content-addressed stratified split
|
|
68
|
+
artifacts, including property-tested partition invariants.
|
|
69
|
+
- Registered logistic-regression and gradient-boosting training with injected RNGs, validation-only
|
|
70
|
+
sigmoid or isotonic calibration, abstention bands, and training-range distribution-shift flags.
|
|
71
|
+
- Frozen-test evaluation with a metric registry, reliability data, abstention and distribution-shift
|
|
72
|
+
accounting, subgroup reports, and deterministic metrics, SVG reliability plot, benchmark-card, and
|
|
73
|
+
manifest exports.
|
|
74
|
+
- Frozen public API, offline CLI demonstration, generated API documentation, extension guidance, and
|
|
75
|
+
Citation File Format metadata. A DOI has not been assigned.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use CALM, please cite it using this metadata."
|
|
3
|
+
title: "CALM: Calibrated Menopausal-status Benchmark"
|
|
4
|
+
version: 0.1.3
|
|
5
|
+
date-released: 2026-07-19
|
|
6
|
+
license: MIT
|
|
7
|
+
abstract: "A reproducible research benchmark for menopausal-status prediction from routine health markers."
|
|
8
|
+
keywords:
|
|
9
|
+
- reproducibility
|
|
10
|
+
- NHANES
|
|
11
|
+
- menopausal status
|
|
12
|
+
- benchmark
|