Skip to main content

coderifts-sdk

Python SDK for CodeRifts — API governance for AI agents.

v3.2.0 (ID75) closes REST method parity with @coderifts/sdk 3.3.0. Decision Spec v2 still requires top-level preflight_mode on preflight. PyPI publishes are a separate, manual flow (do not twine upload from this checkout). Offline Ed25519 verification is not in this package (requests only) — use @coderifts/sdk, coderifts-app, or receipt-verifier.

Surface vs TypeScript SDK

Capability Python TypeScript 3.3.0 Notes
preflight_change_set / analyze_change_set / authorize_change_set yes preflightChangeSet / analyzeChangeSet / authorizeChangeSet POST /api/v1/preflight
verify_receipt yes verifyReceipt POST /api/v1/verify-receipt
get_decision_details yes getDecisionDetails POST /api/v1/decisions/lookup
preflight_check yes (3.2.0) preflightCheck POST /api/v1/agent/preflight
diff yes (3.2.0) diff POST /api/v1/diff
score_mcp yes (3.2.0) scoreMcp POST /api/v1/agent-readiness-score
get_ledger yes (3.2.0) getLedger GET /api/v1/ledger (from_ → query from)
simulate_policy yes (3.2.0) simulatePolicy POST /api/v1/policy-simulator
explain_decision yes (3.2.0) explainDecision client-side; no HTTP
how_to_unblock yes (3.2.0) howToUnblock client-side; no HTTP
readDecision no readDecision Guard helper — TS-only by design (agent-guard / tool-table).
verifyExecutionGrant no verifyExecutionGrant Offline Ed25519. Python has no crypto dep; helpers compute_scope_hash / receipt_digest / after_payload_canonical only.
waiver / deploy-gate / publish-gate no no Not on the TS client. Not invented here.
MCP client no no Out of scope.

Installation

pip install coderifts-sdk

Requires Python 3.9+ and requests.

Quick start

from coderifts import CodeRifts, CodeRiftsError

client = CodeRifts(api_key="cr_live_...")

preflight_change_set / analyze_change_set / authorize_change_set

Required keyword-only preflight_mode='analyze'|'authorize' (Decision Spec v2; server returns HTTP 400 if omitted). Prefer the wrappers so the two meanings cannot be mixed.

Branch on execution_action (proceed signal, authorize). Closed set: CONTINUE | CONTINUE_WITH_MONITORING | REQUEST_APPROVAL | STOP. Unrecognised → treat as STOP. Use decision for the explanation label. Analyze is informational (risk-only), not permission.

v2 fields on authorize: receipt_kind (operation_authorization | NONE), chain_receipt, optional execution_grant, blast_radius (counts, not a score).

before = open("openapi-before.json").read()
after = open("openapi-after.json").read()
artifacts = [
    {
        "id": "spec-main",
        "type": "openapi",
        "before": before,
        "after": after,
    }
]

# Risk-only
risk = client.analyze_change_set(artifacts=artifacts)
print(risk.analysis_outcome, risk.receipt_kind)  # receipt_kind == "NONE"

# Operation-bound authorize (requires context.operation; may mint a receipt)
result = client.authorize_change_set(
    artifacts=artifacts,
    context={
        "operation": "merge",
        "environment": "staging",
    },
    include_execution_grant=True,  # opt-in cr.exec.v1 grant
)

print(result.execution_action)   # e.g. "CONTINUE"
print(result.decision)           # e.g. "ALLOW"
print(result.receipt_kind)       # "operation_authorization" | "NONE"
print(result.breaking_changes)   # integer count, not a list
print(getattr(result, "execution_grant", None))  # grant token when opted in
print(getattr(result, "blast_radius", None))

token = result.chain_receipt
decision_id = result.decision_result.decision_id

verify_receipt

A valid signature is not authorization. currently_authorized is True / False / NoneNone means authorization was not evaluated. Expiry uses 30s clock-skew leeway (CLOCK_SKEW_LEEWAY_MS); 0s for destructive operations in production when the intended context declares them. The SDK does not compare expiry locally — the server does.

This is a REST verify. Offline grant verification is TS/app/receipt-verifier.

# Cryptographic check only
check = client.verify_receipt(token=token)
print(check.valid, check.status)
print(check.currently_authorized)  # often None without intent context

# With intent + the body-bound decision envelope for full authorization
authz = client.verify_receipt(
    token=token,
    operation="merge",
    environment="staging",
    target_id=result.decision_result.artifact_digest,
    fingerprint=result.verdict_fingerprint,
    decision_result=result.decision_result.to_dict(),
)
print(authz.currently_authorized)  # True / False once evaluable
print(getattr(authz, "authz_status", None))

Grant helpers (no Ed25519):

from coderifts import compute_scope_hash, receipt_digest

print(receipt_digest(token))
print(compute_scope_hash("merge", "sha256:tgt", after))

get_decision_details

Look up a stored decision by decision_id or fingerprint.

stored = client.get_decision_details(decision_id=decision_id)
print(stored.execution_action)
print(stored.decision)
print(stored.meta.source)

Other REST methods (TS parity)

client.diff(before=before, after=after)
client.score_mcp(manifest={"tools": []})
client.get_ledger(repo="acme/api", from_="2026-01-01", limit=20)
client.simulate_policy(policy_yaml="rules: []", old_spec=before, new_spec=after)

Error handling

from coderifts import CodeRifts, ApiError, AuthError, RateLimitError, CodeRiftsError

try:
    client.authorize_change_set(artifacts=[...], context={"operation": "merge"})
except AuthError as e:
    print("auth", e.message)
except RateLimitError as e:
    print("rate limit", e.message)
except ApiError as e:
    print(e.status_code, e.message)
except CodeRiftsError as e:
    print(e.code, e.message)

Response access

Return values are thin wrappers around the JSON object:

result.decision                 # attribute
result["decision"]              # item
"decision" in result            # membership
result.to_dict()                # full dict
result.decision_result.decision_id  # nested dicts wrap too

License

MIT

Release files for coderifts-sdk 3.2.0

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

Source distribution (sdist)

Source distribution for coderifts-sdk 3.2.0
File Size Uploaded
coderifts_sdk-3.2.0.tar.gz 22.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for coderifts-sdk 3.2.0
File Interpreter ABI Platform
coderifts_sdk-3.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 39.5 kB

Release files / coderifts_sdk-3.2.0.tar.gz

Download URL coderifts_sdk-3.2.0.tar.gz
Size 22.1 kB
Tags Source
SHA-256 checksum
How to use checksums
df5146538f40fe9d64859ae8e13313c4c3d9e7459292b40f248055869bac0631
BLAKE2b-256 checksum
How to use checksums
fb6201dde3e262c5ada012160c4fa3ce3e8c21ab643c5f8bc0a7b1c05c1bc6d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / coderifts_sdk-3.2.0-py3-none-any.whl

Download URL coderifts_sdk-3.2.0-py3-none-any.whl
Size 17.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
73fe83814c75fca2fff100ba9861224315a412b32ad21259f303b6ebe6d2a722
BLAKE2b-256 checksum
How to use checksums
b78532c966627c6fd062f4ad3788879d24b5a7e08d336f70cb9f5e81690f5df8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

3.8.2

2 release files

3.8.1

2 release files

3.8.0

2 release files

3.7.0

2 release files

3.6.0

2 release files

3.5.0

2 release files

3.3.0

2 release files

This release

3.2.0 This release

2 release files

3.0.0

2 release files

2.0.0

2 release files

1.0.1

2 release files

1.0.0

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