Skip to main content

promises

Declare the contracts your repos share, so agents and people read them before changing them.

A promises.yaml at the root of a multi-repo workspace lists every value one repo produces and another consumes: a Firestore field, a Pub/Sub topic, an HTTP route, an environment variable. Each row carries one line of meaning and one line of invariant. That is the whole idea. There is no graph, no server, no hook. A one-line pointer in your agent instructions file is the integration.

promises.yaml          # the declarations (see SPEC.md)
promises.schema.json   # JSON Schema for editors and the lint
promises check         # a lint: every row has meaning + invariant, writer files exist, keys still appear in them

Why it exists

Picture a parking operator's platform split across a few repositories: a web app the operators use, a mobile app the drivers use, and a handful of cloud functions that copy documents from the shared Firestore into PostgreSQL for billing. The web app writes a sessions/{plate} document with a boolean is_parked. The app's "parked now" screen is one equality query on that field.

The rule that is_parked is true only while the session has no end time lives in exactly one place: the body of the function that computes it. One day a refactor rebuilds that payload inline, drops the helper, and writes is_parked: True, because every session the new code path sees is, at that moment, being started. Nothing fails. The app keeps showing cars as parked after they leave, and the first person to notice is a driver disputing a bill months later.

The field had writers in two repositories and a reader in a third, and no file anywhere said what it meant. That is the gap promises.yaml fills: one row, one meaning, one invariant, read by whoever is about to change a writer.

The obvious fix looked like a tool: a cross-repo contract graph, a server to query it, and a pre-edit hook that warns an agent "this field has consumers in another repo". We wrote the plan for that tool and then tested whether it was needed before building it.

What the experiment showed

On a private multi-repo workspace where a flag of exactly this shape had drifted, fresh planning agents were given the original refactor task, on a snapshot of the code at the commit before the incident, with the sibling repos visible. Nothing in the prompt mentioned the flag or its invariant.

Setup Found the consumer in the other repo Preserved the invariant
Instructions file only, as it was 1 of 3 3 of 3, by reusing the old function body
+ one sentence: "grep the sibling repos for consumers before finalising" 3 of 3 3 of 3
Harder prompt that asks for the payload rebuilt inline, the helper dropped and the flag set on the way through, sentence only 3 of 3 3 of 3 (one as a literal True inside a gate)
Same prompt + promises.yaml present and pointed to 4 of 4 4 of 4, each citing the row by line

One of the four runs with the file present was wrapped as a compacted session whose summary claimed orientation was already done. It still found the file, by listing the root directory, not by reading the pointer.

By the decision rule fixed before the runs, the hook lost to a YAML file. Declarations plus one sentence became v1, and the tool was never built.

Read the caveats. Seven runs, one codebase, one model, one afternoon. The field under test also had a one-line warning in the instructions file in every arm, so the experiment cannot separate "a declarations file" from "a well-aimed sentence about that one field". What the file demonstrably added was form, every run wrote the derivation and none wrote a literal, and reach: the runs also applied rows for fields the instructions file never mentioned, and raised the rows marked unknown as questions for the maintainer.

Use it

  1. Copy examples/promises.yaml to your workspace root and replace the rows with yours. Start with the fields that have bitten you.

  2. Add to your CLAUDE.md / AGENTS.md:

    Cross-repo contracts and their invariants are declared in promises.yaml. Read the relevant rows before changing any field, topic, or route listed there.

  3. In CI, from the workspace root:

    uvx --from promises-yaml promises check
    

    It fails when a row lacks meaning or invariant, when a written_by glob matches no file, when two rows share an id, or when a declared key no longer appears in any of its writer files.

Where you cannot state an invariant, write invariant: UNKNOWN — <owner> to confirm. Agents treat that as a question to raise, which is the right behaviour.

What it is not

Not a scanner: consumers are found by grepping, which the sentence tells the agent to do. Not a schema registry: schema: may point at a JSON Schema or a model file, but the lint does not read it. Not a hook: if you need an edit-time interrupt, the experiment above is the reason we did not build one; your codebase may differ.

Licence

MIT.

Metadata

Release files for promises-yaml 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for promises-yaml 0.1.1
File Size Uploaded Provenance Actions
promises_yaml-0.1.1.tar.gz 51.0 kB Without provenance Details for promises_yaml-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for promises-yaml 0.1.1
File Interpreter ABI Platform Actions
promises_yaml-0.1.1-py3-none-any.whl Python 3 none any Details for promises_yaml-0.1.1-py3-none-any.whl

Total release size: 58.0 kB

Release files / promises_yaml-0.1.1.tar.gz

Download URL promises_yaml-0.1.1.tar.gz
Size 51.0 kB
Tags Source
SHA-256 checksum
How to use checksums
93b9dd143d83aafc3682b8f2bdd17258dcc2f6eb1f433aa081568a23513cd370
BLAKE2b-256 checksum
How to use checksums
eae704e78c6ad2907d4382f8abaacfc0786b1dd3ce4992df3c49141acc5763e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / promises_yaml-0.1.1-py3-none-any.whl

Download URL promises_yaml-0.1.1-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
406ccd4aeecc052894662dffc22d977851db7b93c2a0c655d877b8586e59ce42
BLAKE2b-256 checksum
How to use checksums
cf01f4d39bf3d110c5721f094da286434dd2c15da16cd71ae383c2f69988c20b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for promises-yaml 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

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