Dependency Update Policy¶
Purpose¶
This policy defines how FiberPath tracks, triages, and upgrades dependencies across Python, Node/Tauri, Rust, and GitHub Actions workflows.
Scope¶
Applies to:
- Python dependencies in
pyproject.tomlanduv.lock - Node dependencies in
fiberpath_gui/package.jsonandfiberpath_gui/package-lock.json - Rust dependencies in
fiberpath_gui/src-tauri/Cargo.tomlandfiberpath_gui/src-tauri/Cargo.lock - GitHub Actions dependencies in
.github/workflows/*.yml
Cadence¶
- Patch updates: monthly
- Minor updates: quarterly review window
- Major updates: dedicated release slot (for example, a migration-focused release like v0.7.0 or similar)
Ownership¶
- Primary triage owner: maintainers responsible for the active release planning document in
docs/development/feature-backlog.md - PR review owner: area maintainer for the affected ecosystem
- Security escalation owner: release manager on current target milestone
Triage SLAs¶
- Critical vulnerabilities: initial triage within 48 hours
- High vulnerabilities: triage and mitigation plan within 7 days
- Moderate vulnerabilities: scheduled into next planned maintenance slot
- Low vulnerabilities: best-effort backlog prioritization
Update Classification¶
- Low risk: patch updates and non-breaking minor updates without migration notes
- Medium risk: minor updates with behavior changes, tooling/runtime defaults, or lockfile churn with integration risk
- High risk: major updates, breaking API changes, migration guide required, or observed test/build regressions
CI audit gating¶
One policy, enforced per ecosystem by .github/workflows/dependency-audit.yml (runs on PRs to
main, pushes to main, and weekly on Monday). The policy: High/Critical vulnerabilities block;
everything else is reported but does not block. Full dependency tree is in scope — dev and build
dependencies block the same as runtime ones, because the build chain produces the shipped binaries
(PyInstaller, Tauri bundler) and dev tools execute in CI.
| Ecosystem | Blocks CI | Reported, non-blocking | Mechanism |
|---|---|---|---|
Rust (cargo audit) |
vulnerability with CVSS ≥ 7.0 | CVSS < 7.0, unscored (loud ::warning::), informational unmaintained/unsound/yanked |
scripts/ci/cargo_audit_gate.py computes the CVSS 3.x base score from the RustSec vector and fails closed on a missing/malformed report |
Python (pip-audit) |
any advisory | — | pip-audit exit code. Deliberately stricter: pip-audit has no severity filter and PyPI/OSV advisories often carry no CVSS, so tiering is not implementable. Use the allowlist to accept a triaged Medium/Low. |
Node (npm audit) |
severity high or critical, or any unrecognised severity |
moderate/low/info |
scripts/ci/npm_audit_gate.py reads the npm audit --json report and counts each advisory once (not every package it propagates through). It fails closed on a missing/malformed report, a report format other than auditReportVersion 2, or a package npm flags at high/critical (or an unrecognised severity) that does not trace through its via chain to a parsed advisory at least as severe; an ignored advisory still accounts for its chain |
Allowlists — an accepted advisory is waived where the tool supports it, and every entry must carry the advisory ID, a one-line justification, and a re-check trigger (an upstream event or date):
- Rust:
[advisories] ignoreinfiberpath_gui/src-tauri/audit.toml(create on first use). - Python:
--ignore-vuln <ID>flags on the pip-audit step independency-audit.yml. - Node: npm has no native ignore, so
--ignore <GHSA-ID>flags on the gate step independency-audit.ymlwaive it innpm_audit_gate.py. An--ignorethat no longer matches any advisory raises a::warning::so the entry gets removed.
Record the reasoning for each accepted advisory in this document (see Accepted advisories); the live state is whatever the latest audit run reports — its JSON reports upload as artifacts on every run, pass or fail.
Enforcement note: Dependency Audit is intentionally not a required status check (only "CI Check" is). Advisories are published asynchronously — an unrelated PR must not be hard-blocked because a CVE landed overnight. The gate is the weekly scheduled run plus PR-level visibility, and the rule that a red audit is triaged (fix, allowlist, or tracked deferral) before further merges — by convention, not branch protection.
Remediation flow when an audit goes red: Renovate's weekly lock-file maintenance (Mondays
before 06:00, ahead of the 07:00 audit) usually clears it; for urgent advisories bump directly
(uv lock --upgrade-package <pkg>, cargo update -p <pkg>, npm audit fix) — floor constraints
like Pillow>=10.3 mean no Renovate update PR will exist, so the lockfile bump is the fix.
Dependabot security alerts remain enabled as the notification backstop.
Exception Handling¶
When an update is deferred:
- Record package, current version, candidate version, and reason in the active roadmap.
- Assign a target release for re-evaluation.
- Add temporary ignore rules only when they reduce noise and are documented.
- Remove ignore rules once the deferred item is re-scoped into active execution.
Accepted advisories (reasoning record)¶
This section records why an advisory is accepted so it is not re-triaged from scratch. It is deliberately not an inventory — the live advisory state is the latest audit run's report artifacts, and informational warnings never block by policy, so they only get an entry when the reasoning is non-obvious. Remove an entry when its re-check trigger fires. Do not block a release solely for anything listed here.
glib0.18 — unsoundVariantStrIteriterator impls (RUSTSEC-2024-0429, GHSA-wrw7-89jp-8q8g). Tauri 2.x on Linux renders via GTK3, and every crate in its Linux chain requires gtk-rs^0.18, which holdsglibat 0.18; the fix is in 0.20. Not upgradable from this repo (#376).cargo auditreports it as an informationalunsoundwarning (no CVSS), non-blocking under the gate; Dependabot alert #3 is the same advisory. The gtk-rs 0.18unmaintainedadvisories (RUSTSEC-2024-0412gdk, -0413atkand -0415gtkamong them) were withdrawn on 2026-08-14 when gtk3-rs development resumed, so audit runs no longer report them. Re-check when Tauri moves off GTK3 on Linux (tracked upstream in tauri-apps/tauri).braces<= 3.0.3 — stack-exhaustion DoS on deeply nested patterns (GHSA-vfj7-8cjw-p6xm, high, CVSS 7.5). The DoS needs an attacker-supplied brace pattern, and the only thing that reachesbraceshere isstylelint(viaglobby/fast-glob/micromatch) expanding thesrc/**/*.csspattern written in this repo. No patched release exists (3.0.3 is the latest published version), and dropping the dependent, as@vitest/uiwas dropped forflattedin v0.5.4, is not an option: CSS lint runs in CI and pre-commit, and currentstylelint(17.16.0) still depends on the same chain. Re-check whenbracespublishes a fix: lock-file maintenance picks it up and the gate's stale---ignorewarning says to remove this entry.
Resolved entries for the record: rand 0.7.3 GHSA-cq8v-f236-94qc (from the pre-2026 lockfile)
no longer applies — its pinning chain left the tree with the Tauri 2.x migration; quick-xml
RUSTSEC-2026-0194/0195 (CVSS 7.5) were remediated by bumping plist to 1.10.0 rather than
accepted.
Required Tooling¶
- Python:
uv,pip-audit - Node:
npm audit+ the gatescripts/ci/npm_audit_gate.py(unit-tested intests/ci/) - Rust:
cargo audit+ the CVSS gatescripts/ci/cargo_audit_gate.py(unit-tested intests/ci/) - Automation: Renovate for version updates (org preset
github>fiberpath/renovate-config, configured viarenovate.json); Dependabot security alerts/updates remain enabled; scheduled dependency audit workflow (.github/workflows/dependency-audit.yml)
CI and Artifact Requirements¶
- Dependency audit workflow must run on PRs to
main, pushes tomain, and weekly schedule. - PRs must not merge over unresolved blocking findings in any ecosystem — High/Critical for Rust and Node, any advisory for Python — per CI audit gating.
- Audit report artifacts (JSON) must upload on every run, pass or fail (
if: always()). - Release workflow must publish SBOM artifacts for Python, Node, and Rust.
Documentation and Traceability¶
- Roadmap and release source of truth:
CHANGELOG.md,docs/development/roadmap.md, anddocs/development/feature-backlog.md. - Release-level summary:
CHANGELOG.md. - CI architecture reference:
docs/development/ci-cd.md.