Skip to content

test: execute the two rule-one residuals instead of describing them - #128

Merged
lesnik512 merged 1 commit into
mainfrom
test/catalogue-rule-one-residuals
Sep 20, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
test/catalogue-rule-one-residuals

Conversation

@lesnik512

@lesnik512 lesnik512 commented Sep 20, 2026

Copy link
Copy Markdown
Member

Closes #127.

The gap

ADR-0006 calls rule one hard — accepted(compose2pod) ⊆ accepted(docker), no exceptions — and #87 records two exceptions, parked as a deliberate ruling. Nothing measured them.

The harness looks like it covers this. It does not: corpus/depends_on_unknown.yaml puts the ghost dependency on the target, where startup_order's closure walk catches it. The residual needs it on a service the closure never reaches, and no corpus file does that. Measured against docker compose config v5.1.2, both halves reproduce:

ghost  docker: REJECT (service "other" depends on undefined service "ghost")
cycle  docker: REJECT (dependency cycle detected: a -> b -> a)
ghost  compose2pod: ACCEPT  <- forbidden combination
cycle  compose2pod: ACCEPT  <- forbidden combination

Neither could live in corpus/, because assert_rule raises on exactly that combination. So the one known breach of the one hard rule rested on prose in an ADR and an issue body — the position rule two was in before #109.

What this adds

corpus_residual/ plus assert_residual, the inverse of assert_rule: the forbidden combination is the expected result, and the run prints it.

==== conformance: rule-one residuals (docker rejects, compose2pod accepts) =====
tests/conformance/test_residuals.py::test_a_catalogued_residual_still_breaks_rule_one[depends_on_cycle_outside_closure]
tests/conformance/test_residuals.py::test_a_catalogued_residual_still_breaks_rule_one[depends_on_ghost_outside_closure]
2 residual(s) -- the hard rule, knowingly broken; https://github.com/modern-python/compose2pod/issues/87

This closes no residual and does not argue with the ruling in #87. It makes the ruling checkable.

(Wording edited after merge: the original sentence read "does not fix #87", and GitHub's closing-keyword parser ignored the negation and closed that issue. Reopened.)

Two properties, both verified by running them rather than asserted

property proof
a residual that closes fails the test dropped corpus/depends_on_unknown.yaml (which compose2pod does reject) into corpus_residual/: AssertionError: compose2pod now rejects this document -- the residual is closed, delete the file
an uncatalogued residual still fails dropped the ghost document into corpus/: AssertionError: docker compose config REJECTS this document but compose2pod ACCEPTS it

The first is the point. A catalogue that merely tolerates its entries goes stale in the direction that looks green, which is how #86's unmeasured claim survived long enough to ship. The second is what keeps the hard rule hard everywhere it is not deliberately suspended — an exemption costs a file someone has to add on purpose.

The residuals print in their own section rather than joining the over-rejection list: an over-rejection is allowed by the rule, a residual is the rule being broken, and merging them would blur the two directions the harness exists to keep apart.

Not covered

A residual widening — a third false green of the same shape — is still caught only if something probes it. That is the generated matrix's one-key-one-service limit, not this mechanism's, and #127 says so.

Verification

  • just lint, just test-ci: green, 100% line coverage held.
  • just test-conformance against real docker: 867 passed (up 2), 6 over-rejections — unchanged from the main baseline — and the 2 residuals now printed.

`accepted(compose2pod) subset-of accepted(docker)` is the hard rule, and issue
87 records two exceptions to it. Neither could live in `corpus/`, because
`assert_rule` raises on exactly that combination, so the one known breach of
the hard rule rested on prose.

`corpus_residual/` holds both documents and `assert_residual` asserts the
breach is still real, printing it in the terminal summary. It fails when a
residual closes: a catalogue nobody re-runs goes stale in the direction that
looks green. Every document outside that directory still goes through
`assert_rule`.

Closes #127
@lesnik512
lesnik512 merged commit b8603da into main Sep 20, 2026
10 checks passed
@lesnik512
lesnik512 deleted the test/catalogue-rule-one-residuals branch September 20, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The two rule-one residuals are held in prose; the conformance harness never probes them Validate the depends_on graph outside the target's closure

1 participant