Self-contained runtime
How Apothem's engine runs from any checkout — vendored dependencies, the PYTHONPATH=src invocation model, and the plugin-tree bootstrap.
Self-Contained Runtime
Apothem's engine is a self-contained runtime: it runs registry-free,
directly from any checkout or placed source tree, because its third-party
dependencies travel with it. Two pieces make that work — a vendored
dependency tree and a python -m invocation model that needs no installed
console scripts.
Vendored dependency tree
The validation and serialization stack is vendored as pure-Python source
under src/apothem/_vendor/, each package alongside its upstream license
file:
yaml(the pure-Python parser/emitter; the optional libyaml C extension is not carried)jsonschema, with its dependency chainattrs(and itsattralias),referencing, andjsonschema_specificationsrpds— a pure-Python shim that reimplements theHashTrieMap,HashTrieSet, andListsurfacejsonschemaandreferencinguse, backed by builtin types, so the stack runs with zero compiled extensionstyping_extensions
Vendored copies take precedence over any system-installed version: the
plugin bootstrap, the npm shim, the installers, and the python -m apothem
entry point itself each put the vendor directory on sys.path ahead of
site-packages. The selection policy — what is vendored, what is not, and
how vendored packages are refreshed — is documented in the
dependency vendoring strategy.
Two dependencies stay outside the tree: click and rich, the
terminal-facing libraries the CLI imports. They must be importable under
the interpreter that runs the engine; the installers check both, name any
that is missing, and offer to install it for you — with your confirmation,
or automatically with --yes / APOTHEM_AUTO_INSTALL_DEPS=1. On every other
channel the entry point checks both with the standard library before it
imports the CLI, and a missing one stops it with an error that names the
exact pip command for the running interpreter (a JSON envelope with code
runtime.dependency_missing under --json).
The python -m invocation model
Apothem intentionally declares no console scripts in pyproject.toml —
console scripts only exist when a package manager places them on PATH,
and the self-contained runtime never assumes one. The engine has two
invocation surfaces instead:
| Surface | Invocation | Context |
|---|---|---|
| Engine CLI | python -m apothem <command> | A source tree with src/ on PYTHONPATH (checkout, npx cache, plugin tree) |
| Hook runtime | <resolved CPython> "<harness-root>/.apothem/support/hooks/dispatch.py" <event> | The Claude Code materialization: the copy under the harness root's shared .apothem/support/ tree, by absolute path |
python -m apothemrunssrc/apothem/__main__.py, which putssrc/apothem/_vendoronsys.path, checks thatclickandrichare importable, then callsapothem.cli:main— the Click command group.- Hook entries in the materialized
settings.json/hooks.jsoninvoke the dispatcher (and, for Claude Code, the conformity gate at<harness-root>/.apothem/support/conformity/gate.py) by absolute script path. Both are standalone stdlib scripts that bootstrap their ownsys.path, and the gate's schema fixtures ride beside it at<harness-root>/.apothem/support/schemas/, so hooks run with no importableapothempackage on the host. The templates carry a${HARNESS_ROOT}token thatapothem installrenders to the real harness-root path in forward-slash form. - From a source checkout, the module forms
python -m apothem.hooks.dispatchandpython -m apothem.conformity.gaterun the same code for development.
The package directory becomes importable by prepending the checkout's
src/ directory to PYTHONPATH:
PYTHONPATH="$HOME/.apothem/src" python -m apothem <command>When the apothem launcher is not on PATH, install.sh prints this form at
completion, with the vendored directory ahead of src/ and the CPython it
resolved in place of python. install.ps1 prints the same two settings in
PowerShell form: a $env:PYTHONPATH assignment that joins the vendored and
src/ directories with ;, then & '<CPython>' -m apothem <command>.
Plugin-tree bootstrap
The Claude Code plugin bundles the engine under <plugin_root>/lib/apothem
rather than relying on PYTHONPATH. The bootstrap module
apothem.lib.plugin_bootstrap exposes bootstrap_syspath, which
idempotently prepends <plugin_root>/lib and the vendor directory to
sys.path so import apothem and every vendored dependency resolve from
the plugin tree. A malformed tree (missing lib/) raises
PluginBootstrapError rather than silently importing a stale system copy.
What the installer places on disk
The script installers place a git clone of the source tree at ~/.apothem
(override with APOTHEM_HOME) and run the engine from it — no Python packages
are installed into site-packages beyond the optional click / rich
prerequisite offer. The clone is the full repository, including the test suite
and documentation site the runtime never imports, for two deliberate reasons:
the engine materializes its cohorts — rules, skills, commands, and
templates — directly from the tree into each harness, so the tree is the live
source of truth rather than only a runtime; and the .git directory stays in
place so apothem update checks out the release tag in the existing clone
instead of re-downloading.
This run-from-source layout is the same pattern tools like nvm, pyenv, and
oh-my-zsh use — a few megabytes of source plus history, removable in one step
with the uninstaller (there is no system state to unwind). A slimmer footprint
— a shallow or sparse checkout that omits tests/ and site/ — is possible
but would trade away the in-place, signature-verified git-based update path;
the current layout favours a simple, verifiable update over minimal disk.
How the runtime finds Python
The one-shot installers and the npx shim probe different names and apply the
same rules. The installers probe python3, python, and the versioned names
(python3.14 through python3.10). The npx shim probes APOTHEM_PYTHON when
it is set, then python3, python, and py -3; it has no versioned names.
Both reject Microsoft Store launcher shims and accept the first candidate
reporting version 3.10 or newer.
When run from a source tree, the installers reuse the bundled
hooks/lib/find-python locator, which applies the same floor.
Recommended Next Step
Run python -m apothem --help with the checkout's src/ directory on
PYTHONPATH to confirm the self-contained CLI path resolves on your host.