Route contracts for urirun connectors — declared output shape, effect class, reversibility and composition wires
Project description
urirun-contract
AI Cost Tracking
- 🤖 LLM usage: $0.6783 (36 commits)
- 👤 Human dev: ~$1400 (14.0h @ $100/h, 30min dedup)
Generated on 2026-07-05 using openrouter/qwen/qwen3-coder-next
Deklaratywne kontrakty tras dla connectorów urirun.
Kształt wyjścia, klasa efektu (query/command), odwracalność i taksonomia błędów są dziś
tylko konwencją — emergentną z rozproszonych return. LLM edytujący handler nie ma punktu
zakotwiczenia i dryfuje. Ten pakiet czyni kontrakt deklarowaną, wersjonowaną encją.
README.md ──(lokalny LLM)──▶ contracts.json ──(generator det.)──▶ src/handlers_generated.py
intencja proponuje, kształt prawdy sygnatura + koperta (nie edytuj)
człowiek recenzuje │
+ commituje ▼ człowiek/LLM pisze CIAŁO
src/handlers.py
│
▼ enforce + conform (det.)
registry (bindings.v2)
LLM biegnie lokalnie (LiteLLM + ollama / llama.cpp / vLLM). Do CI nie dociera — CI weryfikuje deterministycznie: kontrakt i wygenerowany kod są już w repo, brama tylko sprawdza zgodność.
Instalacja
pip install urirun-contract
Użycie w connectorze
# contracts.py — jedyne źródło prawdy
from urirun_contract import Contract, Wire
CONTRACTS = {
"window/command/close": Contract(
version="v1", effect="command", reversible=True,
inverse_route="window/command/restore",
inp={"id": "?str"},
out={"action": "const:window-close", "snapshot": "obj", "inverse": "?obj"},
errors=("unreachable",),
examples=(...),
),
"window/command/restore": Contract(...),
}
WIRES = [Wire("window/command/close", "window/command/restore", {"snapshot": "snapshot"})]
# core.py — enforce() PRZED pierwszym @conn.handler
import os
import urirun
from urirun_contract import enforce
from myconnector.contracts import CONTRACTS
conn = urirun.connector("myconn", scheme="myscheme")
enforce(conn, CONTRACTS, validate=os.environ.get("URIRUN_CONTRACT_CHECK") == "1")
@conn.handler("window/command/close", isolated=True)
def close(id: str = "") -> dict:
...
Pipeline (lokalnie, przed commitem)
make contract # README → contracts.json (LLM, bramkowane conform())
make gen # contracts.json → src/handlers_generated.py
make check # conform + anty-dryf (bez LLM)
pre-commit install # wepnij bramy w git
API
| Funkcja | Opis |
|---|---|
Contract |
Deklaracja trasy: efekt, reversible, inp, out, errors, examples |
Wire |
Krawędź kompozycji: producer → consumer + mapping |
conform(contracts) |
Oracle CI: efekt↔czasownik, wzajemny inverse, golden examples |
enforce(conn, contracts, validate=...) |
Wrap conn.handler przed dekoratorami |
check(schema, value, where) |
Walidator mini-języka schematu |
check_wire(wire, contracts) |
Statyczna weryfikacja krawędzi kompozycji |
envelope_violation(contract, envelope) |
Sprawdź kopertę; zwróć naruszenie lub None |
Mini-język schematu
| Token | Znaczenie |
|---|---|
"str" "int" "bool" "num" "obj" "list" "any" |
typy prymitywne |
"?str" |
opcjonalny / nullable |
"const:write" |
dokładna wartość literalna |
"enum:a|b|c" |
wartość z listy |
["int"] |
jednorodna lista |
{"oneOf": [A, B]} |
unia wariantów |
CI (deterministyczne, bez LLM)
# .github/workflows/contract.yml
- run: pip install urirun-contract pytest
- run: python -m pytest tests/ -q
- run: bash ci/pre_commit.sh
Przykład
examples/windowpair/ — odwracalna para window/close ↔ window/restore
contracts.json — deklaracja (2 kontrakty + 1 wire)
src/handlers_generated.py — wygenerowany szkielet (nie edytuj ręcznie)
Multi-package HTTP (architektura wdrożeniowa)
Dwa niezależnie wdrożone procesy różnych URI rozmawiające po HTTP, powiązane jednym
contracts.json. Orchestrator jest bramą międzyprocesową: nie współdzieli pamięci
z żadną ze stron, tylko weryfikuje JSON na sieci.
producer (Python, :8801) consumer-py (Python, :8802)
window/command/close window/command/restore
│ ▲
│ POST /run → koperta JSON │
│ │
└────────────┐ ┌─────────────┘
│ orchestrator │
│ drive.py │
│ ┌──────────────────┤
│ │ 1. POST producer │
│ │ 2. wire_payload │
└──│ 3. check handoff │──▶ consumer-go (Go, :8803)
│ 4. POST consumer │ window/command/restore
└─────────────────┘ (ten sam contracts.json,
różny język i kontener)
make integration # uruchom lokalne procesy i orchestruj (bez Dockera)
docker compose up --build --abort-on-container-exit --exit-code-from orchestrator
Udowodnione na realnych portach HTTP:
producer(py) ──HTTP──▶ consumer(py)— full handoff, exit 0producer(py) ──HTTP──▶ consumer(go)— full handoff, exit 0- consumer(py) i consumer(go):
snapshot=string → 422, brakurl → 422 + remediation
Struktura repozytrorium
contracts.json ← jedno źródło prawdy
toolkit/ ← gate kopiowany do każdego obrazu (zsynchronizuj: make sync-toolkit)
packages/producer/ ← Python, :8801
packages/consumer/ ← Python, :8802
packages/consumer-go/ ← Go, :8803 (te same weryfikacje, inny runtime)
orchestrator/drive.py ← brama: py→py + py→go
docker-compose.yml ← 4 serwisy z health-checks
Licencja
Apache-2.0 · Tom Sapletta · https://tom.sapletta.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file urirun_contract-0.1.1.tar.gz.
File metadata
- Download URL: urirun_contract-0.1.1.tar.gz
- Upload date:
- Size: 49.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b66f7e36183d7028f1e1b69f1e1e00385439352e5bb6664f036a46d462d41cc8
|
|
| MD5 |
6a11672a9c752f8e6bc1ae07a2bdd0bb
|
|
| BLAKE2b-256 |
671677e05166e057d973031cfe062d4246a70006938bedb9e7cfec6aba4a87b5
|
File details
Details for the file urirun_contract-0.1.1-py3-none-any.whl.
File metadata
- Download URL: urirun_contract-0.1.1-py3-none-any.whl
- Upload date:
- Size: 34.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2eeec5fe10bd35226d820fd56e330185d6a27170f171e2aade516193811cb61
|
|
| MD5 |
3c0d42a1a3cc384054f0fe380762db52
|
|
| BLAKE2b-256 |
37cec0b5b693949c9c5c5dcdb4306c0e23d3e9e3a4cde340e22d3cecf73c6012
|