| eatmycode_version | 1.2.0 |
|---|
python3 -m kerness.selfcheck answers one question: is this installation
usable, and which optional features are available? It imports every core
module, loads every built-in asset, reports optional dependencies, and exits 0
or 1.
It is the first thing to run against a fresh wheel, because the failure it is designed to catch — an extension that built but cannot import, or assets that shipped but do not parse — produces no error until something tries. It owns the check and its exit code only; the loaders it calls belong to gameplan.md, role.md, persona.md and skills.md, and it runs no session.
done — .venv/bin/python -m kerness.selfcheck prints OK: all core checks passed and exits 0; bindings/python/tests/test_selfcheck.py passes 6 tests.
CI runs the check against the developed extension
(.github/workflows/ci.yml:110) and against a source distribution installed
into a clean interpreter (.github/workflows/release.yml:110).
| File | Role |
|---|---|
bindings/python/kerness/selfcheck.py |
the whole check: the core-module list, the optional list, the three check functions and main |
bindings/python/tests/test_selfcheck.py |
coverage and exit-code tests |
Deliberately Python, not a Rust entry point: the failure it exists to catch is a broken Python import, which a Rust binary cannot observe. Tests also monkeypatch both module lists, which requires them to be module attributes.
Python only, one module in the installed package; the root's Coding Style
and Code Design rules apply
and ruff check bindings/python (rules E4, E7, E9, F) enforces them.
Local facts:
- It is the one package module that is a
__main__script rather than a re-export shim, sobindings/python/tests/test_packaging.py:60excludes it from the__all__rule every other public module is held to. - Every check catches bare
Exceptionunder# noqa: BLE001(bindings/python/kerness/selfcheck.py:55,:76,:87,:100,:111): the point is to report anything at all, including a non-ImportErrorraised at import time. TheBLErule set is not selected inbindings/python/pyproject.toml, so the markers are documentation rather than a suppression the linter needs. - Output is
printto stdout, which is whatcapsysreads inbindings/python/tests/test_selfcheck.py:61and:109; this is the package's only module that prints by design. - Tests follow the package convention:
Test<Behaviour>classes andtest_<sentence>functions, withmonkeypatchon module attributes.
Three passes, each appending a label to one failures list, then one exit
code. _check_imports (bindings/python/kerness/selfcheck.py:51) imports each
(module, label) in _CORE_MODULES. _check_assets (:62) enumerates every
built-in gameplan, skill, role and persona through its list_builtin_*
function and loads each one, refusing a gameplan with no terminate_on
(:74) and a role with no body (:98). _check_optional (:116) reports
_OPTIONAL imports as PASS or SKIP and never touches failures.
Invariants a change must preserve:
- Assets are discovered, not listed. The asset pass calls the loaders'
enumeration functions —
crates/kerness/src/gameplan.rs:109,crates/kerness/src/skill/loader.rs:113,crates/kerness/src/role.rs:123,crates/kerness/src/persona.rs:82— so an added or removed asset cannot escape it. Enforced bytest_every_asset_class_is_enumerated_from_disk(bindings/python/tests/test_selfcheck.py:36) andtest_the_check_reports_every_asset_on_disk(:61), which pins what the check prints rather than only which helper it calls. - Core modules are a literal list held in step by a test.
_CORE_MODULES(bindings/python/kerness/selfcheck.py:15) is the definition of "core";test_every_package_module_is_in_the_core_list(bindings/python/tests/test_selfcheck.py:18) walks the package directory and fails on any unlisted module. The comment atbindings/python/kerness/selfcheck.py:38records the one naming constraint in the package:kerness.skillsis theSKILL.mddata directory, so the runtime module isskill_runtimeto avoid shadowing it. - Optional absence is a SKIP, never a failure. Enforced by
test_a_healthy_install_exits_zero_even_without_the_extras(:88). - A failure of any kind is exit 1 and names its label.
main(bindings/python/kerness/selfcheck.py:126) returns 1 whenfailuresis non-empty and printsOK: all core checks passed(:143) otherwise. Enforced bytest_a_broken_core_module_exits_nonzero(bindings/python/tests/test_selfcheck.py:100) andtest_a_broken_asset_exits_nonzero(:109). - Nothing here calls a provider or starts a session. Observed; no test enforces it.
The Rust side proves the same asset properties for a crate-only caller in
crates/kerness/tests/public_api.rs:178, :197 and :219; the two are the
two halves of one guarantee and neither substitutes for the other.
bindings/python/kerness/selfcheck.py:15—_CORE_MODULES— 25(module, label)pairs that must import.bindings/python/kerness/selfcheck.py:46—_OPTIONAL—(import, label, what it enables); absence is reported, never fatal.bindings/python/kerness/selfcheck.py:51—_check_imports(failures)— imports each core module, printsPASS/FAIL, appends failed labels.bindings/python/kerness/selfcheck.py:62—_check_assets(failures)— enumerates each built-in class from disk and loads every member.bindings/python/kerness/selfcheck.py:116—_check_optional()— printsPASSorSKIPper optional import; no side effect on the exit code.bindings/python/kerness/selfcheck.py:126—main()— runs the three passes in order and returns the process exit code.
- Imports every module in the package, so it transitively touches every
subsystem doc in the Index; the extension is reached first as
kerness._core. - Loads assets through gameplan.md's
load_gameplan, role.md'sload_role, skills.md'sload_skilland persona.md'sload_persona, and enumerates them through the matchinglist_builtin_*functions; the asset root is the one bindings.md'sbootstrapinstalled at import. - Its
_CORE_MODULESlist andbindings/python/kerness/*.pymust stay in step;bindings/python/tests/test_selfcheck.py:18is where that is tested. - testing.md runs it in CI after
maturin developand after a clean sdist install; the second run is what proves the installed package rather than the working tree.
.venv/bin/python -m kerness.selfcheck # pass = last line "OK: all core checks passed", exit 0
.venv/bin/python -m pytest bindings/python/tests/test_selfcheck.py -q # pass = 6 passedbindings/python/tests/test_selfcheck.py:18—test_every_package_module_is_in_the_core_list— walksbindings/python/kerness/and asserts every module appears in_CORE_MODULES, so a new shim that is not listed fails the suite.bindings/python/tests/test_selfcheck.py:36—test_every_asset_class_is_enumerated_from_disk— the "assert discovery, not literals" rule, tested directly.bindings/python/tests/test_selfcheck.py:61—test_the_check_reports_every_asset_on_disk— every enumerated asset name appears in what the check prints.bindings/python/tests/test_selfcheck.py:88,:100and:109— a missing optional is exit 0; a broken core module and a broken asset are each exit 1.- Gap: no test asserts that a role with an empty body (
selfcheck.py:98) fails the roles pass; the Rust counterpartevery_bundled_role_loads_and_carries_a_prompt(crates/kerness/tests/public_api.rs:197) covers the property for the crate's copy only.
- Adding a package module → add its
(module, label)pair to_CORE_MODULES(bindings/python/kerness/selfcheck.py:15);test_every_package_module_is_in_the_core_listfails until you do. If it is a new kind of module, add it to bindings.md's Code Structure. - Adding an asset class → add a fourth block to
_check_assets(:62) following the existing shape (enumerate, load each, printPASS <class> (<names>)), extendtest_every_asset_class_is_enumerated_from_diskandtest_the_check_reports_every_asset_on_disk, and add the class to the Rust side incrates/kerness/tests/public_api.rs. - Adding an optional dependency → append to
_OPTIONAL(:46); theenablestext is what a user reads onSKIP, so name the feature it gates. - Changing the output format →
test_the_check_reports_every_asset_on_diskandtest_a_broken_asset_exits_nonzeromatch printed text; theOK:line at:143is the evidence string every How to Test in this doc set cites. - Forbidden coupling: no import of a provider backend at module scope, no
network, no session construction; the check must stay runnable with no key
and no
pydantic. - Compatibility check:
bindings/python/tests/test_packaging.py:60excludesselfcheckfrom the__all__rule by name; renaming the module breaks that exclusion.
Improvement candidates (proposals, not accepted work):
- Derive
_CORE_MODULESfrompkgutil.iter_modulesthe waybindings/python/tests/test_packaging.py:60already does, keeping only the label map literal. Benefit: an unlisted shim is caught in an installed wheel, not only in this repository. Check:test_every_package_module_is_in_the_core_listbecomes redundant and is retired with a citation to the derivation. - Assert the empty-role-body refusal from Python. Benefit: closes the gap
named above. Check: one monkeypatched case in
TestExitCodereturning aRoleConfigwith emptycontentand asserting"roles" in failures.
_CORE_MODULESis a literal list, unlike the asset checks, so a new shim must be added by hand. The omission is caught bybindings/python/tests/test_selfcheck.py:18rather than by the check itself — which means it is caught in this repository but not in an installed wheel.- The check imports and loads but does not run anything — a session that would fail on its first provider call still reports a healthy installation.