komichi 1.0.1__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.
- komichi-1.0.1/.github/workflows/ci.yml +37 -0
- komichi-1.0.1/.github/workflows/publish.yml +82 -0
- komichi-1.0.1/.gitignore +28 -0
- komichi-1.0.1/CHANGELOG.md +330 -0
- komichi-1.0.1/CONTRIBUTING.md +72 -0
- komichi-1.0.1/LICENSE +21 -0
- komichi-1.0.1/PKG-INFO +304 -0
- komichi-1.0.1/README.md +243 -0
- komichi-1.0.1/docs/adr/0001-toolbox-not-workflow.md +40 -0
- komichi-1.0.1/docs/adr/0002-freeze-the-public-surface.md +59 -0
- komichi-1.0.1/docs/adr/README.md +13 -0
- komichi-1.0.1/docs/bench.md +149 -0
- komichi-1.0.1/docs/clean.md +200 -0
- komichi-1.0.1/docs/console.md +148 -0
- komichi-1.0.1/docs/eval.md +179 -0
- komichi-1.0.1/docs/index.md +32 -0
- komichi-1.0.1/docs/inspect.md +110 -0
- komichi-1.0.1/docs/philosophy.md +61 -0
- komichi-1.0.1/docs/plugins.md +136 -0
- komichi-1.0.1/docs/quickstart.md +176 -0
- komichi-1.0.1/docs/report.md +73 -0
- komichi-1.0.1/docs/roadmap.md +35 -0
- komichi-1.0.1/docs/sweep.md +90 -0
- komichi-1.0.1/docs/ui.md +46 -0
- komichi-1.0.1/examples/README.md +39 -0
- komichi-1.0.1/examples/benchmark.html +167 -0
- komichi-1.0.1/examples/pipeline.py +91 -0
- komichi-1.0.1/examples/profile.html +395 -0
- komichi-1.0.1/examples/profile.json +1126 -0
- komichi-1.0.1/examples/recipe.yaml +54 -0
- komichi-1.0.1/examples/sweep.yaml +14 -0
- komichi-1.0.1/mkdocs.yml +33 -0
- komichi-1.0.1/pyproject.toml +124 -0
- komichi-1.0.1/src/michi/__init__.py +19 -0
- komichi-1.0.1/src/michi/adapters/README.md +13 -0
- komichi-1.0.1/src/michi/adapters/__init__.py +17 -0
- komichi-1.0.1/src/michi/adapters/model.py +323 -0
- komichi-1.0.1/src/michi/bench/README.md +12 -0
- komichi-1.0.1/src/michi/bench/__init__.py +33 -0
- komichi-1.0.1/src/michi/bench/preprocess.py +145 -0
- komichi-1.0.1/src/michi/bench/registry.py +412 -0
- komichi-1.0.1/src/michi/bench/runner.py +554 -0
- komichi-1.0.1/src/michi/bench/significance.py +223 -0
- komichi-1.0.1/src/michi/cli/__init__.py +12 -0
- komichi-1.0.1/src/michi/cli/app.py +153 -0
- komichi-1.0.1/src/michi/cli/bench_cmd.py +226 -0
- komichi-1.0.1/src/michi/cli/clean_cmd.py +402 -0
- komichi-1.0.1/src/michi/cli/context.py +117 -0
- komichi-1.0.1/src/michi/cli/errors.py +28 -0
- komichi-1.0.1/src/michi/cli/eval_cmd.py +266 -0
- komichi-1.0.1/src/michi/cli/inspect_cmd.py +170 -0
- komichi-1.0.1/src/michi/cli/report_cmd.py +103 -0
- komichi-1.0.1/src/michi/cli/sweep_cmd.py +152 -0
- komichi-1.0.1/src/michi/cli/ui_cmd.py +67 -0
- komichi-1.0.1/src/michi/console/__init__.py +38 -0
- komichi-1.0.1/src/michi/console/commands.py +467 -0
- komichi-1.0.1/src/michi/console/session.py +139 -0
- komichi-1.0.1/src/michi/console/shell.py +180 -0
- komichi-1.0.1/src/michi/core/__init__.py +59 -0
- komichi-1.0.1/src/michi/core/artifacts.py +411 -0
- komichi-1.0.1/src/michi/core/config.py +166 -0
- komichi-1.0.1/src/michi/core/errors.py +90 -0
- komichi-1.0.1/src/michi/core/hashing.py +64 -0
- komichi-1.0.1/src/michi/core/io.py +281 -0
- komichi-1.0.1/src/michi/core/manifest.py +364 -0
- komichi-1.0.1/src/michi/evaluation/README.md +11 -0
- komichi-1.0.1/src/michi/evaluation/__init__.py +38 -0
- komichi-1.0.1/src/michi/evaluation/checks.py +260 -0
- komichi-1.0.1/src/michi/evaluation/evaluator.py +488 -0
- komichi-1.0.1/src/michi/evaluation/metrics.py +402 -0
- komichi-1.0.1/src/michi/explain/README.md +12 -0
- komichi-1.0.1/src/michi/explain/__init__.py +18 -0
- komichi-1.0.1/src/michi/explain/content/README.md +6 -0
- komichi-1.0.1/src/michi/explain/content/findings.yaml +384 -0
- komichi-1.0.1/src/michi/explain/registry.py +81 -0
- komichi-1.0.1/src/michi/inspection/README.md +12 -0
- komichi-1.0.1/src/michi/inspection/__init__.py +25 -0
- komichi-1.0.1/src/michi/inspection/findings.py +652 -0
- komichi-1.0.1/src/michi/inspection/profiler.py +304 -0
- komichi-1.0.1/src/michi/plugins/__init__.py +40 -0
- komichi-1.0.1/src/michi/plugins/compat.py +138 -0
- komichi-1.0.1/src/michi/plugins/registry.py +127 -0
- komichi-1.0.1/src/michi/py.typed +0 -0
- komichi-1.0.1/src/michi/recipes/README.md +11 -0
- komichi-1.0.1/src/michi/recipes/__init__.py +58 -0
- komichi-1.0.1/src/michi/recipes/apply.py +321 -0
- komichi-1.0.1/src/michi/recipes/author.py +634 -0
- komichi-1.0.1/src/michi/recipes/export.py +303 -0
- komichi-1.0.1/src/michi/recipes/model.py +235 -0
- komichi-1.0.1/src/michi/recipes/pipeline.py +126 -0
- komichi-1.0.1/src/michi/recipes/serialise.py +171 -0
- komichi-1.0.1/src/michi/report/README.md +9 -0
- komichi-1.0.1/src/michi/report/__init__.py +51 -0
- komichi-1.0.1/src/michi/report/comparison.py +330 -0
- komichi-1.0.1/src/michi/report/html.py +193 -0
- komichi-1.0.1/src/michi/report/runs.py +130 -0
- komichi-1.0.1/src/michi/report/templates/_ui_base.html.jinja +70 -0
- komichi-1.0.1/src/michi/report/templates/benchmark.html.jinja +159 -0
- komichi-1.0.1/src/michi/report/templates/profile.html.jinja +163 -0
- komichi-1.0.1/src/michi/report/templates/runs.html.jinja +101 -0
- komichi-1.0.1/src/michi/report/templates/ui_index.html.jinja +41 -0
- komichi-1.0.1/src/michi/report/templates/ui_missing.html.jinja +9 -0
- komichi-1.0.1/src/michi/report/templates/ui_run.html.jinja +74 -0
- komichi-1.0.1/src/michi/report/terminal.py +754 -0
- komichi-1.0.1/src/michi/sweep/README.md +10 -0
- komichi-1.0.1/src/michi/sweep/__init__.py +28 -0
- komichi-1.0.1/src/michi/sweep/plan.py +193 -0
- komichi-1.0.1/src/michi/sweep/runner.py +256 -0
- komichi-1.0.1/src/michi/ui/__init__.py +18 -0
- komichi-1.0.1/src/michi/ui/app.py +99 -0
- komichi-1.0.1/tests/conftest.py +180 -0
- komichi-1.0.1/tests/e2e/README.md +5 -0
- komichi-1.0.1/tests/e2e/test_export_equivalence.py +168 -0
- komichi-1.0.1/tests/e2e/test_schema_stability.py +177 -0
- komichi-1.0.1/tests/fixtures/README.md +8 -0
- komichi-1.0.1/tests/fixtures/schemas/manifest-1.0.json +80 -0
- komichi-1.0.1/tests/fixtures/schemas/profile-1.0.json +86 -0
- komichi-1.0.1/tests/fixtures/schemas/recipe-1.0.yaml +50 -0
- komichi-1.0.1/tests/golden/README.md +6 -0
- komichi-1.0.1/tests/golden/__snapshots__/test_render_profile.ambr +291 -0
- komichi-1.0.1/tests/golden/test_render_profile.py +182 -0
- komichi-1.0.1/tests/unit/adapters/test_model.py +127 -0
- komichi-1.0.1/tests/unit/bench/test_runner.py +265 -0
- komichi-1.0.1/tests/unit/bench/test_significance.py +163 -0
- komichi-1.0.1/tests/unit/cli/test_app.py +36 -0
- komichi-1.0.1/tests/unit/cli/test_bench_report_cmd.py +288 -0
- komichi-1.0.1/tests/unit/cli/test_clean_cmd.py +241 -0
- komichi-1.0.1/tests/unit/cli/test_error_messages.py +113 -0
- komichi-1.0.1/tests/unit/cli/test_eval_cmd.py +296 -0
- komichi-1.0.1/tests/unit/cli/test_inspect_cmd.py +138 -0
- komichi-1.0.1/tests/unit/cli/test_project_defaults.py +243 -0
- komichi-1.0.1/tests/unit/console/test_console.py +310 -0
- komichi-1.0.1/tests/unit/core/test_artifacts.py +210 -0
- komichi-1.0.1/tests/unit/core/test_errors.py +40 -0
- komichi-1.0.1/tests/unit/core/test_io.py +142 -0
- komichi-1.0.1/tests/unit/evaluation/test_bootstrap.py +140 -0
- komichi-1.0.1/tests/unit/evaluation/test_checks.py +172 -0
- komichi-1.0.1/tests/unit/evaluation/test_evaluator.py +221 -0
- komichi-1.0.1/tests/unit/inspection/test_findings.py +191 -0
- komichi-1.0.1/tests/unit/inspection/test_profiler.py +143 -0
- komichi-1.0.1/tests/unit/plugins/test_plugins.py +291 -0
- komichi-1.0.1/tests/unit/recipes/test_recipes.py +350 -0
- komichi-1.0.1/tests/unit/sweep/test_sweep.py +262 -0
- komichi-1.0.1/tests/unit/test_explain.py +69 -0
- komichi-1.0.1/tests/unit/ui/test_ui.py +143 -0
- komichi-1.0.1/uv.lock +2613 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
checks:
|
|
10
|
+
name: ${{ matrix.os }} / py${{ matrix.python }}
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
python: ["3.11", "3.13"]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: astral-sh/setup-uv@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python }}
|
|
23
|
+
|
|
24
|
+
- name: Install
|
|
25
|
+
run: uv sync --extra dev --extra ui
|
|
26
|
+
|
|
27
|
+
- name: Lint
|
|
28
|
+
run: uv run ruff check .
|
|
29
|
+
|
|
30
|
+
- name: Format
|
|
31
|
+
run: uv run ruff format --check .
|
|
32
|
+
|
|
33
|
+
- name: Types
|
|
34
|
+
run: uv run mypy src/michi
|
|
35
|
+
|
|
36
|
+
- name: Tests
|
|
37
|
+
run: uv run pytest
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when a version tag is pushed.
|
|
4
|
+
#
|
|
5
|
+
# Uses trusted publishing (OpenID Connect): there is no API token stored in
|
|
6
|
+
# this repository, and nothing to leak or rotate. PyPI is configured to trust
|
|
7
|
+
# this exact workflow file in this exact repository.
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
tags: ["v*"]
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
# The gates run again against the tagged commit. A release that skips them
|
|
19
|
+
# because "CI already passed on main" is how a broken artifact reaches PyPI.
|
|
20
|
+
verify:
|
|
21
|
+
name: verify ${{ matrix.os }}
|
|
22
|
+
runs-on: ${{ matrix.os }}
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: true
|
|
25
|
+
matrix:
|
|
26
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- uses: astral-sh/setup-uv@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.11"
|
|
32
|
+
- run: uv sync --extra dev --extra ui
|
|
33
|
+
- run: uv run ruff check .
|
|
34
|
+
- run: uv run ruff format --check .
|
|
35
|
+
- run: uv run mypy src/michi
|
|
36
|
+
- run: uv run pytest
|
|
37
|
+
|
|
38
|
+
build:
|
|
39
|
+
name: build distributions
|
|
40
|
+
needs: verify
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- uses: astral-sh/setup-uv@v5
|
|
45
|
+
with:
|
|
46
|
+
python-version: "3.11"
|
|
47
|
+
|
|
48
|
+
- name: Check the tag matches the package version
|
|
49
|
+
shell: bash
|
|
50
|
+
run: |
|
|
51
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
52
|
+
version=$(grep -m1 '^version = ' pyproject.toml | cut -d'"' -f2)
|
|
53
|
+
if [ "$tag" != "$version" ]; then
|
|
54
|
+
echo "tag $tag does not match pyproject version $version" >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
- run: uv build
|
|
59
|
+
|
|
60
|
+
- name: Verify the built distributions
|
|
61
|
+
run: uvx twine check dist/*
|
|
62
|
+
|
|
63
|
+
- uses: actions/upload-artifact@v4
|
|
64
|
+
with:
|
|
65
|
+
name: distributions
|
|
66
|
+
path: dist/
|
|
67
|
+
|
|
68
|
+
publish:
|
|
69
|
+
name: publish to PyPI
|
|
70
|
+
needs: build
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
environment:
|
|
73
|
+
name: pypi
|
|
74
|
+
url: https://pypi.org/p/komichi
|
|
75
|
+
permissions:
|
|
76
|
+
id-token: write # required for trusted publishing
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/download-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: distributions
|
|
81
|
+
path: dist/
|
|
82
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
komichi-1.0.1/.gitignore
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
|
|
8
|
+
# Environments
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
|
|
12
|
+
# Tooling caches
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.ruff_cache/
|
|
16
|
+
.hypothesis/
|
|
17
|
+
.coverage
|
|
18
|
+
htmlcov/
|
|
19
|
+
|
|
20
|
+
# Docs build
|
|
21
|
+
site/
|
|
22
|
+
|
|
23
|
+
# Michi runtime outputs produced while developing
|
|
24
|
+
runs/
|
|
25
|
+
|
|
26
|
+
# OS noise
|
|
27
|
+
.DS_Store
|
|
28
|
+
Thumbs.db
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to michi are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [1.0.1] — 2026-07-27
|
|
10
|
+
|
|
11
|
+
Fixes found by using the built package the way a stranger would.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **`michi.toml` now reaches every command**, not only the console. The
|
|
15
|
+
documented precedence — flags > `michi.toml` > built-in — was previously
|
|
16
|
+
true only inside the console, which made the documentation wrong for every
|
|
17
|
+
shell user. `michi inspect`, `bench`, `clean`, and `report` now run with no
|
|
18
|
+
arguments in a configured project.
|
|
19
|
+
- **`--recipe` on `eval`**, which the documentation had promised. Only the
|
|
20
|
+
recipe's deterministic steps run: imputers in a recipe were fitted for
|
|
21
|
+
training, and re-fitting them on the evaluation set would quietly change
|
|
22
|
+
what is being measured.
|
|
23
|
+
- A PyPI publishing workflow using trusted publishing, which re-runs every
|
|
24
|
+
gate against the tagged commit and refuses to publish if the tag and the
|
|
25
|
+
package version disagree.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- The distribution is **`komichi`** on PyPI, because `michi` was already
|
|
29
|
+
taken. The command and the import are both still `michi`.
|
|
30
|
+
- A *configured* target is a hint, not a command: running against data that
|
|
31
|
+
lacks it prints a note and continues, rather than failing a run the user did
|
|
32
|
+
not misconfigure. A typed `--target` that is missing still fails loudly.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- Error messages naming an extra were rendered as terminal markup, so
|
|
36
|
+
`pip install 'komichi[bench]'` reached users as `pip install 'komichi'` —
|
|
37
|
+
an install command that silently does the wrong thing. Messages are now
|
|
38
|
+
rendered verbatim, and a test asserts the brackets survive.
|
|
39
|
+
- The install command is built from one constant, and a test fails if any
|
|
40
|
+
message hardcodes the package name — which immediately caught a stale hint
|
|
41
|
+
in the Excel loader.
|
|
42
|
+
- **A skipped analysis is now a finding.** Above 200 columns michi caps its
|
|
43
|
+
pairwise checks; it used to skip them in silence, so a user could conclude
|
|
44
|
+
there were no duplicate columns when michi had never looked. Silence reads
|
|
45
|
+
as "nothing found", which is a different claim from "not looked at".
|
|
46
|
+
- **`michi eval` was unusably slow on large data.** The default bootstrap on
|
|
47
|
+
400,000 rows would have taken about three and a half minutes. Resamples are
|
|
48
|
+
now shared across metrics instead of being redrawn identically for each,
|
|
49
|
+
and very large draws are capped and rescaled — an 8× speed-up.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- The distribution is **`komichi`** on PyPI (小道, *a small path*), because
|
|
53
|
+
`michi` was taken. The command and the import remain `michi`.
|
|
54
|
+
- Large-sample intervals use the *m-out-of-n* bootstrap correction. Capping
|
|
55
|
+
the draw without rescaling reported intervals nearly **three times too
|
|
56
|
+
wide**; overstating uncertainty is no more honest than understating it.
|
|
57
|
+
|
|
58
|
+
## [1.0.0] — 2026-07-27
|
|
59
|
+
|
|
60
|
+
The public surface is frozen.
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
- **A quickstart** taking one messy CSV to a compared, reported model in
|
|
64
|
+
fifteen minutes — the page that decides whether michi is worth adopting.
|
|
65
|
+
- **[ADR-0002](docs/adr/0002-freeze-the-public-surface.md)** records exactly
|
|
66
|
+
what is now public API under semantic versioning: the profile, run manifest,
|
|
67
|
+
and recipe schemas (all 1.0); the verb names, flags, and exit codes; the
|
|
68
|
+
plugin entry-point groups and contract; and each package's `__all__`.
|
|
69
|
+
Terminal layout, report styling, explanation prose, and finding thresholds
|
|
70
|
+
are deliberately *not* frozen.
|
|
71
|
+
- **Schema-stability tests** that read committed 1.0 fixtures of all three
|
|
72
|
+
artifact types on every CI run, execute every frozen recipe operation, and
|
|
73
|
+
compile a 1.0 recipe to code. A promise nobody tests is a hope.
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
- A recipe step's `why` — the reason a column was dropped — was written as a
|
|
77
|
+
YAML comment and silently lost on reload. It is now a field and round-trips.
|
|
78
|
+
That reason is exactly the part nobody can reconstruct six months later, and
|
|
79
|
+
the freeze tests are what caught it.
|
|
80
|
+
|
|
81
|
+
### Notes
|
|
82
|
+
- The freeze is what makes the toolbox claim real: a verb adopted today
|
|
83
|
+
behaves the same next year, which is the only basis on which anyone puts
|
|
84
|
+
michi in a pipeline.
|
|
85
|
+
- Everything on the roadmap has now shipped: `inspect`, `eval`, `bench`,
|
|
86
|
+
`report`, `clean`/`apply`/`export`, the console, `sweep`, `ui`, and plugins.
|
|
87
|
+
|
|
88
|
+
## [0.8.0] — 2026-07-27
|
|
89
|
+
|
|
90
|
+
The plugin surface.
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
- **Two extension points**, discovered via entry points:
|
|
94
|
+
`michi.models` adds algorithms to the `bench` catalogue, and
|
|
95
|
+
`michi.adapters` adds ways to load a model for `eval` — which is where an
|
|
96
|
+
ONNX or framework loader belongs, since michi deliberately ships none.
|
|
97
|
+
- **`michi plugins`** lists what is installed, working or not.
|
|
98
|
+
- **A published compatibility suite** (`michi.plugins.check_model_entry`,
|
|
99
|
+
`check_adapter`) that plugin authors run in their own CI. michi's maintainer
|
|
100
|
+
is not the integration point for every plugin — that is the only way an
|
|
101
|
+
ecosystem stays affordable for one person to support.
|
|
102
|
+
- `CONTRIBUTING.md` and a plugin guide.
|
|
103
|
+
|
|
104
|
+
### Notes
|
|
105
|
+
- These points were opened at v0.8, not before, because the interfaces behind
|
|
106
|
+
them had by then survived six milestones and a dozen concrete
|
|
107
|
+
implementations without changing shape. An interface with one implementation
|
|
108
|
+
is a guess, and a published interface is a promise.
|
|
109
|
+
- **A broken plugin is skipped, never fatal**: an entry point that fails to
|
|
110
|
+
import is reported by `michi plugins` and ignored, and benchmarks keep
|
|
111
|
+
running.
|
|
112
|
+
- **Built-ins win ties.** A plugin cannot shadow `rf` or any documented name,
|
|
113
|
+
so `--list-models` always means what the documentation says.
|
|
114
|
+
- Recipe operations, report sections, and metric definitions remain closed.
|
|
115
|
+
They stay closed until something real needs them.
|
|
116
|
+
|
|
117
|
+
## [0.7.0] — 2026-07-27
|
|
118
|
+
|
|
119
|
+
A local viewer: `michi ui`.
|
|
120
|
+
|
|
121
|
+
### Added
|
|
122
|
+
- **`michi ui`** (needs `michi[ui]`) — a read-only web view over the runs
|
|
123
|
+
directory: every run grouped by dataset and target, and a detail page per
|
|
124
|
+
run with metrics beside their baselines, checks, slices, and full
|
|
125
|
+
provenance.
|
|
126
|
+
- Serves on **localhost only**, with no flag to change that.
|
|
127
|
+
|
|
128
|
+
### Notes
|
|
129
|
+
- The viewer is **read-only by construction**: a test asserts the application
|
|
130
|
+
exposes only `GET`. A UI that can act is a platform, and michi is not one.
|
|
131
|
+
- **No database, no build step, no network.** Every request reads the
|
|
132
|
+
directory, so a run appears on refresh; pages are server-rendered HTML with
|
|
133
|
+
inline CSS, so the viewer works air-gapped and cannot rot when a frontend
|
|
134
|
+
toolchain moves on.
|
|
135
|
+
- **It is deletable.** Removing it would remove convenience and not one
|
|
136
|
+
capability — everything it shows is a file, and `michi report` renders the
|
|
137
|
+
same artifacts. That is the bar it has to keep clearing.
|
|
138
|
+
|
|
139
|
+
## [0.6.0] — 2026-07-27
|
|
140
|
+
|
|
141
|
+
Experiment grids: `michi sweep`.
|
|
142
|
+
|
|
143
|
+
### Added
|
|
144
|
+
- **`michi sweep`** — executes a declarative grid of models × recipes × seeds
|
|
145
|
+
from a YAML plan, recording one run manifest per cell. Progress is printed
|
|
146
|
+
as it goes, and `--dry-run` lists the grid without running anything.
|
|
147
|
+
- **Content-hash caching and resumption.** Each cell's identity is a hash of
|
|
148
|
+
the data, recipe, model, seed, and fold count that produce it, so an
|
|
149
|
+
interrupted sweep resumes exactly where it stopped, and editing one recipe
|
|
150
|
+
re-runs exactly the cells that use it. A long sweep *will* be interrupted;
|
|
151
|
+
resumption is not a nicety.
|
|
152
|
+
- **Contained failure**: a cell that cannot train is recorded and the grid
|
|
153
|
+
continues, because losing thirty completed cells to the thirty-first would
|
|
154
|
+
be indefensible.
|
|
155
|
+
- **`--recipe` support in `bench`** — a recipe's deterministic steps run once
|
|
156
|
+
up front; its fitted steps become a transformer fitted inside each fold, so
|
|
157
|
+
comparing preprocessing strategies stays leak-free. A recipe the user wrote
|
|
158
|
+
takes precedence over michi's default preparation.
|
|
159
|
+
- Sweep manifests feed straight into `michi report`.
|
|
160
|
+
- Documentation for `sweep`.
|
|
161
|
+
|
|
162
|
+
## [0.5.0] — 2026-07-27
|
|
163
|
+
|
|
164
|
+
The console: `michi` with no arguments.
|
|
165
|
+
|
|
166
|
+
### Added
|
|
167
|
+
- **An interactive console** with the context always visible in the prompt
|
|
168
|
+
(`michi (train.csv → churned) ›`), `help`, `use`, `set`, `unset`, and
|
|
169
|
+
`show [context|columns|models|runs]`.
|
|
170
|
+
- **Tab completion over your own data** — once a dataset is loaded, `set
|
|
171
|
+
target <TAB>` completes that file's column names. This is the one thing a
|
|
172
|
+
one-shot CLI can never do, and the reason the console exists.
|
|
173
|
+
- **`history --export`** writes the session as a replayable shell script of
|
|
174
|
+
fully-expanded one-shot commands. Console-only commands never appear, so
|
|
175
|
+
exploration stays reproducible.
|
|
176
|
+
- **`michi.toml`** — optional project defaults, found by searching upward from
|
|
177
|
+
the working directory. Precedence is flags > `michi.toml` > built-in, and
|
|
178
|
+
`michi info` prints which file was found and what it supplies. This is
|
|
179
|
+
michi's answer to session state: if it is remembered, it is a file you can
|
|
180
|
+
read, edit, diff, and commit.
|
|
181
|
+
- The console's context *is* the `michi.toml` model, so `save` persists it and
|
|
182
|
+
a later session restores it.
|
|
183
|
+
|
|
184
|
+
### Fixed
|
|
185
|
+
- Console line splitting treated a backslash as an escape character, which
|
|
186
|
+
silently mangled every Windows path a user typed. Backslashes are now
|
|
187
|
+
literal; quoting still groups arguments containing spaces.
|
|
188
|
+
|
|
189
|
+
### Notes
|
|
190
|
+
- The console contains **zero logic**: every verb dispatches to the same Typer
|
|
191
|
+
application the shell invokes, and a test asserts no console verb exists
|
|
192
|
+
outside the CLI. Deleting the console would remove convenience, never
|
|
193
|
+
capability.
|
|
194
|
+
- Bare `michi` prints help rather than opening a prompt when stdout is not a
|
|
195
|
+
terminal, so scripts never hang.
|
|
196
|
+
|
|
197
|
+
## [0.4.0] — 2026-07-26
|
|
198
|
+
|
|
199
|
+
Cleaning decisions as a file you own: `michi clean`, `apply`, and `export`.
|
|
200
|
+
|
|
201
|
+
### Added
|
|
202
|
+
- **`michi clean`** — authors a **recipe**: an ordered list of declarative
|
|
203
|
+
cleaning operations plus the schema they were written against. Your data is
|
|
204
|
+
never touched. The interactive mode walks the *findings* `inspect` produced,
|
|
205
|
+
grouped, so a two-hundred-column dataset yields a handful of questions
|
|
206
|
+
rather than two hundred prompts — and "leave them as they are" is always
|
|
207
|
+
present and always the default.
|
|
208
|
+
- **Full flag parity**: `--drop`, `--dedupe`, `--cast`, `--impute`, `--clip`,
|
|
209
|
+
`--encode`, `--scale` express everything the wizard can, and every session
|
|
210
|
+
prints the non-interactive command that reproduces it.
|
|
211
|
+
- **`michi apply`** — executes a recipe non-destructively to a new file. The
|
|
212
|
+
recipe's schema snapshot acts as a data contract: applying it to data that
|
|
213
|
+
lacks the named columns fails loudly, with `--no-strict` to degrade
|
|
214
|
+
gracefully.
|
|
215
|
+
- **`michi export`** — compiles a recipe into a standalone Python module that
|
|
216
|
+
imports pandas and scikit-learn, never michi. Deterministic steps become a
|
|
217
|
+
`prepare()` function; fitted steps become an sklearn transformer to fit
|
|
218
|
+
inside cross-validation. Generated code passes ruff check and format, and a
|
|
219
|
+
test executes it and asserts it matches `michi apply`.
|
|
220
|
+
- **Recipe artifact** (schema 1.0) written as commented YAML through a
|
|
221
|
+
template — `yaml.dump` cannot produce a comment, and the comments carry the
|
|
222
|
+
reason each decision was made.
|
|
223
|
+
- Honest leakage reporting: steps that learn from data are marked as such,
|
|
224
|
+
`apply` says when it fitted them on a whole file, and the caveat is written
|
|
225
|
+
into the recipe itself.
|
|
226
|
+
- Documentation for `clean`, `apply`, and `export`.
|
|
227
|
+
|
|
228
|
+
## [0.3.0] — 2026-07-26
|
|
229
|
+
|
|
230
|
+
Honest model comparison: `michi bench` and `michi report`. This completes the
|
|
231
|
+
MVP — inspect, evaluate, compare, report.
|
|
232
|
+
|
|
233
|
+
### Added
|
|
234
|
+
- **`michi bench`** — cross-validates several models and reports which of them
|
|
235
|
+
are actually distinguishable. A dummy baseline is always added; differences
|
|
236
|
+
from the leader are tested with the **corrected resampled *t*-test**
|
|
237
|
+
(Nadeau & Bengio, 2003) and Holm-adjusted across models, and the conclusion
|
|
238
|
+
is stated in plain language ("tied with leader at this sample size").
|
|
239
|
+
- **A model catalogue** (`--list-models`) of 14 algorithms: `dummy`, `linear`,
|
|
240
|
+
`ridge`, `lasso`, `tree`, `rf`, `extra-trees`, `hist-gbm`, `knn`, `svm`,
|
|
241
|
+
`naive-bayes` in the base install, plus `xgb`, `lgbm`, `catboost` behind the
|
|
242
|
+
`bench` extra. Everything trains locally; nothing is downloaded.
|
|
243
|
+
- **Stated column preparation**, printed every run and recorded in every
|
|
244
|
+
manifest, and fitted *inside each fold* so a benchmark cannot leak.
|
|
245
|
+
Overridable with `--impute`, `--encode`, `--no-scale`.
|
|
246
|
+
- **`michi report`** — renders recorded runs as a self-contained offline HTML
|
|
247
|
+
page, Markdown for a pull request, or a paste-ready booktabs LaTeX table for
|
|
248
|
+
a paper. Runs are grouped by dataset content hash and target, so
|
|
249
|
+
incomparable numbers are never put in one table.
|
|
250
|
+
- Benchmark checks: `below-baseline`, `no-clear-winner`, `model-failed`.
|
|
251
|
+
- Documentation for `bench` and `report`.
|
|
252
|
+
|
|
253
|
+
### Changed
|
|
254
|
+
- Unknown or task-incompatible model names now fail immediately, before any
|
|
255
|
+
training, rather than appearing as a failed row in the leaderboard.
|
|
256
|
+
|
|
257
|
+
### Fixed
|
|
258
|
+
- The corrected *t*-test returned "not significant" when two models differed
|
|
259
|
+
by exactly the same amount on every fold. A zero-variance difference is the
|
|
260
|
+
strongest possible evidence, not the weakest; the limit is now p = 0.
|
|
261
|
+
|
|
262
|
+
## [0.2.0] — 2026-07-26
|
|
263
|
+
|
|
264
|
+
Evaluate models michi never saw trained: `michi eval`.
|
|
265
|
+
|
|
266
|
+
### Added
|
|
267
|
+
- **`michi eval`** — evaluate an existing model against a dataset. Reports
|
|
268
|
+
metrics with 95% bootstrap confidence intervals, always beside trivial
|
|
269
|
+
baselines, plus a confusion matrix, per-slice scores, and a calibration
|
|
270
|
+
curve.
|
|
271
|
+
- **Two ways to supply a model**: sklearn-compatible pickle/joblib files, or
|
|
272
|
+
*any* object exposing `predict(X)` via a `mymodule:my_model` reference —
|
|
273
|
+
which covers PyTorch, TensorFlow, ONNX, and bespoke models without michi
|
|
274
|
+
shipping a loader per framework. Formats that cannot be loaded honestly are
|
|
275
|
+
refused with a route forward rather than a confusing failure.
|
|
276
|
+
- **Eight evaluation checks**: `below-baseline`, `beats-baseline`,
|
|
277
|
+
`suspiciously-perfect`, `single-class-predictions`, `wide-interval`,
|
|
278
|
+
`miscalibrated`, `slice-gap`, and `small-evaluation-set` — each with an
|
|
279
|
+
explanation and options, never a recommendation.
|
|
280
|
+
- **Run manifests** (schema 1.0) written to `runs/` by default: dataset and
|
|
281
|
+
model hashes, seed, metrics, baselines, checks, and the environment,
|
|
282
|
+
making any number traceable to the conditions that produced it.
|
|
283
|
+
- **CI gate**: `--fail-under metric=value`, respecting each metric's
|
|
284
|
+
direction so `rmse=3.0` passes when RMSE is at most 3.0.
|
|
285
|
+
- Automatic task detection (classification or regression), overridable with
|
|
286
|
+
`--task`.
|
|
287
|
+
- Documentation for `eval`, including the predict protocol.
|
|
288
|
+
|
|
289
|
+
### Changed
|
|
290
|
+
- sklearn's internal warnings are suppressed during evaluation; michi reports
|
|
291
|
+
the same conditions itself, as checks, in language a user can act on.
|
|
292
|
+
|
|
293
|
+
## [0.1.0] — 2026-07-26
|
|
294
|
+
|
|
295
|
+
The first working verb: `michi inspect`.
|
|
296
|
+
|
|
297
|
+
### Added
|
|
298
|
+
- **`michi inspect`** — profile any CSV, TSV, or Parquet file (Excel via the
|
|
299
|
+
`michi[excel]` extra). Reports column kinds, missing values, duplicates,
|
|
300
|
+
cardinality, distribution shape, and outliers, with findings ranked by
|
|
301
|
+
severity.
|
|
302
|
+
- **Fifteen finding detectors**, including empty and constant columns,
|
|
303
|
+
identifier-like and high-cardinality columns, skew, outliers, duplicate and
|
|
304
|
+
near-perfectly-correlated columns, numbers and dates stored as text, mixed
|
|
305
|
+
types, and — when `--target` is given — class imbalance and target-leakage
|
|
306
|
+
suspects.
|
|
307
|
+
- **Explanations** (`--explain`) attached to every finding: what it means and
|
|
308
|
+
which options practitioners choose between, never a recommendation.
|
|
309
|
+
Explanation text lives in reviewable content files.
|
|
310
|
+
- **Three output surfaces**: a rich terminal report, a self-contained offline
|
|
311
|
+
HTML report (`--html`, no CDN or JavaScript), and the versioned profile
|
|
312
|
+
artifact as JSON (`--json`).
|
|
313
|
+
- **Honest sampling** for large files: seeded random sampling above 256 MB,
|
|
314
|
+
always recorded in the artifact and the report, with `--full` to override.
|
|
315
|
+
- **CI gate mode**: `--fail-on high|warn|info` with meaningful exit codes.
|
|
316
|
+
- Artifact foundations: immutable, versioned value objects (profile schema
|
|
317
|
+
1.0), SHA-256 content hashing, and the tabular io layer.
|
|
318
|
+
- Documentation for `inspect`, plus committed example artifacts in
|
|
319
|
+
`examples/`.
|
|
320
|
+
|
|
321
|
+
### Notes
|
|
322
|
+
- Profile schema is versioned but not yet frozen; it comes under semantic
|
|
323
|
+
versioning at 1.0.
|
|
324
|
+
|
|
325
|
+
## [0.0.1] — 2026-07-26
|
|
326
|
+
|
|
327
|
+
### Added
|
|
328
|
+
- Project skeleton: packaging, CI, module layout, error hierarchy, CLI entry
|
|
329
|
+
point (`michi --version`, `michi info`), philosophy and roadmap
|
|
330
|
+
documentation, ADR-0001.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Contributing to michi
|
|
2
|
+
|
|
3
|
+
Thank you for looking. This file exists so that "no" is a citation rather than
|
|
4
|
+
an argument, and so that a yes is easy.
|
|
5
|
+
|
|
6
|
+
## Before you start
|
|
7
|
+
|
|
8
|
+
Read the [philosophy](docs/philosophy.md). michi is a **toolbox, not a
|
|
9
|
+
workflow**, and it **automates implementation, never judgement**. A pull
|
|
10
|
+
request that conflicts with either is declined regardless of how good the code
|
|
11
|
+
is — that is not a comment on the work, only on the fit.
|
|
12
|
+
|
|
13
|
+
In particular, michi will never gain: AutoML or automatic model selection, a
|
|
14
|
+
required project structure, a training-loop wrapper, cloud features, accounts,
|
|
15
|
+
telemetry, serving, monitoring, DAG orchestration, or hidden session state.
|
|
16
|
+
|
|
17
|
+
## What is most welcome
|
|
18
|
+
|
|
19
|
+
- **Bug reports with a dataset shape that reproduces them.** Tiny CSVs are
|
|
20
|
+
perfect.
|
|
21
|
+
- **Findings and checks michi should raise but does not** — with a sentence on
|
|
22
|
+
what the finding means and what options a practitioner has.
|
|
23
|
+
- **Corrections to explanation content** in `src/michi/explain/content/`. This
|
|
24
|
+
is prose, reviewed like documentation, and accuracy matters more than
|
|
25
|
+
anything else in the repository.
|
|
26
|
+
- **Cross-platform fixes.** Windows is first-class; if something is awkward
|
|
27
|
+
there, that is a bug.
|
|
28
|
+
- **Plugins.** See [the plugin guide](docs/plugins.md) — new model families and
|
|
29
|
+
loaders belong in your package, not michi's.
|
|
30
|
+
|
|
31
|
+
## Working on it
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv sync --extra dev --extra ui
|
|
35
|
+
uv run ruff check . && uv run ruff format --check .
|
|
36
|
+
uv run mypy src/michi
|
|
37
|
+
uv run pytest
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
All four must pass. CI runs them on Linux, macOS, and Windows against Python
|
|
41
|
+
3.11 and 3.13.
|
|
42
|
+
|
|
43
|
+
## House rules
|
|
44
|
+
|
|
45
|
+
- **One slice per pull request**: a verb, a finding, a fix. Tests and
|
|
46
|
+
documentation land with the change, not after it.
|
|
47
|
+
- **Concrete before abstract.** An interface needs two real implementations
|
|
48
|
+
before it exists. Cite them in the description.
|
|
49
|
+
- **New dependencies need a reason** in the pull request; new *core*
|
|
50
|
+
dependencies need an ADR in `docs/adr/`.
|
|
51
|
+
- **Tests assert behaviour, never exact floats**: shapes, invariants, "beats
|
|
52
|
+
the dummy baseline", "is not called significant". A test that pins a number
|
|
53
|
+
breaks on the next sklearn release and teaches nobody anything.
|
|
54
|
+
- **Every module docstring states what the module deliberately does not do.**
|
|
55
|
+
That sentence is often the most useful one in the file.
|
|
56
|
+
- **Error messages are actionable**: name the exact command to run next.
|
|
57
|
+
|
|
58
|
+
## Style
|
|
59
|
+
|
|
60
|
+
Python 3.11+, `from __future__ import annotations`, full type hints, mypy
|
|
61
|
+
strict, ruff for lint and formatting, line length 88. Frozen dataclasses for
|
|
62
|
+
value objects. Errors raised from the `MichiError` hierarchy at public
|
|
63
|
+
boundaries, with third-party failures wrapped and chained.
|
|
64
|
+
|
|
65
|
+
Comments explain *why*, not *what*. If a threshold is arbitrary, say so and
|
|
66
|
+
say what it trades off.
|
|
67
|
+
|
|
68
|
+
## Reviews
|
|
69
|
+
|
|
70
|
+
Reviews are about the code and the fit, never the person. A "no" on scope is
|
|
71
|
+
not a judgement of quality — michi says no to most things on purpose, and that
|
|
72
|
+
is what keeps it maintainable by a small number of people for a long time.
|
komichi-1.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 K Satya Sai Nischal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|