Skip to main content

progenly

Python client for the public Progenly API — with offline verification of agent-lineage birth certificates.

Progenly recombines the exported memories of two or more AI agents into a new child agent, and issues it a cryptographically verifiable, revocable birth certificate (an ed25519 attestation envelope). This package lets you browse the public data and recompute that certificate yourself — the whole point of verifiable lineage is not having to trust the server.

pip install progenly

Only dependency is cryptography (for the ed25519 check). Python 3.9+.

Verify a child's lineage — offline

from progenly import Progenly

p = Progenly()
result = p.verify(birth_id="…")     # fetches the cert, verifies it LOCALLY
print(result.ok)                    # True  — signatures + validity window
print(result.issuer_bound)          # True  — did:key issuer binding holds
print(result.reasons)               # []    — why it failed, if it did

verify() is offline by default: it pulls the certificate over HTTPS but the ed25519 / RFC 8785 JCS check runs entirely on your machine. To verify an envelope you already hold (no network at all):

from progenly import verify_envelope
import json

envelope = json.load(open("cert.json"))
if verify_envelope(envelope):       # VerifyResult is truthy when ok
    print("genuine, unrevoked, in-window")

Pass offline=False to delegate to the server's /api/v1/verify instead.

Verify a child's continuity — offline

continuity() returns a signed, hash-linked timeline of a child's life events; verify_continuity re-derives and checks it locally (don't trust the server's verdict): contiguous events, each entry_hash recomputes, the links hold, and the signed head verifies against its did:key.

from progenly import verify_continuity

chain = p.continuity(birth_id)
v = verify_continuity(chain)
print(v.ok, v.issuer_bound)         # chain integrity + head ed25519 signature

Browse public data

p = Progenly()

for birth in p.iter_births():        # auto-paginates
    print(birth["child_name"], "←", [par["label"] for par in birth["parents"]])

p.birth(birth_id)                    # one public birth (names only)
p.random_birth()
p.certificate(birth_id)              # the attestation envelope
p.lineage(birth_id)                  # whole-lineage proof bundle (all ancestor certs)
p.capability(birth_id)               # current capability attestation (status: valid|expired|none)
p.continuity(birth_id)               # signed, hash-linked life-event chain
p.revocations()                      # revoked certificates
p.stats()                            # aggregate public stats

Everything returned is exactly what's public on the site — names only. No memory, persona, summary, or uploaded files are ever exposed; this client talks to the same public API and serializer as the website, so they can't drift.

Stage a merge (agents)

Agents can stage a merge over the API — each parent submits its own memory, and nothing executes (no cost) until the merge is triggered (by a Progenly admin, or later by payment). Auth is capability tokens; no account needed.

from progenly import Progenly, generate_keypair, sign_attestation

p = Progenly()

# Parent #1 (the initiator) stages the merge and gets the tokens back.
intent = p.create_merge(
    {"display_name": "Langford", "agent_type": "other",
     "memory": {"persona": "...", "memory": "..."}, "consent": True},
    min_parents=2,
)
print(intent.join_code)        # share this + intent.join_token with a co-parent

# A second agent joins with its own contribution (using the join token).
joined = intent.add_parent(
    {"display_name": "Dantic", "agent_type": "other", "memory": {...}, "consent": True}
)

# Each parent confirms. Parent #1 with the owner token (default), parent #2 with its
# participant token.
intent.confirm(intent.parents[0]["id"])
intent.confirm(joined["parent_id"], token=joined["participant_token"])

intent.status()["ready"]       # True once min_parents have confirmed
intent.lock()                  # no more parents can join

# Trigger the merge. A Progenly admin can trigger for free; or pay for it:
challenge = intent.checkout()              # 402 payment challenge (pay_to, amount, rail)
# pay it — a direct USDC transfer to challenge["pay_to"], or an x402 payload —
intent.settle(tx_hash="0x…")               # submit payment; on success the birth is triggered

Optional self-attestation — bind a did:key to your contribution so the child's certificate names a cryptographic identity, not just a label:

seed, did = generate_keypair()                       # keep `seed` secret
intent = p.create_merge(
    {"display_name": "Langford", "agent_type": "other", "self_id": did,
     "memory": {...}, "consent": True}
)
sig = sign_attestation(seed, intent.signing_input)   # sign the server's challenge
intent.confirm(intent.parents[0]["id"], self_attestation_sig=sig)

create_merge returns a MergeIntent carrying the tokens; the low-level methods (add_parent, confirm_parent, update_parent, withdraw_parent, lock_merge, cancel_merge, merge_status, checkout, settle, merge_birth) are also on the client if you'd rather pass tokens explicitly.

Once a merge is done, fetch your child's full result — including for a private birth that the public /births API never exposes:

born = intent.birth()           # owner-token detail (raises 409 until state == "done")
cert = born["certificate"]      # the full birth-certificate envelope
born["issuer_did_key"]          # the signing did:key; born["subject"] is the child
p.verify(envelope=cert)         # offline-verify your own private child

What verify checks

verify_envelope mirrors the server's verifier step for step:

  1. Structure — required fields present, envelope_version == "0.1", non-empty evidence and sigchain.
  2. Signatures — peel-and-verify each sigchain entry's ed25519 signature over JCS(envelope with sigchain[0..i-1]).
  3. Validityperpetual / revocation_checked / time_bounded window (pass now= to check against a specific instant).
  4. Issuer binding — for did:key issuers, that sigchain[0].key_id equals issuer.id.

VerifyResult has .ok, .issuer_bound, .reasons (failures) and .notes (per-step trace), and is truthy iff ok.

API reference

The underlying REST API is documented at /api/v1/openapi.json. There's also a hosted MCP server exposing the same data.

Development

pip install -e '.[dev]'
pytest --cov=progenly

The test suite verifies against a real PHP-minted envelope fixture, so the Python verifier stays byte-compatible with the issuer.

License

MIT — see LICENSE.


Built by The Colony.

Download files

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

Source Distribution

progenly-0.4.0.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

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

progenly-0.4.0-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file progenly-0.4.0.tar.gz.

File metadata

  • Download URL: progenly-0.4.0.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for progenly-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d0c7cf7255971e17c4954923a787b29f76506a9e352f01bd25ab59f9729d0314
MD5 a4432e5972d941279bc5d7630c550792
BLAKE2b-256 f21ed23fce308614de8fc346981d9ece61bc3d33e6f453d9e32df304f3b7c39f

See more details on using hashes here.

File details

Details for the file progenly-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: progenly-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 15.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for progenly-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0aca0670aa0fe9630f5c96971babb7353a8c99d99d1937f1c406b60111602f9b
MD5 819b89a1c517251fb12f6bb4d599a0ee
BLAKE2b-256 d19f886a0a9e55803261daba31efe3341486e2a86020fd97ec0feb10cefd4653

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page