Englische Quelle — Übersetzung ausstehend — Englisch

Dependency Management & Supply-Chain Governance

SSOT for how dependencies are declared, updated, audited, and merged in this

repository. Established by TASK-DEVOPS-DEPENDABOT-HARDENING (2026-09-11).

Every claim below is backed by CI evidence or a verified GitHub API read;

commands marked with a source line are the repository's own verified tooling.

1. Dependency sources (what is authoritative)

EcosystemManifest (hand-edited SSOT)Generated artifacts (DO NOT EDIT)Production runtime?
Pythonpyproject.tomlrequirements.lock, requirements.txt (both # GENERATED - DO NOT EDIT)Yes — the engine runs from the lock (see ci.yml "Install via lock")
Frontend (/frontend)package.jsonpackage-lock.json (npm-managed, in lockstep)No — build/dev-time only. Node never runs the production engine; frontend/ is compiled to static assets. Do not introduce Node into the runtime path.
GitHub Actions.github/workflows/*—n/a (CI supply chain)

uv.lock exists as a resolution artifact referenced by lockfile-diff.yml,

osv-scanner.yml, and scripts/ci/classify_changes.py; the install/drift

contract below runs through requirements.lock.

2. Python lockfile synchronization (verified contract)

Source of truth: scripts/ci/check_dependency_drift.py and the header of the

generated artifacts. The authoritative regeneration command is:

python scripts/ci/check_dependency_drift.py --regen
# = uv pip compile pyproject.toml --all-extras --universal --generate-hashes

Rules (enforced fail-closed by the required check **"Dependency drift (lock vs

pyproject)"**):

  1. pyproject.toml is the ONLY hand-maintained dependency definition.
  2. Any PR that changes pyproject.toml MUST regenerate requirements.lock

AND requirements.txt in the SAME PR. A hand-edited generated artifact is

a CI red by design.

  1. The resolver must see a Python 3.11 interpreter (project floor

requires-python >=3.11); the CI job pins 3.11 and uv 0.12.10

(dependency-lock.yml comment block documents why both sides move

together). Do not bump uv on one side only.

  1. requirements.txt is a generated thin compatibility artifact parsed from

requirements.lock — regenerate it via the same script, never by hand.

Dependabot pip PRs modify only the version pins inside the generated

artifacts. That is allowed (the artifacts are regenerated outputs), but the

PR must still leave pyproject.toml and the artifacts mutually consistent —

the drift check passes iff the resolution matches, regardless of which file

Dependabot edited.

3. Frontend (npm) lockfile synchronization

package.json and package-lock.json must move together. Verification before

merge — use the scripts that actually exist in frontend/package.json

(dev, build, preview, typecheck; there is **no test script — do not

invent one**):

cd frontend
npm ci           # clean install strictly from package-lock.json (lockstep proof)
npm run typecheck
npm run build    # tsc -b && vite build

npm ci failing = lockfile out of sync = the PR does not merge. Never accept a

PR where only package.json changed.

4. Dependabot configuration (.github/dependabot.yml)

EcosystemDirectorySchedule (Etc/UTC)PR limitGroups
pip/weekly, Sunday 04:005python-production, python-dev-tools
npm/frontendweekly, Sunday 04:305frontend-framework, frontend-build-tools
github-actions/weekly, Sunday 05:005github-actions

Commit-message prefixes: chore(deps-py), chore(deps-fe), ci(actions)

(all with scope). Labels: dependencies + python / javascript (both

labels exist on the repo) / github-actions.

5. Security-update policy (security-first)

Dependabot security-update PRs are never grouped and never suppressed — they

arrive individually and are triaged ahead of routine bumps.

all torch updates") would also suppress security remediation. Do not add

blanket ignores.

pyproject.toml version ranges (e.g. torch>=2.2.0,<3.0.0,

polars>=0.20.0,<2.0.0). Dependabot respects those ranges, so ordinary

updates stay inside the tested compatibility window while a genuine security

fix inside the window still flows. Changing a range is an architectural

decision, not a governance flip.

security vs ORDINARY version. Security remediation must not wait behind

grouped freshness PRs.

6. Grouping policy and noise control

maximum routine load ≈ 3 grouped PRs/week, capped at 5 open PRs per

ecosystem.

bump can be reverted without touching the runtime group.

(vite, typescript, @types/, @vitejs/) are separate for the same

reason.

intentionally unused): Python, npm, and Actions have different validation

paths, and separate PRs keep rollback and CI diagnosis deterministic.

7. GitHub Actions SHA pinning

Every external uses: reference in .github/workflows/ is pinned to a full

40-character commit SHA with a human-readable version comment:

uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

/ GitHub API; SHA is authoritative, the comment is a label).

there are currently none in production workflows.

a pin = update SHA + version comment together.

external ref) was run at implementation time; keep it green. Local actions

and secrets/vars usage are out of scope of the scan.

8. Required CI before merge (dependency PRs)

Branch protection on main requires (relevant subset):

Tests + Py Tests (macos-latest) + Py Tests (windows-latest)`.

§3 commands locally; they are not (yet) all CI-required for frontend/.

documentation` (workflows are classified as CI changes) — and CI green on

the PR itself.

which dependency manifests moved (it never fails the build; the drift gate

is the enforcing control).

Never weaken, skip, or context-swap a required check to land a dependency PR.

9. Security PR priority, manual overrides, exceptions, rollback

  1. Security remediation > grouped freshness. A security PR may land with

routine grouped PRs still open (limits are per-ecosystem and independent).

  1. Manual override: a maintainer may pause Dependabot version updates

(repo settings) during a release freeze without disabling alerts or

security updates. Record the freeze window in this file.

  1. Exceptions to grouping (e.g. pin a package out of a group) go here with the

reason and removal condition.

  1. Rollback: dependency PRs squash-merge (the repo's merge method — merge

commits are 405-disallowed on this repository); revert the squash commit on

main via a normal PR. The grouped-PR shape (one ecosystem, one area) makes

a revert surgical; if a grouped PR must be partially rolled back, revert the

whole group and re-open the good packages in the next window.

10. GitHub security posture (verified 2026-09-11)

ControlStateEvidence
Dependency graphENABLEDSBOM endpoint GET /dependency-graph/sbom → HTTP 200
Dependabot alertsENABLED, 0 openGET /vulnerability-alerts → 204; GET /dependabot/alerts?state=open → []
Dependabot security updatesENABLED, not pausedGET /automated-security-fixes → {"enabled": true, "paused": false}
Grouped security updatesUI-only toggle; repo-level API does not expose it (404)API 404 on automated-security-fixes/grouped; operator verifies/sets in Security → Dependabot if UI shows the toggle
Malware (dev-environment) alertsNot exposed by repository admin APINo repo-level endpoint; not configurable by this credential/plan
Secret scanning + push protectionENABLEDsecurity_and_analysis in repo metadata
Code scanning (CodeQL) / Trivy / OSV-Scanner / Dependency ReviewPresent as CI workflows (security.yml, osv-scanner.yml, lockfile-diff.yml) with required contexts.github/workflows/
Dependabot rules (org-level policy rules)No repository-visible API (404); no org policy rule interacts with .github/dependabot.ymlAPI evidence as above

11. Operator/owner notes

labels itself on first use. The github-actions label likewise.

org/UI-scoped controls — see the final audit report for the exact evidence

and remaining operator actions.