v0.3.5
Changed
- Runtime Docker image switched from
python:3.13-alpineto
gcr.io/distroless/python3-debian13:nonroot. The image no longer
ships/bin/sh,apk, or busybox — only the Python interpreter,
stdlib, libc, and the project venv. Attack surface in the event of
a container escape is significantly reduced. See
ADR-009 for the rationale. docker runexamples in the README now show--read-only --cap-drop ALL --security-opt no-new-privileges --network nonewith a
read-only mount, modelling the least-privilege posture the linter
itself recommends. The simpler form still works.
Fixed
- Parser post-YAML traversals (
_collect_lines,_strip_lines) no
longer recurse one Python frame per nesting level, so pathologically-
deep input raisesComposeError(or lints cleanly) instead of
crashing with an uncaughtRecursionError. Found by ClusterFuzzLite.
Security
- Dockerfile sets
USER 65532:65532explicitly at the runtime stage.
Distroless:nonrootalready enforces this; the redundancy survives
a future base-image swap that might not default to nonroot.
No CLI, config, or finding-shape changes. Exit codes (0/1/2) are
preserved. A Compose file that passed on 0.3.4 passes identically on
0.3.5.