Manifest zur Abhängigkeitsfixierung
Richtlinie zur Abhängigkeitsdeklaration, die Python-Laufzeitbereiche, Entwicklungswerkzeuge, Lock-Dateien der Release-Werkzeuge und ratifizierte Versionsuntergrenzen für jede Build-Oberfläche abdeckt.
Ratifizierte Haltung dazu, wie Apothem Abhängigkeiten deklariert, fixiert und sperrt. Zielgruppe: Mitwirkende und nachgelagerte Konsumenten, die das Reproduzierbarkeitsmodell verstehen müssen.
Haltung
Apothem ist eine Python-CLI mit einem kleinen Satz an Laufzeitabhängigkeiten plus
einer umfangreicheren Werkzeugkette für Entwicklung, Audit, Release und
Dokumentation. Laufzeitabhängigkeiten verwenden konservative Untergrenzen in
pyproject.toml; die Website committet site/package-lock.json; GitHub Actions
werden per unveränderlichem SHA mit Versionskommentaren fixiert und von Dependabot
aktualisiert.
| Klasse | Deklaration | Lock-Richtlinie |
|---|---|---|
| Python-Laufzeitabhängigkeiten | [project.dependencies] in pyproject.toml | Untergrenzenbereiche für Nutzer; das Paket liefert keinen Python-Laufzeit-Lock mit. CI installiert eine hash-gesperrte Hülle dieser Abhängigkeiten (siehe CI-Abhängigkeits-Locks) |
| Entwicklungs- / Sicherheitswerkzeuge | [project.optional-dependencies]-Extras | Untergrenzenbereiche, außer für ruff und mypy, die das dev-Extra exakt auf die Versionen fixiert, die CI ausführt (für ruff siehe CI-Werkzeug-Locks); CI installiert das dev-Extra aus einer hash-gesperrten Hülle (siehe CI-Abhängigkeits-Locks) |
| Release-Werkzeuge | scripts/release/requirements-build-linux.txt für Release-Workflows; das release-Extra in [project.optional-dependencies] für lokale Builds | Hash-gesperrt für Release-Workflows; aus der Hülle der Release-Werkzeuge erzeugt. Das release-Extra ist ein Untergrenzenbereich |
| CI-pip | scripts/ci/requirements-ci-pip.txt | Hash-gesperrt: eine einzige Fixierung pip==X.Y.Z mit den Hashes von Wheel und sdist, die jeder Workflow, der pip aktualisiert, mit --require-hashes -r installiert. Dependabot schlägt die Upgrades vor und schreibt die Hashes neu; scripts/dev/check_pip_pin_drift.py hält die Fixierung bei pip 26.2 oder neuer |
| CI-Abhängigkeits-Locks | scripts/ci/requirements-ci-dev.txt, -runtime.txt, -test.txt und -prereqs.txt | Hash-gesperrte universelle Hüllen, mit uv pip compile aus pyproject.toml (bei -prereqs.txt aus den Host-Voraussetzungen der Engine) kompiliert, zum Stand eines Lock-Datums abzüglich einer Wartezeit von 7 Tagen; beides steht in jeder Datei. Installiert werden sie mit --require-hashes -r (das Paket selbst mit --no-deps -e .). CI testet die gesperrten Versionen, bis scripts/dev/refresh_ci_locks.py sie neu erzeugt; pip-audit.yml auditiert wöchentlich die neuesten zulässigen Versionen und zusätzlich die Locks. tests/scripts/test_ci_locks_fresh.py schlägt fehl, wenn ein Lock seine Eingaben nicht mehr erfüllt |
| CI-Werkzeug-Locks | scripts/ci/requirements-ci-ruff.txt, -bandit.txt, -pip-audit.txt, -pip-licenses.txt und -pre-commit.txt | Eine hash-gesperrte Hülle je Werkzeug, das die Workflows ausführen, vom selben Skript aus einer exakten Angabe in scripts/dev/ci_lock_table.py kompiliert, mit demselben Lock-Datum und derselben Wartezeit, und mit --require-hashes -r installiert. Kein Workflow nennt eine Werkzeugversion. pre-commit braucht Python 3.11 oder neuer, sein Lock deshalb auch, und der pip-audit-Lock wird ebenfalls für 3.11 kompiliert, weil das neueste filelock mit Unterstützung für 3.10 nicht behobene Sicherheitsmeldungen hat. Nur der CI-pip-Lock fixiert pip |
| Dokumentationsseite | site/package.json | site/package-lock.json committet und von npm ci konsumiert |
| VS-Code-Packager | tools/vsce/package.json | tools/vsce/package-lock.json committet; Release- und Veröffentlichungsjobs führen npm ci --ignore-scripts aus |
| Harness-CLIs für den Channel-Smoke | tools/channel-smoke/package.json | tools/channel-smoke/package-lock.json committet und von npm ci konsumiert |
| GitHub Actions | SHA-fixierte uses:-Referenzen mit Versionskommentaren | Dependabot schlägt wöchentliche Aktualisierungen vor; Ausnahmen tragen action-pinning-exempt:-Markierungen |
Release-Ratifizierung
| Oberfläche | Ratifizierter Zustand | Begründung |
|---|---|---|
| Laufzeitabhängigkeiten | Aktuelle Untergrenzen stehen in pyproject.toml unter [project.dependencies] | Aktuelle stabile Untergrenzen vor dem Release ratifiziert; kein bekannter CVE-Blocker zur Laufzeit |
| Entwicklungswerkzeuge | Aktuelle Untergrenzen stehen im Extra dev von pyproject.toml; ruff und mypy sind dort exakt fixiert | Neueste stabile Untergrenzen vor dem Release ratifiziert; ruff und mypy sind für die Hooks, CI und Mitwirkende auf je eine Version fixiert, der mypy-Hook fixiert die Bibliotheken, die er auflistet, auf die Versionen des dev-Locks, und tests/scripts/test_ci_tool_locks.py schlägt fehl, wenn sie abweichen |
| Sicherheitswerkzeuge | Aktuelle Untergrenzen stehen im Extra security von pyproject.toml | Aktuelle Untergrenzen der Scanner vor dem Release ratifiziert |
| Release-Werkzeuge | Die hash-gesperrte Abhängigkeitsmenge steht in scripts/release/requirements-build-linux.txt | Der Release-Workflow installiert mit --require-hashes; lokale Skripte verlangen, dass build bereits vorhanden ist, statt schwankende Abhängigkeiten stillschweigend zu installieren |
| CI-pip | Die hash-gesperrte Fixierung steht in scripts/ci/requirements-ci-pip.txt | pip 26.2 oder neuer schließt CVE-2026-13346; Workflows installieren pip mit --require-hashes, sodass der Download gegen seinen veröffentlichten Hash geprüft wird |
| CI-Abhängigkeits-Locks | Die hash-gesperrten Abhängigkeitsmengen stehen in scripts/ci/requirements-ci-{dev,runtime,test,prereqs}.txt | Workflows installieren sie mit --require-hashes; jede Datei hält ihr Lock-Datum, ihre Wartezeit und ihren Stichtag fest, und der Aktualitätstest hält sie im Gleichschritt mit pyproject.toml |
| CI-Werkzeug-Locks | Die hash-gesperrten Abhängigkeitsmengen stehen in scripts/ci/requirements-ci-{ruff,bandit,pip-audit,pip-licenses,pre-commit}.txt | Workflows installieren sie mit --require-hashes und nennen keine Werkzeugversion; die Angaben stehen in scripts/dev/ci_lock_table.py, und Lock-Datum, Wartezeit und Stichtag stimmen mit denen der Abhängigkeits-Locks überein |
| Dokumentationswerkzeuge | Aktuelle Bereiche stehen in site/package.json; die exakte Auflösung steht in site/package-lock.json | npm outdated meldet nach der Aktualisierung der Lock-Datei keine veraltete Dokumentationsabhängigkeit |
| GitHub Actions | Bestehende SHA-Pins werden für das aktuelle Release beibehalten; der wiederverwendbare SLSA-Workflow bleibt die dokumentierte, per Tag fixierte Ausnahme und ist in release.yml mit einem Kommentar action-pinning-exempt: gekennzeichnet | Der öffentliche CI-Neulauf ist grün; breite Major-Upgrades von Actions werden bewusst den PRs der Abhängigkeitsautomatisierung überlassen, um Unruhe an der Release-Oberfläche zu vermeiden |
| npm-Paketierung | Der Workflow publish-npm.yml läuft beim Push des Tags v*.*.*; workflow_dispatch dient als Ausweichweg | Das einzige öffentliche npm-Paket ist @ahmed-g-gad/apothem; die Veröffentlichung wartet auf die Genehmigung der Umgebung release durch den Operator, die erteilt wird, nachdem scripts/release/check-release-ready.sh erfolgreich durchgelaufen ist |
Sperrung
Die eigenen Python-Lock-Dateien der Mitwirkenden werden bei Bedarf erzeugt und
nicht committet: Apothems Laufzeithülle ist klein, und die CLI unterstützt
mehrere Python-Nebenversionen. CI ist die Ausnahme und installiert die
hash-gesperrten Dateien in scripts/ci/: vier Abhängigkeits-Locks
(requirements-ci-dev.txt, -runtime.txt, -test.txt und -prereqs.txt) und
einen Lock je Werkzeug, das die Workflows ausführen (-ruff.txt,
-bandit.txt, -pip-audit.txt, -pip-licenses.txt und -pre-commit.txt).
python scripts/dev/refresh_ci_locks.py kompiliert alle neun zum Stand eines
Lock-Datums abzüglich einer Wartezeit von 7 Tagen, die der von Dependabot
entspricht. CI testet also die Releases, die am Lock-Datum mindestens eine
Woche alt waren, und eine Aktualisierung der Dateien rückt auf neuere Releases
vor. Jede Datei hält das Lock-Datum, die Wartezeit und den daraus folgenden
Stichtag fest, und --check reproduziert den Stichtag. Ein dringender
Sicherheitsfix, der jünger als die Wartezeit ist, braucht einen
Aktualisierungslauf mit --cooldown-days 0 oder eine Wartezeit-Ausnahme für
sein Paket in scripts/dev/ci_lock_table.py, die die Wartezeit nur für dieses
Paket aufhebt. Der wöchentliche Lauf von pip-audit.yml auditiert die neuesten
Versionen, die pyproject.toml zulässt, und dazu die neun Locks; die
Sicherheitsmeldungen fragt er beim OSV-Dienst ab. Mitwirkende installieren
weiterhin mit pip install -e ".[dev]".
# Astral uv:
uv pip install -e ".[dev,security,release]"
uv pip freeze > requirements.dev.lock
# pip-tools:
pip-compile --extra=dev --extra=security --extra=release -o requirements.dev.lock pyproject.toml
# Plain pip:
pip install -e ".[dev,security,release]"
pip freeze > requirements.dev.lockDie Website ist anders: site/package-lock.json wird committet und CI verwendet
npm ci, sodass die gerenderte Dokumentationsseite eine reproduzierbare
Node-Hülle hat.
Begründung
- Warum Bereichsfixierungen für Python? Die CLI unterstützt eine breite
Python-Matrix, daher hält
pyproject.tomlkonservative Untergrenzen. CI installiert hash-gesperrte Hüllen dieser Bereiche, die der Maintainer mitscripts/dev/refresh_ci_locks.pyaktualisiert (vorgesehen ist ein wöchentlicher Rhythmus), und der wöchentliche Lauf vonpip-audit.ymllöst die neuesten zulässigen Versionen auf, um Probleme mit aktuellen Werkzeugen aufzudecken. - Warum ein committeter Node-Lock? Die Website ist ein bereitgestelltes
statisches Artefakt; die Lock-Datei liefert deterministische
npm ci-Builds für diese öffentliche Oberfläche. - Warum SHA-fixierte Actions? Tags sind veränderlich; SHAs sind unveränderlich. Dependabot schlägt die SHA-Aktualisierungen vor und schreibt jeden Versionskommentar neu, während das Release-Gate jede absichtliche Zurückstellung festhält.
- Was der Update-Bot nicht anfasst. Die Dependabot-Versionsupdates
(
.github/dependabot.yml) decken die GitHub-Actions-Pins, die Lock-Datei der Website, die Lock-Datei des vsce-Packagers (tools/vsce), die Lock-Datei der Harness-CLIs, die der Channel-Smoke installiert (tools/channel-smoke), das hash-gesperrte pip, das CI installiert (scripts/ci/requirements-ci-pip.txt), und die Pre-Commit-Hooks ab. Die anderen neun Dateien inscripts/cisind Hüllen, diescripts/dev/refresh_ci_locks.pyals Ganzes neu erzeugt; keine davon fixiert pip, und die Dependabot-Versionsupdates für diesen Ordner sind auf pip beschränkt. Die Laufzeit-Untergrenzen inpyproject.toml, die hash-gesperrten Release-Anforderungen, die vendorte Hülle insrc/apothem/_vendor/vendor.txtund die Pre-Commit-Hooks, die im Gleichschritt mitpyproject.tomlfixiert sind, werden von Hand angehoben, weil die Anhebung einer einzelnen Fixierung die Dateien brechen würde, mit denen sie übereinstimmen müssen. Die ruff- und mypy-Hooks sind zwei davon:tests/scripts/test_ci_tool_locks.pyschlägt fehl, bis die exakte ruff-Fixierung inpyproject.toml, die rev des Hooks, der ruff-Lock und der dev-Lock dieselbe Version tragen und bis die exakte mypy-Fixierung, die rev des mypy-Hooks und die Bibliotheken, die dieser Hook auflistet, zum dev-Lock passen. Ein Dependabot-Sicherheits-Pull-Request für eines der beiden Werkzeuge wird daher von Hand angepasst. Die Major-Version von@types/nodeder Website folgt ihrer Node-Untergrenze (enginesund.nvmrc, Node 22), daher schlägt Dependabot nur deren Minor- und Patch-Aktualisierungen vor; heben Sie diese Major-Version zusammen mit der Untergrenze an. Versionsupdates lassen npm-overrides-Blöcke unberührt. Die Dependabot-Sicherheitsupdates decken weiterhin jedes Manifest ab, sodass ein Sicherheits-Pull-Request eine dieser Fixierungen vorschlagen oder einen Override verschieben kann; passen Sie ihn von Hand an oder schließen Sie ihn. - Einen Dependabot-Pull-Request mergen. Die Squash-Voreinstellung des
Repositorys übernimmt den PR-Titel. Manche Dependabot-Titel, meist
gruppierte, die ein Verzeichnis nennen, überschreiten die 72 Zeichen des
Squash-Betreffs; die PR-Title-Prüfung nennt sie, und eine Umbenennung behebt
sie. Ein Pull-Request, der eine Werkzeug-Lock-Datei ändert, führt keinen
ci.yml-Job aus; daher auditiert und installiert sie der npm-Audit-Workflow, paketiert für die vsce-Lock-Datei die VS-Code-Erweiterung und führt die vsce-Release-Tests aus, und für die channel-smoke-Lock-Datei läuft der Channel-Smoke-Workflow. Der Markdown-Lint-Workflow führt bei einem Pull-Request für die Pre-Commit-Hooks den markdownlint-Hook aus; die übrigen Hooks werden in CI nicht ausgeübt, führen Sie daher vor dem Mergenpre-commit run --all-filesauf seinem Branch aus.
Autorschafts-Header — SPDX-Lizenzzeile pro Datei
Definieren und erzwingen Sie SPDX-Lizenzbezeichner-Marker pro Datei mit kanonischen einzeiligen Headern in der für jeden Dateityp passenden Kommentarsyntax.
Plan-Disziplin — Projektlokaler, flüchtiger Arbeitsspeicher
Verwalten Sie projektlokalen, flüchtigen Arbeitsspeicher in .apothem/plans/ (ein Legacy-.plans/-Baum wird per apothem migrate-workspace aktualisiert) mit Frontmatter-Schema, Lebenszyklus-Übergängen, Promotion zu ADRs und Durchsetzung über Hooks und Validatoren.