The Philosophical Developer -- Chapter 23: When the Ground Shifts
2026-07-10 · 6 min read

When the Ground Shifts
The Dagger pipeline in this series was the spine. Every chapter from 15 onward ran modules through it. Format check, validate, test, plan. The same four stages, the same isolated containers, the same Go SDK.
When I built the AWS pipeline, it worked on the first try. dagger.json in pipeline/, include: ["../infrastructure"], and the Dagger engine happily loaded it. I assumed this was the way it worked.
When I built the GCP pipeline two days later with the same structure, it broke immediately.
include/exclude path "../infrastructure" escapes context
The same dagger.json. The same engine version. The same intent. Different result. The engine had been updated between sessions and the include path security was tightened. Paths that escaped the module root were no longer allowed.
This is a chapter about what happened next. Not because the Dagger change was remarkable, but because the way we respond to tooling changes is remarkably consistent across every layer of the stack. And how we respond determines whether the change slows us down or teaches us something.
What Actually Happened
The AWS pipeline was generated with an earlier version of the Dagger engine. When I ran dagger develop on the GCP repo days later, the engine had auto-updated and the security constraint was tightened. The include path ../infrastructure was now rejected.
The Dagger changelog (dagger.io/changelog) describes this context explicitly. The include-path constraint is part of Dagger’s module sandbox model: modules cannot see project structure outside their root unless you thread it through manually. The upcoming Modules v2 (listed as “In development” in the changelog) replaces rigid sandbox constraints with a typed Workspace argument, which is exactly what would have made this transition seamless.
The fix was straightforward. Move dagger.json to the repo root. Change "include": ["../infrastructure"] to "include": ["infrastructure"]. Point the SDK path at pipeline/ so the Go source still lives in its own directory. Run dagger develop again. Done.
The change itself took five minutes to understand and two minutes to implement. The frustrating part was the discovery. I spent an hour trying variations of the same broken pattern before I stopped and looked at what the error was actually telling me.
That hour is the cost of assuming the ground is stable.
The Pattern
This is not a Dagger problem. It is a tooling problem that repeats across every category.
OpenTofu providers change their schemas between versions. An attribute that existed in v5.0 is renamed in v6.0. Floci adds new services and deprecates old endpoint paths. The AzureRM provider went through three major revisions in two years, each breaking something.
Every tool has a changelog. Most of us do not read changelogs until something breaks. The cost of reading the changelog proactively is low. The cost of discovering a breaking change through a failed build is high.
The asymmetry is what makes it painful. The changelog is free. The debugging session costs an hour.
How I Handle It Now
I have developed a habit. Before using a tool in a new context, I check the changelog for the last three months. Not the whole history. Just the recent entries that might affect what I am about to do.
For Dagger, I check https://dagger.io/changelog. For OpenTofu, the GitHub releases page. For Floci, the CHANGELOG.md in each repo.
The habit costs thirty seconds. In the Dagger case, it would have saved an hour.
The Deeper Lesson
The specific Dagger include path issue is already obsolete. The engine will change again, and the fix I applied will need to change with it. But the pattern of response is durable.
A change-resistant workflow has three layers:
Layer 1: Awareness. Know what changed before it breaks. Changelogs, release notes, deprecation warnings in your build output. The signal is there. The discipline is reading it.
Layer 2: Isolation. When something breaks, isolate the change from the context. The include path error was not about my module structure. It was about a security constraint in the engine. I spent the first thirty minutes looking at my Go code before I looked at the error message properly.
Layer 3: Adaptation speed. The faster you can try the fix, the faster you learn whether it works. In the Dagger case, the fix was to restructure the module root. I could have tried that in ten minutes instead of an hour if I had recognised the error pattern earlier.
The Philosophical Bit
Infrastructure tooling is not stable. It never was. The tools we used two years ago are not the tools we use today. The tools we use today will not be the tools we use in two years.
The methodology stays. The implementation changes.
The four pillars – reproducible, traceable, testable, safe – are not tool-dependent. They are independent of whether you use OpenTofu or Pulumi, Floci or real clouds, Dagger or GitHub Actions. The tools implement the pillars. The pillars do not depend on the tools.
When the ground shifts under one tool, you do not rebuild the pillars. You find a new tool that serves the same pillar.
A Proposal for the Workflow
I now keep a file in every project called CHANGE_LOG.md (lowercase, to distinguish it from the tool’s changelog). Every time a dependency update or tool change breaks something, I record:
- What changed
- What broke
- How I fixed it
- What I would check first next time
When I come back to the project months later, the file tells me what traps I already paid for. It is a crystallised version of the debugging session, readable in thirty seconds instead of repeatable in an hour.
I started this after the Dagger incident. It has already saved me on two other issues.
The Closing
Tools break. APIs deprecate. Providers change their schemas. Security constraints tighten. This is not a bug in the ecosystem. It is a feature of a living stack.
The question is not whether the ground will shift. It is whether you are standing in a way that lets you shift with it.
The four pillars are my foundation. Everything else is scaffolding.
Here I geek out with my young Padawan, OrsonRius.
Also on LinkedIn.