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
Metadata
Release files for urirun-contract 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| urirun_contract-0.1.1.tar.gz | 49.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| urirun_contract-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 84.3 kB
Release files / urirun_contract-0.1.1.tar.gz
| Download URL | urirun_contract-0.1.1.tar.gz |
|---|---|
| Size | 49.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b66f7e36183d7028f1e1b69f1e1e00385439352e5bb6664f036a46d462d41cc8
|
|
BLAKE2b-256 checksum How to use checksums |
671677e05166e057d973031cfe062d4246a70006938bedb9e7cfec6aba4a87b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|
Release files / urirun_contract-0.1.1-py3-none-any.whl
| Download URL | urirun_contract-0.1.1-py3-none-any.whl |
|---|---|
| Size | 34.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2eeec5fe10bd35226d820fd56e330185d6a27170f171e2aade516193811cb61
|
|
BLAKE2b-256 checksum How to use checksums |
37cec0b5b693949c9c5c5dcdb4306c0e23d3e9e3a4cde340e22d3cecf73c6012
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|