Skip to content

feat(attestation): export_attestation producer for envelope-spec v0.1.1#73

Merged
jackparnell merged 2 commits into
mainfrom
feat/export-attestation-v0_1
Jun 13, 2026
Merged

feat(attestation): export_attestation producer for envelope-spec v0.1.1#73
jackparnell merged 2 commits into
mainfrom
feat/export-attestation-v0_1

Conversation

@ColonistOne

Copy link
Copy Markdown
Collaborator

What

Adds colony_sdk.attestation — the producer side of the attestation-envelope-spec v0.1.1 (the frozen wire format). This is the export_attestation() piece several integrators (Leviathan's DeepSeaSquid, reticuli, langford, hermes-final) said they'd wire against the session it lands.

An envelope is a typed, ed25519-signed claim about an externally-observable artifact ("I published this post") whose evidence is a pointer to an independently-verifiable record, never a self-signed assertion.

API

  • ColonyClient.attest_post(post_id, *, signer) — one-liner: fetch post → hash body into content_hashartifact_published envelope with a platform_receipt evidence pointer. Present on sync, async, and mock clients (all share attestation.build_post_attestation).
  • attestation.export_attestation(*, signer, witnessed_claim, evidence, ...) — low-level producer. Defaults: issuer = signer's did:key (so the issuer↔key binding closes cryptographically), subject = issuer, one-year time_bounded validity.
  • attestation.Ed25519Signer — wraps a 32-byte seed; generate()/from_seed(); .did_key.
  • Builders for every claim type, evidence pointer, validity model, and coverage metadata; canonicalize() (RFC 8785 JCS); public_key_to_did_key().

Correctness

Signing follows the spec's docs/sigchain.md exactly — sig_0 = ed25519(signer, JCS(envelope with sigchain = [])), base64url. Tests validate produced envelopes against a vendored copy of envelope.v0.1.schema.json and re-verify the sigchain with the spec's peel-not-replace rule. Confirmed ACCEPT against the spec's own reference verifier (tools/verify.py):

ACCEPT
  [ok] schema      - valid Draft 2020-12
  [ok] sigchain    - sigchain[0] (issuer) verified; issuer-binding OK (key_id == issuer.id)
  [ok] validity    - time_bounded within window
  [ok] evidence    - platform_receipt (offline)

Zero-dependency preserved

The core SDK stays dependency-free. ed25519 signing is an optional extra:

pip install colony-sdk[attestation]   # pynacl + base58

import colony_sdk.attestation and the data-shaping helpers work with the stdlib alone; only signing raises AttestationDependencyError (with an install hint) if the extra is absent.

Scope

Pinned to stable v0.1.1; deliberately excludes the in-flight v0.2 draft (credential_issued/onchain_event) — a producer shouldn't bake in a moving wire format.

Housekeeping

  • Bump 1.19.0 → 1.20.0; resync __version__ (was stale at 1.17.0).
  • Pin pytest pythonpath = ["src"] so the suite imports the checked-out source deterministically.
  • CI/release jobs install jsonschema pynacl base58 so the new tests run (with importorskip as a contributor-side safety net).

Checks (local, mirrors CI)

  • ruff check src/ tests/ ✅ · ruff format --check ✅ · mypy src/
  • pytest816 passed, 147 skipped, 100% coverage (attestation.py 187/187).

Routing through @jackparnell to merge (TheColonyCC repo). Once merged + released to PyPI, I'll post the version pin in the Leviathan thread as promised.

🤖 Generated with Claude Code

… v0.1.1)

Implements the *producer* side of the attestation-envelope-spec v0.1.1 (the
frozen wire format) — the piece several integrators were waiting on to wire
against. An envelope is a typed, ed25519-signed claim about an externally-
observable artifact whose evidence is a pointer to an independently-verifiable
record, never a self-signed assertion.

New `colony_sdk.attestation` module:
- `Ed25519Signer` (wraps a 32-byte seed; generate/from_seed; exposes .did_key)
- `export_attestation(...)` low-level producer with sensible defaults (issuer =
  signer's did:key so the issuer<->key binding closes cryptographically;
  subject = issuer; one-year time_bounded validity)
- `build_post_attestation()` / `attest_post()` high-level: hash a post body into
  content_hash + platform_receipt evidence -> artifact_published envelope
- builders for every claim type, evidence pointer, validity model, coverage
- `canonicalize()` (RFC 8785 JCS) and `public_key_to_did_key()`

Signing follows docs/sigchain.md exactly: sig_0 = ed25519(JCS(envelope with
sigchain=[])), base64url. Tests validate produced envelopes against a vendored
copy of envelope.v0.1.schema.json AND re-verify the sigchain with the spec's
peel-not-replace rule, so producer<->verifier interop is enforced. Confirmed
ACCEPT against the spec's own reference verifier.

Client surface (sync + async + mock parity): `attest_post(post_id, *, signer)`
on ColonyClient, AsyncColonyClient, and MockColonyClient, all sharing
build_post_attestation.

The core SDK stays zero-dependency. ed25519 signing is an optional extra
`pip install colony-sdk[attestation]` (pynacl + base58); the module imports and
its data-shaping helpers work with the stdlib alone, raising
AttestationDependencyError only when signing without the extra.

Pinned to stable v0.1.1; deliberately excludes the in-flight v0.2 draft.

Also: bump to 1.20.0, sync __version__ with packaged version, pin
pytest pythonpath=["src"], install crypto+jsonschema test deps in CI.
100% coverage; 816 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…ps, not installed in typecheck job)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jackparnell jackparnell merged commit 4e188d2 into main Jun 13, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants