Runtime autonome
Comment le moteur d'Apothem s'exécute depuis n'importe quel checkout — dépendances vendorisées, le modèle d'invocation PYTHONPATH=src et le bootstrap de l'arbre du plugin.
Runtime autonome
Le moteur d'Apothem est un runtime autonome : il s'exécute sans registre,
directement depuis n'importe quel checkout ou arbre de code source déposé, parce
que ses dépendances tierces voyagent avec lui. Deux pièces rendent cela
possible — un arbre de dépendances vendorisées et un modèle d'invocation
python -m qui n'a besoin d'aucun script de console installé.
Arbre de dépendances vendorisées
La pile de validation et de sérialisation est vendorisée sous forme de code
source en Python pur sous src/apothem/_vendor/, chaque paquet accompagné du
fichier de licence de son projet amont :
yaml(le parseur/émetteur en Python pur ; l'extension C optionnelle libyaml n'est pas embarquée)jsonschema, avec sa chaîne de dépendancesattrs(et son aliasattr),referencingetjsonschema_specificationsrpds— un shim en Python pur qui réimplémente la surfaceHashTrieMap,HashTrieSetetListqu'utilisentjsonschemaetreferencing, adossé à des types intégrés, de sorte que la pile s'exécute sans aucune extension compiléetyping_extensions
Les copies vendorisées priment sur toute version installée sur le système : le
bootstrap du plugin, le shim npm, les installateurs et le point d'entrée
python -m apothem lui-même placent chacun le répertoire vendor dans sys.path
devant site-packages. La politique de sélection — ce qui est vendorisé, ce qui
ne l'est pas et comment les paquets vendorisés sont rafraîchis — est documentée
dans la
stratégie de vendorisation des dépendances.
Deux dépendances restent hors de l'arbre : click et rich, les
bibliothèques orientées terminal qu'importe la CLI. Elles doivent être
importables sous l'interpréteur qui exécute le moteur ; les installateurs
vérifient les deux, nomment celle qui manque et proposent de l'installer pour
vous — avec votre confirmation, ou automatiquement avec --yes /
APOTHEM_AUTO_INSTALL_DEPS=1. Sur tous les autres canaux, le point d'entrée
vérifie les deux avec la bibliothèque standard avant d'importer la CLI, et une
dépendance manquante l'arrête avec une erreur qui nomme la commande pip exacte
pour l'interpréteur en cours d'exécution (une enveloppe JSON avec le code
runtime.dependency_missing sous --json).
Le modèle d'invocation python -m
Apothem ne déclare intentionnellement aucun script de console dans
pyproject.toml — les scripts de console n'existent que lorsqu'un gestionnaire
de paquets les place sur le PATH, et le runtime autonome n'en suppose jamais
un. Le moteur dispose plutôt de deux surfaces d'invocation :
| Surface | Invocation | Contexte |
|---|---|---|
| CLI du moteur | python -m apothem <command> | Un arbre de code source avec src/ sur le PYTHONPATH (checkout, cache npx, arbre du plugin) |
| Runtime des hooks | <resolved CPython> "<harness-root>/.apothem/support/hooks/dispatch.py" <event> | Matérialisation Claude Code : la copie située sous l'arborescence partagée .apothem/support/ de la racine de l'environnement, par chemin absolu |
python -m apothemexécutesrc/apothem/__main__.py, qui placesrc/apothem/_vendordanssys.path, vérifie queclicketrichsont importables, puis appelleapothem.cli:main— le groupe de commandes Click.- Les entrées de hook du
settings.json/hooks.jsonmatérialisé invoquent le répartiteur (et, pour Claude Code, le portail de conformité à<harness-root>/.apothem/support/conformity/gate.py) par chemin de script absolu. Tous deux sont des scripts autonomes de la bibliothèque standard qui amorcent leur propresys.path, et les fixtures de schéma du portail voyagent à côté de lui dans<harness-root>/.apothem/support/schemas/, de sorte que les hooks s'exécutent sans aucun paquetapothemimportable sur l'hôte. Les templates portent un jeton${HARNESS_ROOT}qu'apothem installrend en chemin réel de la racine de l'environnement, sous forme à barres obliques. - Depuis un checkout du code source, les formes de module
python -m apothem.hooks.dispatchetpython -m apothem.conformity.gateexécutent le même code pour le développement.
Le répertoire du paquet devient importable en plaçant le répertoire src/ du
checkout en tête de PYTHONPATH :
PYTHONPATH="$HOME/.apothem/src" python -m apothem <command>Lorsque le lanceur apothem ne figure pas dans le PATH, install.sh affiche cette forme
à la fin, avec le répertoire vendorisé placé avant src/ et le CPython qu'il a
résolu à la place de python. install.ps1 affiche les deux mêmes réglages sous
forme PowerShell : une affectation $env:PYTHONPATH qui joint les répertoires
vendorisé et src/ avec ;, puis & '<CPython>' -m apothem <command>.
Bootstrap de l'arbre du plugin
Le plugin Claude Code embarque le moteur sous <plugin_root>/lib/apothem plutôt
que de s'appuyer sur PYTHONPATH. Le module de bootstrap
apothem.lib.plugin_bootstrap expose bootstrap_syspath, qui place de façon
idempotente <plugin_root>/lib et le répertoire vendor en tête de sys.path
afin qu'import apothem et chaque dépendance vendorisée se résolvent depuis
l'arbre du plugin. Un arbre malformé (sans lib/) lève PluginBootstrapError
plutôt que d'importer silencieusement une copie système périmée.
Ce que l'installateur dépose sur le disque
Les installateurs par script déposent un clone git de l'arbre de code source à
~/.apothem (remplaçable par APOTHEM_HOME) et exécutent le moteur depuis
lui — aucun paquet Python n'est installé dans site-packages au-delà de la
proposition optionnelle des prérequis click / rich. Le clone est le dépôt
complet, y compris la suite de tests et le site de documentation que le runtime
n'importe jamais, pour deux raisons délibérées : le moteur matérialise ses
cohortes — règles, skills, commandes et templates — directement depuis l'arbre
dans chaque environnement, de sorte que l'arbre est la source de vérité vivante
et pas seulement un runtime ; et le répertoire .git reste en place pour
qu'apothem update extraie le tag de version dans le clone existant au lieu
de le retélécharger.
Cette disposition d'exécution depuis le code source suit le même motif que des
outils comme nvm, pyenv et oh-my-zsh — quelques mégaoctets de code source
plus l'historique, supprimables en une seule étape avec le désinstallateur (il
n'y a aucun état système à défaire). Une empreinte plus légère — un checkout
superficiel ou partiel qui omet tests/ et site/ — est possible, mais
sacrifierait le chemin de mise à jour sur place, vérifié par signature et fondé
sur git ; la disposition actuelle privilégie une mise à jour simple et
vérifiable plutôt qu'un espace disque minimal.
Comment le runtime trouve Python
Les installateurs en une étape et le shim npx sondent des noms différents et
appliquent les mêmes règles. Les installateurs sondent python3, python et
les noms versionnés (python3.14 jusqu'à python3.10). Le shim npx sonde
APOTHEM_PYTHON lorsqu'elle est définie, puis python3, python et py -3 ;
il n'a aucun nom versionné. Tous deux rejettent les shims du lanceur Microsoft
Store et acceptent le premier candidat signalant la version 3.10 ou une version
plus récente.
Lorsqu'ils sont exécutés depuis un arbre de code source, les installateurs
réutilisent le localisateur embarqué hooks/lib/find-python, qui applique le
même plancher.
Prochaine étape recommandée
Exécutez python -m apothem --help avec le répertoire src/ du checkout sur
le PYTHONPATH pour confirmer que le chemin de la CLI autonome se résout sur
votre hôte.