Versioned Publish Boundaries and Compatible Change¶
Page Maps¶
graph LR
family["Reproducible Research"]
program["Deep Dive Snakemake"]
section["Publishing Downstream Contracts"]
page["Versioned Publish Boundaries and Compatible Change"]
capstone["Capstone evidence"]
family --> program --> section --> page
page -.applies in.-> capstone
flowchart LR
orient["Orient on the page map"] --> read["Read the main claim and examples"]
read --> inspect["Inspect the related code, proof, or capstone surface"]
inspect --> verify["Run or review the verification path"]
verify --> apply["Apply the idea back to the module and capstone"]
Once you know which files belong in the public contract, the next question appears:
how do downstream users know when that contract has changed?
That is the job of versioned publish boundaries.
Versioning is not a cosmetic folder name. It is how a workflow tells the downstream world whether paths, payloads, and expectations are still stable.
publish/v1/ is a promise, not a convenience path¶
When a workflow publishes under a path such as publish/v1/, it is saying:
- the files in this boundary are intentionally public
- their paths and meanings are being treated with compatibility discipline
- downstream users should not have to guess whether a change is safe
That is much stronger than simply storing outputs in a neat folder.
Why versioning belongs to publish design¶
Without a versioned boundary, small publish changes become dangerous:
- a stable filename disappears
- a JSON field is removed
- a report path moves
- a manifest changes shape
Each change may feel local to the author. To downstream users, those are contract changes.
Versioning makes that change visible instead of surprising.
One useful distinction: compatible change versus contract change¶
Not every improvement requires a new publish version.
Some changes are often compatible:
- adding a new optional JSON field
- improving report styling without changing report location or core purpose
- adding more documentation around the published bundle
Some changes are usually contract changes:
- renaming a published file
- removing a field consumers may already use
- changing a path that scripts or notebooks are expected to read
- changing the semantics of an existing artifact without signaling it
That is the judgment this page is trying to sharpen.
A simple compatibility map¶
flowchart TD
change["publish change proposed"] --> ask1["does a stable path change?"]
ask1 -->|yes| version["treat as versioned contract change"]
ask1 -->|no| ask2["does existing meaning change?"]
ask2 -->|yes| version
ask2 -->|no| compat["likely compatible within current version"]
This is not a legal standard. It is a practical review tool.
The capstone example is already opinionated¶
The workflow contract guide explicitly treats publish/v1/ as the smaller public
boundary.
That means files such as:
summary.jsonsummary.tsvreport/index.htmlmanifest.jsonprovenance.jsondiscovered_samples.json
are expected to be reviewed as part of a versioned surface, not as loose outputs.
Weak version discipline¶
Weak shape:
- publish files are renamed casually
- one run adds extra artifacts with no contract discussion
- consumers are expected to “just update” when the bundle changes
This creates hidden downstream work and weakens trust in the bundle.
Strong version discipline¶
Strong shape:
- treat path stability as part of the public promise
- distinguish additive compatible change from breaking contract change
- bump the publish version when the old promise is no longer true
- document the meaning of the published files so reviews are concrete
This gives a workflow the same kind of discipline that software interfaces need.
A practical review test¶
Ask these questions:
- Would an existing downstream notebook still find the same path?
- Would an existing parser still understand the same payload meaning?
- Is the change additive, or does it alter an existing promise?
If the answer to the first or second question is no, treat the change as a contract change unless you can defend compatibility clearly.
Common failure modes¶
| Failure mode | What happens | Better repair |
|---|---|---|
| publish path renamed casually | downstream automation breaks silently | treat path renames as versioned contract changes |
| optional fields removed later | consumers lose information without warning | prefer additive evolution inside a version |
| report meaning changes without documentation | humans and tools interpret the bundle inconsistently | document artifact roles and change semantics deliberately |
new files appear in publish/v1/ with no review |
the boundary grows by drift rather than design | require a downstream-use reason for new public artifacts |
| version number never changes because change feels small locally | accumulated drift breaks consumer trust | use downstream compatibility, not author convenience, as the threshold |
The explanation a reviewer trusts¶
Strong explanation:
publish/v1/summary.jsonkeeps the same role and core fields, so this change is compatible inside the current version; if we rename the file or change the meaning of an existing field, we should publish under a new versioned boundary instead.
Weak explanation:
the structure changed a bit, but downstream users can adapt.
The strong explanation starts from the contract. The weak explanation pushes the burden onto consumers after the fact.
End-of-page checkpoint¶
Before leaving this page, you should be able to:
- explain why versioning belongs to publish boundaries rather than only release notes
- distinguish an additive compatible change from a contract-breaking change
- explain why path renames are often publish-boundary changes
- describe when a new publish version is the honest repair