Skip to main content

constitution-overlay

DOI License: MIT Python 3.11+

Kustomize-style merge of YAML rule layers + halt-on-reject enforced executor-side.

A small, framework-agnostic Python library (~300 lines) that gives agentic systems two things:

  1. A layered constitution — constitution.yaml defines invariants; corrections.yaml overrides specific values for the current run. Rightmost-wins merge, same semantics as Kustomize.
  2. Executor-side enforcement — @halt_on_reject wraps any function. When the check inside raises PolicyReject, the decorator propagates it unconditionally. The LLM cannot instruct the Python runtime to swallow a raise.

Why this matters: LLMs ignore system prompt instructions under task pressure. An executor-side decorator cannot be bypassed. See DESIGN.md for the full rationale.


Install

pip install constitution-overlay

Requires Python 3.11+. Only dependency: pyyaml.


Quick start

from constitution_overlay import Constitution, PolicyReject, halt_on_reject

# 1. Build a merged constitution from two layers
constitution = Constitution.from_layers(
    {
        "brand": {"prohibited_terms": ["cheap", "cheapest"]},
        "limits": {"max_files_per_commit": 50},
    },
    {
        "limits": {"max_files_per_commit": 200},  # override for this run
    },
)

# 2. Enforce rules executor-side
@halt_on_reject(constitution)
def commit_files(files: list[str]) -> None:
    limit = constitution.get("limits.max_files_per_commit")
    if len(files) > limit:
        raise PolicyReject(f"too many files: {len(files)} > {limit}")

commit_files(["a.py", "b.py"])  # OK
commit_files(["x.py"] * 300)    # raises PolicyReject — cannot be bypassed

See examples/basic_usage.py for a complete runnable example.


Load from YAML

# constitution.yaml
brand:
  prohibited_terms:
    - cheap
    - cheapest
limits:
  max_files_per_commit: 50
  no_force_push: true
# corrections.yaml
limits:
  max_files_per_commit: 200   # override for this large-batch run
from constitution_overlay import Constitution

c = Constitution.from_layers(
    Constitution.from_yaml("constitution.yaml").rules,
    Constitution.from_yaml("corrections.yaml").rules,
)
print(c.get("limits.max_files_per_commit"))  # 200
print(c.get("limits.no_force_push"))          # True — inherited from base

API

# Load
Constitution.from_dict(d: dict) -> Constitution
Constitution.from_yaml(path: str | Path) -> Constitution
Constitution.from_layers(*layers: dict) -> Constitution   # rightmost-wins merge

# Query
c.rules                    # post-merge dict
c.get(key, default=None)   # dot-notation: "brand.prohibited_terms"
c.has(key) -> bool

# Enforce
@halt_on_reject(c)
def agent_action(...): ...   # PolicyReject raised inside propagates unconditionally

# Exceptions
class PolicyReject(Exception): ...

ConstitutionContext is also exported for use inside wrapped functions — a read-only view over c.rules with the same get/has interface.


Merge semantics

  • Dicts merge recursively — a later layer overrides specific keys without clobbering siblings.
  • Scalars and lists are replaced by the rightmost value (list-append directive is on the v0.2 roadmap).
  • None is a valid explicit value and survives the merge.
  • Type mismatches raise TypeError immediately rather than silently coercing.

Project layout

src/constitution_overlay/
    __init__.py       # public exports
    constitution.py   # Constitution class + YAML loading
    corrections.py    # deep_merge + merge_layers
    executor.py       # halt_on_reject, PolicyReject, ConstitutionContext
tests/
    test_constitution.py
    test_executor.py
    test_merge.py
    test_smoke.py
examples/
    basic_usage.py

Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

.venv/bin/pytest tests/ -q          # 69 tests
.venv/bin/mypy --strict src/        # must be clean
.venv/bin/ruff check src/ tests/    # must be clean

See CONTRIBUTING.md for the full contribution guide.


License

MIT — see LICENSE.

Metadata

Release files for constitution-overlay 0.1.2

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

Source distribution (sdist)

Source distribution for constitution-overlay 0.1.2
File Size Uploaded Provenance Actions
constitution_overlay-0.1.2.tar.gz 19.6 kB With provenance Details for constitution_overlay-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for constitution-overlay 0.1.2
File Interpreter ABI Platform Actions
constitution_overlay-0.1.2-py3-none-any.whl Python 3 none any Details for constitution_overlay-0.1.2-py3-none-any.whl

Total release size: 28.0 kB

Release files / constitution_overlay-0.1.2.tar.gz

Download URL constitution_overlay-0.1.2.tar.gz
Size 19.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8c20941a5ca13de05e45db5e3b283899c301bf54880fb59b746d3f58f19b064c
BLAKE2b-256 checksum
How to use checksums
28ad008db2cbf22f393cdf3ece2ddf2cad0132f5e082bb9aedc362fd53268345
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 Sep 10, 2026.

Transparency log

Release files / constitution_overlay-0.1.2-py3-none-any.whl

Download URL constitution_overlay-0.1.2-py3-none-any.whl
Size 8.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
733c3e3a720eb3298cebba0623daa3e7e3698469b2bee8bbaa33dfb652533a85
BLAKE2b-256 checksum
How to use checksums
457741bacdbc95270a3ed3952f2f60a96c95e721b2b408ce9058af66bebe72e4
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 Sep 10, 2026.

Transparency log

Security for constitution-overlay 0.1.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for constitution_overlay-0.1.2.tar.gz

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 Sep 10, 2026.

Transparency log

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.2 This release

2 release files Full 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