You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Validate the depends_on graph outside the target's closure #87
The hard rule in docs/adr/0006-docker-rejection-parity.md is accepted(compose2pod) ⊆ accepted(docker), no exceptions. This is its one known
residual, and it is a deliberate maintainer ruling, not an oversight: closing it
fights compose2pod's own validation design rather than completing an unfinished
parser (contrast issue 1, which is a genuine gap).
Two false greens survive, both measured against docker compose config v5.1.2 with
the same YAML given to both oracles:
depends_on: [ghost] on a service OUTSIDE the target's dependency closure,
naming a service nothing in the document defines — Docker REJECTS the whole
document ("undefined service"); compose2pod ACCEPTS it and runs successfully,
because the target never reaches ghost's declaring service in its closure walk.
A dependency cycle among services OUTSIDE the target's closure — Docker
REJECTS the whole document; compose2pod ACCEPTS it, same reason.
Why it is open rather than fixed.validate() (compose2pod/parsing.py) checks
every depends_on entry's condition document-wide (_validate_depends_on), but
never cross-checks a dependency name against the full service set. That check
happens only inside startup_order (compose2pod/graph.py), which walks exclusively
the --target service's own depends_on closure and raises if a dependency names a
service absent from the document. A service outside that closure never runs, by
design — profiles inertness and the closure-authoritative stance both already lean
on the same fact — so its own depends_on graph, however broken, can never desync a
running script from the document. Validating it anyway means a document-wide pre-pass
wholly independent of --target, cutting against the one design choice
(closure-scoped, not whole-document validation) that makes the gate cheap to reason
about and keeps an unrelated service's typo from blocking every other target in a
shared compose file.
Proposed shape: a document-wide pre-validation pass over depends_on existence
and cycles, run independently of the target closure — so it costs nothing extra for a
document where every service is well-formed, and only ever narrows acceptance for one
that is not. That closes both cases.
Revisit trigger: a user hits either case in practice — most likely the cycle,
since an unrelated-service typo is comparatively easy to notice by eye.
#128's body contained the sentence "This does not fix #87 and does not argue with the ruling". GitHub's closing-keyword parser matches fix #87 and does not read the negation in front of it, so merging the PR closed this issue.
Nothing about this residual changed. #128 added tests/conformance/corpus_residual/, which asserts the breach is still real and fails if it ever closes — the opposite of a fix. The ruling in this issue stands untouched.
Activity
lesnik512 commentedon Sep 20, 2026
Reopened: closed by accident, not by a fix.
#128's body contained the sentence "This does not fix #87 and does not argue with the ruling". GitHub's closing-keyword parser matches
fix #87and does not read the negation in front of it, so merging the PR closed this issue.Nothing about this residual changed. #128 added
tests/conformance/corpus_residual/, which asserts the breach is still real and fails if it ever closes — the opposite of a fix. The ruling in this issue stands untouched.