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 constitutionconstitution.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.

Download files

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

Source Distribution

constitution_overlay-0.1.2.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

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

constitution_overlay-0.1.2-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file constitution_overlay-0.1.2.tar.gz.

File metadata

  • Download URL: constitution_overlay-0.1.2.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for constitution_overlay-0.1.2.tar.gz
Algorithm Hash digest
SHA256 8c20941a5ca13de05e45db5e3b283899c301bf54880fb59b746d3f58f19b064c
MD5 a76f3a9c9776029cceefe24ceea73f6d
BLAKE2b-256 28ad008db2cbf22f393cdf3ece2ddf2cad0132f5e082bb9aedc362fd53268345

See more details on using hashes here.

Provenance

The following attestation bundles were made for constitution_overlay-0.1.2.tar.gz:

Publisher: release.yml on arnoldwender/constitution-overlay

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

File details

Details for the file constitution_overlay-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for constitution_overlay-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 733c3e3a720eb3298cebba0623daa3e7e3698469b2bee8bbaa33dfb652533a85
MD5 25401a3b9f1fdcd9803e2d8384c9ff8d
BLAKE2b-256 457741bacdbc95270a3ed3952f2f60a96c95e721b2b408ce9058af66bebe72e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for constitution_overlay-0.1.2-py3-none-any.whl:

Publisher: release.yml on arnoldwender/constitution-overlay

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

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

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