boundver
A Git-aware lockfile and CI check for contracts shared across components.
This README follows main; its examples can reference a version still in
development. Check the latest published release
for available packages, Action tags, and download assets. For that version's
instructions, read the README at its release tag.
Did we change something other teams depend on?
Declare what each component publishes and who consumes it. Boundver records those declarations in a lockfile committed with the code. In CI, it compares that lockfile with an exact Git snapshot and reports:
- what kind of declared contract changed;
- which direct or transitive consumers may need verification; and
- enough machine-readable output to route the next check.
Boundver does not replace a compiler, build graph, compatibility checker, or consumer test. It supplies the repository-level signal that connects them.
Try it in one minute
Run this in a Git repository with tracked code under src/:
python -m pip install "boundver[schema,yaml]"
boundver init
boundver validate-config
boundver generate --source working-tree
boundver verify --source working-tree --facets exact
boundver coverage --source working-tree
Review and commit boundary.config.json and boundary.lock.json together.
coverage separately reports tracked files that boundary/behavior selectors
or component roots do not reach; add --strict when CI should gate on them.
Plain boundver init creates a placeholder component rooted at src/. For a
different layout, use boundver init --discover and review its proposal, or
edit the generated component path before validation. Add a real boundary,
version source, and consumers before gating those signals.
For a runnable repository and expected output, use the one-minute demo.
The gap between existing tools
A compiler protects the code it understands. In a repository with a Python service, a TypeScript client, generated OpenAPI, and JSON Schema, a shared contract can cross language and build-system boundaries.
Git reports changed files. A build graph schedules known targets. A format-specific checker can judge one schema family. Boundver records which artifacts form each component's contract and who consumes them, so CI can send the changed contract to the appropriate checks.
Four signals, one result
Each component can provide up to four facets. More than one facet can change in the same comparison.
| Facet | What changed | Exit code when gated |
|---|---|---|
exact |
Tracked content, path, or file identity; text CRLF/LF are equivalent | 1 |
behavior |
A declared runtime-relevant input | 3 |
boundary |
A declared published artifact | 4 |
compat |
The configured compatibility family | 5 |
Exit 0 means no unacknowledged gated facet drift remains. With a verification
baseline, acknowledged drift can still be present. Exit 2 means boundver
could not complete the check reliably, such as when configuration, history, or
declared files are missing. When several gated facets drift, the highest
applicable drift code is returned.
A common policy is to gate boundary and compat, report the other signals,
then run a format-specific compatibility check and the affected consumer suites.
See exit-code handling
and the comparison guide.
What it will not tell you
Boundver reports drift in what you declared. It does not decide whether a change breaks a consumer, run consumer tests, or discover dependencies. Files left out of a selector are invisible to that facet.
A clean result means no unacknowledged gated drift remains. With a verification baseline, acknowledged lock drift can still be present. It does not prove backward compatibility or guarantee that every consumer is safe. Use oasdiff, Buf, GraphQL Inspector, compilers, and consumer tests for the judgments they are designed to make.
A practical configuration
{
"$schema": "https://raw.githubusercontent.com/yzm1/boundver/v0.16.0/boundary.config.schema.json",
"project": "payments-platform",
"defaults": {
"compat_mode": "major",
"verify_facets": ["boundary", "compat"]
},
"components": {
"payment-api": {
"path": "services/payment",
"version_source": {"file": "package.json", "field": "version"},
"boundary": {
"provider": "openapi-canonical",
"paths": ["openapi/**/*.yaml"]
},
"behavior": {
"paths": ["openapi/**/*.yaml", "config/**/*.json"]
},
"consumers": ["checkout-web"],
"external_consumers": ["external-risk-service"]
},
"checkout-web": {
"path": "apps/checkout",
"version_source": {"file": "package.json", "field": "version"},
"boundary": {"provider": "leaf", "paths": []},
"verify_facets": ["exact"]
}
},
"slices": {
"checkout-contracts": {
"description": "Contracts required by checkout",
"mode": "boundary",
"components": ["payment-api"]
}
}
}
This records one API boundary, one direct internal consumer, one external consumer, and a named slice. Paths are repository-relative for components and component-relative inside boundary, behavior, and version declarations. Compatibility versions may also inherit another configured component or use an explicit SemVer constant when no tracked manifest or tag owns the identity.
The configuration reference documents providers, selectors, source modes, facets, and graph limits. The glossary defines the terms used throughout the project.
Reconcile a branch, then review the range
review compares reconciled checkpoints. Both endpoint commits must already
contain locks that match their source trees.
# Inspect the candidate before accepting its drift.
boundver verify --source working-tree
boundver why payment-api --source working-tree
# Record intentional drift, inspect the lock change, and commit the checkpoint.
boundver verify --source working-tree --update
git diff -- boundary.lock.json
git add boundary.lock.json path/to/changed-file
git commit -m "chore: reconcile boundver lock"
boundver verify --source head
# Now compare the two reconciled commits.
boundver review origin/main..HEAD --merge-base --transitive
review is read-only and compares two immutable Git trees. verify remains
the integrity gate for the current candidate. Repositories that update locks
only periodically can review their reconciled checkpoints, but cannot use an
unreconciled pull-request tip as a review endpoint. For generated boundaries,
declare a derivations receipt so verification fails when either its inputs or
outputs move without fresh evidence; see
troubleshooting.
GitHub Actions
Pin the Action to the same release used to write the lock:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: yzm1/boundver@v0.16.0
with:
operation: verify
source: head
Omitting facets applies each component's configured verify_facets policy.
The CI cookbook covers GitHub, GitLab, pre-commit, range review, outputs, and shallow-history failures.
Install and run
- PyPI:
python -m pip install "boundver[schema,yaml]" - GitHub Action: Marketplace
- GitLab CI/CD: Catalog project
- Container:
docker run --rm ghcr.io/yzm1/boundver:0.16.0 --version - Homebrew:
brew install yzm1/boundver/boundver - Standalone archive: download
boundver-0.16.0.pyzfrom GitHub Releases
The project supports Python 3.10 or newer and Git 2.32 or newer. Boundver checks the selected Git version and its process-local security configuration before inspecting a repository. Partial clones additionally require Git 2.45 or newer. Release channels and least-privilege container use are documented in the distribution guide.
Trust and privacy
The built-in boundver CLI is telemetry-free. It does not send source, usage, analytics, update checks, or crash reports anywhere. Custom Python providers are explicitly enabled trusted code and are outside that built-in guarantee.
Read the privacy policy, the security model, and the normative specification.
Using or evaluating boundver? You can identify yourself voluntarily in the adopter discussion.
Project
Boundver is beta software under the MIT license. Issues and pull requests are welcome. Start with CONTRIBUTING.md; maintainers should use the checked-in release process.
The changelog records user-visible changes. The v0.16 line is focused on declaration coverage, security hardening, and making the public documentation easier to use. Semantic-provider implementation remains separately gated work for a later release.
Metadata
Release files for boundver 0.16.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| boundver-0.16.0.tar.gz | 2.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| boundver-0.16.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.1 MB
Release files / boundver-0.16.0.tar.gz
| Download URL | boundver-0.16.0.tar.gz |
|---|---|
| Size | 2.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ba7cdc43ba8bdf4ac6c48ea396dbbcef401f7bb2d4b19d4d164da1caf141eb16
|
|
BLAKE2b-256 checksum How to use checksums |
09a77d79a6da0bbc3afa588a268f9dcadbbeddf9d293b8c39e5cc944beb1aeed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency logRelease files / boundver-0.16.0-py3-none-any.whl
| Download URL | boundver-0.16.0-py3-none-any.whl |
|---|---|
| Size | 1.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
751097181ef8f753f45e151d338a8ec20c13ffb71815335c3c0c114d8d02c37b
|
|
BLAKE2b-256 checksum How to use checksums |
2ba25cb02fe763e2048b5c22832d190de48db8dbbf8b5ddad58ca8143cccb761
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency log