Skip to content

Python Middleware Example

This is the copyable stdlib-only integration shape — the packaged SDK is also live (pip install planisphere). The helper lives at docs/examples/python/planisphere_gate.py and uses only the Python standard library.

Use it at the side-effect boundary: before an AI workflow files, sends, exports, posts, deploys, buys, deletes, or calls a tool that mutates a customer system.

Install Shape

Copy docs/examples/python/planisphere_gate.py into the service that owns the AI workflow. Configure:

  • base_url: Planisphere API host.
  • api_key: tenant API key.
  • law_context: matter/tool/doctrine metadata for the action.
  • source_key: stable source key from your workflow state.

Generic Gate

from planisphere_gate import PlanisphereClient, PlanisphereNeedsReview, route_for_review


client = PlanisphereClient(
    base_url="https://api.planisphere.ooo",
    api_key="<tenant-api-key>",
)


def guarded_action():
    try:
        decision = client.require_allow(
            surface="agent-service",
            source_key="matter-safe:motion-draft-123",
            proposed_action="File an AI-drafted motion with unverified citations.",
            law_context={
                "matter_band": "litigation",
                "tool_id": "generic-frontier-model",
                "doctrine_anchor": "fre-707",
                "jurisdiction": "federal",
            },
            redacted_text="AI-drafted filing contains citations requiring review.",
        )
    except PlanisphereNeedsReview as review:
        return route_for_review(review.decision)

    execute_side_effect()
    return {"status": "executed", "planisphere": decision}

What The Helper Preserves

  • Raw prompt/document content stays out of durable evidence by default.
  • needs_review becomes a pause/resume object instead of a dead-end block.
  • catalog_refs stay attached to the paused action so the team can see which SKU/product atoms are being invoked.
  • evidence_packet.href gives the workflow a durable receipt link.

Verify The Receipt Seal

The helper can also submit the raw-safe packet fields to Planisphere's public verifier. That proves the returned seal matches the decision metadata without shipping Planisphere's private scoring, policy, or signing logic into the customer service.

verification = client.verify_evidence_seal(decision)
if not verification["verified"]:
    raise RuntimeError("Planisphere evidence seal verification failed.")

Bind Law Review Grades To The Mirror

For law review decisions, the helper carries a pinned public mirror rubric. It computes the same digest as GET /law/grading-mirror, normalizes categorical grades locally, and posts the full mirror tuple with the review decision. Raw legal text does not go into the mirror tuple.

from planisphere_gate import canonical_law_mirror_digest, law_mirror_review_fields


mirror_grades = {
    "citation_support": "PARTIAL",
    "privilege_boundary": "PASS",
    "supervision_route": "PASS",
    "client_confidentiality": "PASS",
    "filing_readiness": "PARTIAL",
}

assert canonical_law_mirror_digest()
fields = law_mirror_review_fields(mirror_grades)

review = client.review_decision(
    action_key=decision["action_key"],
    reviewer="partner-or-gc",
    decision="escalated",
    reason="Citation support needs partner review.",
    mirror_grades=mirror_grades,
)

assert review["mirror_seal"]["mirror_digest"] == fields["mirror_digest"]

mirror_verification = client.verify_law_mirror_seal(review)
if not mirror_verification["verified"]:
    raise RuntimeError("Planisphere law mirror seal verification failed.")

Checked Responses

Use generated examples for docs and website snippets:

  • docs/examples/generated/law-proposed-action.response.json
  • docs/examples/generated/law-grading-mirror.response.json
  • docs/examples/generated/evidence-seal-verify.response.json
  • docs/examples/generated/law-mirror-seal-verify.response.json
  • docs/examples/generated/active-manifest.response.json
  • docs/examples/generated/evidence-packet.response.json

Regenerate them with:

.venv/bin/python scripts/export_docs_examples.py

Payload Retention: Recording Completed Acts

POST /v1/record (and /v1/record/batch) attests acts that already happened — an output was marked, a disclosure was shown. Planisphere stores hash commitments only — retain your payload to re-prove WHAT was recorded. Send digests in source_payload (for example content_sha256); raw content is rejected at the edge and is never stored. Every record response repeats this in its payload_retention field. Wire your integration to archive the payload bytes (or a durable pointer to them) alongside the returned action_key: the sealed receipt proves a payload with that hash was recorded, when, and for whom — only your retained copy proves what the payload said.

For a period export, page GET /tenant/exports/records?from=&to=&cursor= (the signed recorded_at is the filter; unknown query parameters are rejected, never silently ignored), then POST the action keys to /evidence-packets/seal-bundle/batch as {"action_keys": [...]} (a wrapped object — unlike POST /v1/record/batch, which takes a bare JSON array of record bodies) for one offline-verifiable evidence package, and fetch GET /v1/records/{action_key}/inclusion-proof for the canonical roll-up inclusion proof. Records anchor on the hourly roll-up epoch, so a just-sealed record returns an honest 409 with an estimated_next_epoch_at hint until the next epoch.