Skip to main content

boundver

Boundver boundary-event logo

A Git-aware lockfile and CI check for contracts shared across components.

CI Docs PyPI GitHub Marketplace GitLab Catalog Python 3.10+ License: MIT

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.

A boundver verification reports boundary drift and affected consumers

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

Review and commit boundary.config.json and boundary.lock.json together. 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.15.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.

The configuration reference documents providers, selectors, source modes, facets, and graph limits. The glossary defines the terms used throughout the project.

Review a branch before accepting drift

# Compare committed endpoints using pull-request merge-base semantics.
boundver review origin/main..HEAD --merge-base --transitive

# Verify the candidate snapshot.
boundver verify --source working-tree

# After review, update the lock and inspect the exact change.
boundver verify --source working-tree --update
git diff -- boundary.lock.json

review is read-only and compares two immutable Git trees. verify remains the integrity gate for the current candidate. Generated boundary artifacts need their own deterministic freshness check before verification; 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.15.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.15.0 --version
  • Homebrew: brew install yzm1/boundver/boundver
  • Standalone archive: download boundver-0.15.0.pyz from GitHub Releases

The project supports Python 3.10 or newer and requires Git. 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.15 line is focused on historical range review, security hardening, and making the public documentation easier to use. Semantic-provider implementation remains separately gated work for a later release.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

boundver-0.15.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

boundver-0.15.0-py3-none-any.whl (921.4 kB view details)

Uploaded Python 3

File details

Details for the file boundver-0.15.0.tar.gz.

File metadata

  • Download URL: boundver-0.15.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for boundver-0.15.0.tar.gz
Algorithm Hash digest
SHA256 4e123fda4466c691574eeb39479786979cc3dabe6362eccf0f41d5531464378b
MD5 04c4f8d9f48d93365d474865d85cebd1
BLAKE2b-256 6ee9b58df46ec78d20ee55b5c8487a4d73b89fceb44493e47b1c0ec70076e23e

See more details on using hashes here.

Provenance

The following attestation bundles were made for boundver-0.15.0.tar.gz:

Publisher: publish.yml on yzm1/boundver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file boundver-0.15.0-py3-none-any.whl.

File metadata

  • Download URL: boundver-0.15.0-py3-none-any.whl
  • Upload date:
  • Size: 921.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for boundver-0.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 de6c01534c6226ce5a10ebfc8ed78a7fc5d40baec1cbec59e96d898a2ff9c6e9
MD5 8e314d31fd3a3dcd2da50dc94d899d1b
BLAKE2b-256 9241c94aa2176350fccac064568d4e5a2805047b4c167f5f519bebb7659e9741

See more details on using hashes here.

Provenance

The following attestation bundles were made for boundver-0.15.0-py3-none-any.whl:

Publisher: publish.yml on yzm1/boundver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.15.2

2 files

This release

0.15.0 This release

2 files

0.14.1

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.1

2 files

0.9.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page