A Scarab Diagnostic Suite field test just landed upstream in Docker Compose.
PR: https://github.com/docker/compose/pull/13831
Issue: https://github.com/docker/compose/issues/13613
Status: merged
The fix is small in shape, but important in meaning.
It repairs a failure in how Docker Compose handled variable discovery for Compose files that still contained ${...} interpolation expressions inside typed fields, especially in remote stack paths such as oci://... Compose applications.
The specific bug appeared when Compose tried to discover interpolation variables from a Compose model that had not yet been fully resolved.
That model could contain values like:
ports:
- host_ip: "${LXKNS_ADDRESS:-127.0.0.1}" published: "${LXKNS_PORT:-5010}"
Those values are valid as unresolved Compose expressions.
But they are not yet valid concrete typed values.
host_ip eventually needs to be an IP address.
published eventually needs to resolve into a port value.
The problem was that validation was running before the interpolation-variable discovery path had finished doing the work needed to make validation meaningful.
So Compose failed early with an error like:
invalid ip address: ${LXKNS_ADDRESS:-127.0.0.1}
The important part is not only that the command failed.
The important part is why it failed.
The hypothesis
The Scarab hypothesis is that many software failures are not best understood as “bad code” first.
They are often boundary failures.
A system has phases.
A system has ownership surfaces.
A system has claims that are allowed to be true in one phase and not yet true in another.
A value may be valid as an unresolved expression before it is valid as a typed runtime value.
A generated artifact may be valid as output but not as source truth.
A test may be valid as regression evidence but not as permission to rewrite behavior.
A config may describe intent before runtime has resolved it into concrete state.
When the wrong boundary enforces at the wrong time, the system can fail even though the pieces involved are each doing something reasonable in isolation.
That is what made this Docker Compose issue diagnostically interesting.
It was not that validation was bad.
Validation is necessary.
It was not that interpolation was bad.
Interpolation is necessary.
The failure was that the validation boundary was being applied during a phase where unresolved interpolation expressions were still supposed to exist.
The boundary was firing too early.
The user-facing shape
The issue came from a real Compose application distributed through an OCI artifact.
That matters because this was not a theoretical parser edge case.
The workflow was:
A Compose application is published.
A consumer deploys it from an oci://... URL.
The Compose file contains interpolation variables so the consumer can customize deployment values.
Compose needs to discover those variables, prompt or resolve them, and then continue.
Instead, typed-field validation saw unresolved ${...} values too early and treated them as invalid concrete values.
So a remote Compose application that should have been customizable failed before the customization path could complete.
That is the kind of failure Scarab is built to care about.
Not just “command errored.”
But:
Which phase owned this value at the moment it failed?
Was ${LXKNS_ADDRESS:-127.0.0.1} supposed to be treated as an IP address yet?
Or was it still supposed to be treated as an unresolved interpolation expression?
That question identifies the repair surface.
The boundary
The boundary was between:
interpolation-variable discovery
and
typed Compose model validation
Those are not the same operation.
Variable discovery needs to inspect unresolved expressions.
Typed validation needs to validate resolved values.
When validation runs too early, it rejects the exact thing discovery is supposed to find.
That is the contradiction.
So the repair was not “turn validation off.”
That would be too broad.
The repair was:
load unresolved models with validation skipped only for variable-discovery paths.
That distinction matters.
Validation remains part of the system.
But variable discovery gets to happen before validation treats templated typed fields as concrete runtime values.
The patch
The merged PR applies loader.WithSkipValidation to the specific Compose loading paths used for interpolation-variable extraction.
It covers:
- interpolation-variable extraction from unresolved models
- docker compose config --variables
- remote-stack interpolation-variable prompting
- regression coverage for templated typed port fields such as host_ip and published
- a test-only remote loader override so the remote-stack case can be tested deterministically
The patch touched five files:
- cmd/compose/options.go
- cmd/compose/config.go
- cmd/compose/compose.go
- cmd/compose/options_test.go
- cmd/compose/up_test.go
That is the repair shape I want to keep emphasizing:
Find the boundary.
Provide the context and evidence.
Apply the narrow patch.
Let the win trickle down.
Why this is a good field test
This is a good Scarab field test because the fix is not dramatic.
It does not rewrite Compose loading.
It does not change the meaning of typed validation globally.
It does not broaden remote stack behavior beyond the failing path.
It restores the order of responsibility.
Variable discovery gets to read unresolved interpolation expressions.
Validation gets to validate once values are in the phase where validation has authority.
That is the core of the diagnostic theory.
A lot of software drift comes from systems forgetting which layer owns which truth at which moment.
Sometimes the repair is not to add a new abstraction.
Sometimes the repair is not to make the system more permissive everywhere.
Sometimes the repair is to restore the sequence of authority.
This value is still an expression.
This phase is still discovery.
This validator does not own the value yet.
That is the whole bug.
Why this matters beyond Docker Compose
This is why I keep saying that Scarab is not only about AI-assisted code.
AI makes drift faster and more visible, but software drift is older than AI.
Human-built systems drift too.
Complex systems drift when phases blur, when contracts move, when generated artifacts gain authority they should not have, when tests begin proving the patch instead of the behavior, or when validation starts enforcing a claim before the system has reached the phase where that claim can be true.
Docker Compose is a serious developer tool.
This was a human-built, mature codebase.
The bug was still a boundary failure.
That is the point.
Scarab Diagnostic Suite is a proprietary diagnostic system for software drift. It can be used against AI-assisted development, but the deeper theory is broader: diagnose where a software system stopped preserving the truth another part depended on.
In this case, the truth was simple:
An unresolved interpolation expression is not yet a concrete typed field.
Once that was clear, the repair became narrow.
Evidence before repair
The field-test posture matters.
The goal was not to throw a patch at the wall.
The goal was to identify the boundary and make the smallest change that restored it.
The validation for the PR included:
go test ./cmd/compose
docker buildx bake lint
The regression tests were part of the claim.
They prove that templated typed port fields no longer break variable extraction and that remote-stack prompting can handle the unresolved model path.
That is the difference between a patch and a diagnostic repair.
A patch says: “This seems to work.”
A diagnostic repair says: “This is the boundary that failed, this is the evidence, this is the narrow change, and this is the validation that protects the claim.”
The public record
This PR has now merged into Docker Compose.
That makes it a useful public proof point for the larger Scarab hypothesis.
Not because every field test will merge.
Not because every diagnostic claim becomes an upstream patch.
But because this one shows the shape clearly:
A real issue in a major software platform.
A boundary failure.
A narrow repair.
Regression coverage.
Upstream acceptance.
That is the loop.
Scarab Diagnostic Suite finds evidence.
People make claims.
Maintainers decide.
Field Lab
Scarab Systems maintains a public Field Lab for selected diagnostic field tests.
The Field Lab publishes public case records from real open-source issues: the issue being examined, the suspected boundary, the evidence gathered, the validation performed, and the current status of the diagnostic claim.
Some cases may end with a local repair candidate.
Some may become upstream pull requests.
Some may remain diagnostic records only.
That status is part of the record.
Scarab Diagnostic Suite is proprietary, but the larger conversation is shared. Software drift is not one team’s problem, and AI-assisted development is making the need for better diagnostic framing more urgent across the industry.
If you know of a public open-source issue that looks like cross-layer drift, unclear ownership, phase confusion, AI-assisted codebase confusion, or a boundary failure, you can suggest it as a Field Lab candidate.
Useful suggestions include the public issue link, the suspected boundary, reproduction notes if available, and why the issue may be diagnostically interesting.
The goal is simple:
Make the failure legible.
Find the boundary.
Preserve the evidence.
Repair narrowly.
Let the win trickle down.
Top comments (0)