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.
Files changed (146) hide show
  1. komichi-1.0.1/.github/workflows/ci.yml +37 -0
  2. komichi-1.0.1/.github/workflows/publish.yml +82 -0
  3. komichi-1.0.1/.gitignore +28 -0
  4. komichi-1.0.1/CHANGELOG.md +330 -0
  5. komichi-1.0.1/CONTRIBUTING.md +72 -0
  6. komichi-1.0.1/LICENSE +21 -0
  7. komichi-1.0.1/PKG-INFO +304 -0
  8. komichi-1.0.1/README.md +243 -0
  9. komichi-1.0.1/docs/adr/0001-toolbox-not-workflow.md +40 -0
  10. komichi-1.0.1/docs/adr/0002-freeze-the-public-surface.md +59 -0
  11. komichi-1.0.1/docs/adr/README.md +13 -0
  12. komichi-1.0.1/docs/bench.md +149 -0
  13. komichi-1.0.1/docs/clean.md +200 -0
  14. komichi-1.0.1/docs/console.md +148 -0
  15. komichi-1.0.1/docs/eval.md +179 -0
  16. komichi-1.0.1/docs/index.md +32 -0
  17. komichi-1.0.1/docs/inspect.md +110 -0
  18. komichi-1.0.1/docs/philosophy.md +61 -0
  19. komichi-1.0.1/docs/plugins.md +136 -0
  20. komichi-1.0.1/docs/quickstart.md +176 -0
  21. komichi-1.0.1/docs/report.md +73 -0
  22. komichi-1.0.1/docs/roadmap.md +35 -0
  23. komichi-1.0.1/docs/sweep.md +90 -0
  24. komichi-1.0.1/docs/ui.md +46 -0
  25. komichi-1.0.1/examples/README.md +39 -0
  26. komichi-1.0.1/examples/benchmark.html +167 -0
  27. komichi-1.0.1/examples/pipeline.py +91 -0
  28. komichi-1.0.1/examples/profile.html +395 -0
  29. komichi-1.0.1/examples/profile.json +1126 -0
  30. komichi-1.0.1/examples/recipe.yaml +54 -0
  31. komichi-1.0.1/examples/sweep.yaml +14 -0
  32. komichi-1.0.1/mkdocs.yml +33 -0
  33. komichi-1.0.1/pyproject.toml +124 -0
  34. komichi-1.0.1/src/michi/__init__.py +19 -0
  35. komichi-1.0.1/src/michi/adapters/README.md +13 -0
  36. komichi-1.0.1/src/michi/adapters/__init__.py +17 -0
  37. komichi-1.0.1/src/michi/adapters/model.py +323 -0
  38. komichi-1.0.1/src/michi/bench/README.md +12 -0
  39. komichi-1.0.1/src/michi/bench/__init__.py +33 -0
  40. komichi-1.0.1/src/michi/bench/preprocess.py +145 -0
  41. komichi-1.0.1/src/michi/bench/registry.py +412 -0
  42. komichi-1.0.1/src/michi/bench/runner.py +554 -0
  43. komichi-1.0.1/src/michi/bench/significance.py +223 -0
  44. komichi-1.0.1/src/michi/cli/__init__.py +12 -0
  45. komichi-1.0.1/src/michi/cli/app.py +153 -0
  46. komichi-1.0.1/src/michi/cli/bench_cmd.py +226 -0
  47. komichi-1.0.1/src/michi/cli/clean_cmd.py +402 -0
  48. komichi-1.0.1/src/michi/cli/context.py +117 -0
  49. komichi-1.0.1/src/michi/cli/errors.py +28 -0
  50. komichi-1.0.1/src/michi/cli/eval_cmd.py +266 -0
  51. komichi-1.0.1/src/michi/cli/inspect_cmd.py +170 -0
  52. komichi-1.0.1/src/michi/cli/report_cmd.py +103 -0
  53. komichi-1.0.1/src/michi/cli/sweep_cmd.py +152 -0
  54. komichi-1.0.1/src/michi/cli/ui_cmd.py +67 -0
  55. komichi-1.0.1/src/michi/console/__init__.py +38 -0
  56. komichi-1.0.1/src/michi/console/commands.py +467 -0
  57. komichi-1.0.1/src/michi/console/session.py +139 -0
  58. komichi-1.0.1/src/michi/console/shell.py +180 -0
  59. komichi-1.0.1/src/michi/core/__init__.py +59 -0
  60. komichi-1.0.1/src/michi/core/artifacts.py +411 -0
  61. komichi-1.0.1/src/michi/core/config.py +166 -0
  62. komichi-1.0.1/src/michi/core/errors.py +90 -0
  63. komichi-1.0.1/src/michi/core/hashing.py +64 -0
  64. komichi-1.0.1/src/michi/core/io.py +281 -0
  65. komichi-1.0.1/src/michi/core/manifest.py +364 -0
  66. komichi-1.0.1/src/michi/evaluation/README.md +11 -0
  67. komichi-1.0.1/src/michi/evaluation/__init__.py +38 -0
  68. komichi-1.0.1/src/michi/evaluation/checks.py +260 -0
  69. komichi-1.0.1/src/michi/evaluation/evaluator.py +488 -0
  70. komichi-1.0.1/src/michi/evaluation/metrics.py +402 -0
  71. komichi-1.0.1/src/michi/explain/README.md +12 -0
  72. komichi-1.0.1/src/michi/explain/__init__.py +18 -0
  73. komichi-1.0.1/src/michi/explain/content/README.md +6 -0
  74. komichi-1.0.1/src/michi/explain/content/findings.yaml +384 -0
  75. komichi-1.0.1/src/michi/explain/registry.py +81 -0
  76. komichi-1.0.1/src/michi/inspection/README.md +12 -0
  77. komichi-1.0.1/src/michi/inspection/__init__.py +25 -0
  78. komichi-1.0.1/src/michi/inspection/findings.py +652 -0
  79. komichi-1.0.1/src/michi/inspection/profiler.py +304 -0
  80. komichi-1.0.1/src/michi/plugins/__init__.py +40 -0
  81. komichi-1.0.1/src/michi/plugins/compat.py +138 -0
  82. komichi-1.0.1/src/michi/plugins/registry.py +127 -0
  83. komichi-1.0.1/src/michi/py.typed +0 -0
  84. komichi-1.0.1/src/michi/recipes/README.md +11 -0
  85. komichi-1.0.1/src/michi/recipes/__init__.py +58 -0
  86. komichi-1.0.1/src/michi/recipes/apply.py +321 -0
  87. komichi-1.0.1/src/michi/recipes/author.py +634 -0
  88. komichi-1.0.1/src/michi/recipes/export.py +303 -0
  89. komichi-1.0.1/src/michi/recipes/model.py +235 -0
  90. komichi-1.0.1/src/michi/recipes/pipeline.py +126 -0
  91. komichi-1.0.1/src/michi/recipes/serialise.py +171 -0
  92. komichi-1.0.1/src/michi/report/README.md +9 -0
  93. komichi-1.0.1/src/michi/report/__init__.py +51 -0
  94. komichi-1.0.1/src/michi/report/comparison.py +330 -0
  95. komichi-1.0.1/src/michi/report/html.py +193 -0
  96. komichi-1.0.1/src/michi/report/runs.py +130 -0
  97. komichi-1.0.1/src/michi/report/templates/_ui_base.html.jinja +70 -0
  98. komichi-1.0.1/src/michi/report/templates/benchmark.html.jinja +159 -0
  99. komichi-1.0.1/src/michi/report/templates/profile.html.jinja +163 -0
  100. komichi-1.0.1/src/michi/report/templates/runs.html.jinja +101 -0
  101. komichi-1.0.1/src/michi/report/templates/ui_index.html.jinja +41 -0
  102. komichi-1.0.1/src/michi/report/templates/ui_missing.html.jinja +9 -0
  103. komichi-1.0.1/src/michi/report/templates/ui_run.html.jinja +74 -0
  104. komichi-1.0.1/src/michi/report/terminal.py +754 -0
  105. komichi-1.0.1/src/michi/sweep/README.md +10 -0
  106. komichi-1.0.1/src/michi/sweep/__init__.py +28 -0
  107. komichi-1.0.1/src/michi/sweep/plan.py +193 -0
  108. komichi-1.0.1/src/michi/sweep/runner.py +256 -0
  109. komichi-1.0.1/src/michi/ui/__init__.py +18 -0
  110. komichi-1.0.1/src/michi/ui/app.py +99 -0
  111. komichi-1.0.1/tests/conftest.py +180 -0
  112. komichi-1.0.1/tests/e2e/README.md +5 -0
  113. komichi-1.0.1/tests/e2e/test_export_equivalence.py +168 -0
  114. komichi-1.0.1/tests/e2e/test_schema_stability.py +177 -0
  115. komichi-1.0.1/tests/fixtures/README.md +8 -0
  116. komichi-1.0.1/tests/fixtures/schemas/manifest-1.0.json +80 -0
  117. komichi-1.0.1/tests/fixtures/schemas/profile-1.0.json +86 -0
  118. komichi-1.0.1/tests/fixtures/schemas/recipe-1.0.yaml +50 -0
  119. komichi-1.0.1/tests/golden/README.md +6 -0
  120. komichi-1.0.1/tests/golden/__snapshots__/test_render_profile.ambr +291 -0
  121. komichi-1.0.1/tests/golden/test_render_profile.py +182 -0
  122. komichi-1.0.1/tests/unit/adapters/test_model.py +127 -0
  123. komichi-1.0.1/tests/unit/bench/test_runner.py +265 -0
  124. komichi-1.0.1/tests/unit/bench/test_significance.py +163 -0
  125. komichi-1.0.1/tests/unit/cli/test_app.py +36 -0
  126. komichi-1.0.1/tests/unit/cli/test_bench_report_cmd.py +288 -0
  127. komichi-1.0.1/tests/unit/cli/test_clean_cmd.py +241 -0
  128. komichi-1.0.1/tests/unit/cli/test_error_messages.py +113 -0
  129. komichi-1.0.1/tests/unit/cli/test_eval_cmd.py +296 -0
  130. komichi-1.0.1/tests/unit/cli/test_inspect_cmd.py +138 -0
  131. komichi-1.0.1/tests/unit/cli/test_project_defaults.py +243 -0
  132. komichi-1.0.1/tests/unit/console/test_console.py +310 -0
  133. komichi-1.0.1/tests/unit/core/test_artifacts.py +210 -0
  134. komichi-1.0.1/tests/unit/core/test_errors.py +40 -0
  135. komichi-1.0.1/tests/unit/core/test_io.py +142 -0
  136. komichi-1.0.1/tests/unit/evaluation/test_bootstrap.py +140 -0
  137. komichi-1.0.1/tests/unit/evaluation/test_checks.py +172 -0
  138. komichi-1.0.1/tests/unit/evaluation/test_evaluator.py +221 -0
  139. komichi-1.0.1/tests/unit/inspection/test_findings.py +191 -0
  140. komichi-1.0.1/tests/unit/inspection/test_profiler.py +143 -0
  141. komichi-1.0.1/tests/unit/plugins/test_plugins.py +291 -0
  142. komichi-1.0.1/tests/unit/recipes/test_recipes.py +350 -0
  143. komichi-1.0.1/tests/unit/sweep/test_sweep.py +262 -0
  144. komichi-1.0.1/tests/unit/test_explain.py +69 -0
  145. komichi-1.0.1/tests/unit/ui/test_ui.py +143 -0
  146. 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
@@ -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.