contracts¶
Envelope, payload models, signing, scope and schema validation.
coalitionkit_contracts ¶
Contracts for the Coalition Protocol v0.1: models, JCS, signing, IDs and schema validation.
NotADeciderError ¶
Bases: ValueError
The answering participant is not named for this subject (not_a_decider).
Envelope ¶
Bases: WireModel
parse_payload ¶
Validate the payload against the model for this envelope's type.
StoredSubmission
dataclass
¶
What the host keeps per accepted event: who sent it and the digest of what they sent.
DecisionExpiredError ¶
Bases: ValueError
The decision arrived after its subject's decision_deadline (deadline_exceeded).
LogIntegrityError ¶
Bases: Exception
The log does not match its genesis, its own chain or a receipt the host signed.
LogStub
dataclass
¶
A replay entry for an event outside the reader's scope: only its place in the chain.
OwnerKeyConflictError ¶
Bases: ValueError
The owner key is already pinned to another participant (wire error not_authorized).
StaleSubjectError ¶
Bases: ValueError
The decision names a revision that is not the subject's current one (stale_subject).
Membership
dataclass
¶
Who the members are and who holds each role, at derivation time.
ScopeSource
dataclass
¶
One source event of a derived output: its scope and the owner of its sender.
projected says the output is built from the source's redacted projection only (its
redact paths are already removed from the data the host read), not from the original.
SignatureError ¶
Bases: Exception
The signature is malformed or does not verify.
SchemaValidationError ¶
Bases: Exception
The data fails its JSON Schema. errors lists one line per problem.
canonicalize ¶
JCS bytes of a JSON value. Integers outside +-(2**53 - 1) are refused by rfc8785.
prev_hash ¶
SHA-256 hex of the JCS form of the previous accepted envelope (all fields, sig too).
consent_payload ¶
The JCS bytes the owner signs. decide is a coalition.decide payload.
sign_consent ¶
sign_consent(
coalition_id: str,
decide: Mapping[str, Any],
owner_key: Ed25519PrivateKey,
kid: str,
*,
participant: str,
) -> str
The consent_sig value for a decision (any consent_sig already in it is ignored).
verify_consent ¶
verify_consent(
coalition_id: str,
decide: Mapping[str, Any],
owner_public_key: Ed25519PublicKey,
*,
participant: str,
expected_kid: str | None = None,
) -> str
Verify decide['consent_sig'] against the pinned OWNER key only. Returns the kid.
verify_decision ¶
verify_decision(
envelope: Envelope | Mapping[str, Any],
agent_public_key: Ed25519PublicKey,
owner_public_key: Ed25519PublicKey,
) -> None
A decision counts only when the agent signed the envelope AND the owner signed the consent.
Raises SignatureError otherwise.
record_answer ¶
record_answer(
answers: Mapping[str, T],
named: Collection[str],
decider: str,
consent: T,
) -> tuple[dict[str, T], bool]
Record one decider's answer for one (subject, revision).
Returns the new answers and whether this answer was recorded. A second answer from the same
decider is not recorded (the first one wins) and recorded is False.
tally ¶
refused on any refusal, decided when every named decider consented, else pending.
tally_choice ¶
tally_choice(
named: Collection[str],
answers: Mapping[str, tuple[bool, str]],
) -> tuple[ChoiceState, str | None]
Tally a subject whose consents each name a choice (a tension_option).
answers maps a decider to (consent, choice). Returns the state and the chosen option:
refused on any refusal; split when two consents name different options (no option has
every decider, so the tension is replanned); decided when every named decider consented to
the same option; otherwise pending.
classify_submission ¶
classify_submission(
original: StoredSubmission | None,
authenticated_sender: str,
envelope: Envelope | Mapping[str, Any],
) -> Outcome
new (nothing stored), replay (return the original acknowledgement) or mismatch.
mismatch is answered with duplicate_mismatch and discloses nothing about the original:
the same answer for a different sender and for a different envelope.
idempotency_key ¶
The lookup key: (coalition_id, event_id).
submission_digest ¶
SHA-256 hex of the JCS form of the envelope without the host fields (sig included).
is_ulid ¶
True when value matches the ULID pattern used by the JSON Schemas.
new_ulid ¶
Create a ULID. now_ms and entropy (10 bytes) exist for tests.
ulid_timestamp_ms ¶
The millisecond timestamp encoded in a ULID.
accepts ¶
True when a message of this kind about a task in status passes the status check.
after_planning_start ¶
Status after the host's first query, proposal or tension names the task.
after_replan ¶
Status after a refusal, a withdrawn commitment, a ripple or a decision expiry.
check_decision_window ¶
Raise DecisionExpiredError when a decision is accepted after the deadline.
decision_expired ¶
True when at (the host's acceptance time, or its clock) is after the deadline.
may_create_commitment ¶
One active commitment per task: creation needs none of the task's commitments active.
supersede_active ¶
The commitments of a task after a replan: every active one becomes superseded.
check_receipts ¶
check_receipts(
entries: Sequence[Entry],
receipts: Sequence[ReceiptInfo],
host_public_key: Ed25519PublicKey,
*,
expected_kid: str | None = None,
) -> None
Compare a replayed log with the receipts a member kept.
truncated: the log ends before a receipt's seq. receipt_mismatch: the entry at a
receipt's seq hashes to something else (an edited tail, even one with a re-linked chain).
Projections are verified against the pinned host key first, as in verify_chain.
entry_hash ¶
The hash the next entry must carry as prev_hash.
A coalition.projection is refused here: its own envelope hash is not the chain hash. Turn
it into a stub with verify_projection first.
genesis_hash ¶
The prev_hash of seq 1.
projection_stub ¶
The stub {seq, prev_hash, hash} a coalition.projection carries for its source.
receipt_payload ¶
The payload of the receipt for an accepted envelope (which carries its host fields).
verify_chain ¶
verify_chain(
entries: Sequence[Entry],
genesis: str,
host_public_key: Ed25519PublicKey,
*,
first_seq: int = 1,
expected_kid: str | None = None,
) -> int
Check seq is gap-free from first_seq and each prev_hash links to the one before.
genesis is the expected prev_hash of entries[0] (the genesis hash for a full
replay). Each coalition.projection entry is first verified against the pinned host key
(SignatureError if forged) and stands in as its source's stub. Returns the head seq
(first_seq - 1 for an empty log).
verify_projection ¶
verify_projection(
projection: Envelope | Mapping[str, Any],
host_public_key: Ed25519PublicKey,
*,
expected_kid: str | None = None,
) -> LogStub
Verify a projection against the pinned host key and return the stub it carries.
A replay holding projections checks the chain with these stubs, never with the projection's own envelope hash.
verify_receipt ¶
verify_receipt(
receipt: Envelope | Mapping[str, Any],
host_public_key: Ed25519PublicKey,
*,
accepted: Envelope | Mapping[str, Any] | None = None,
expected_kid: str | None = None,
) -> ReceiptInfo
Verify a receipt envelope against the pinned host key and, if given, the accepted envelope.
Raises SignatureError for a bad signature and LogIntegrityError for a receipt that does not
describe accepted.
check_owner_key_unique ¶
check_owner_key_unique(
pinned: Mapping[str, str],
participant: str,
owner_key_thumbprint: str,
) -> None
Raise when this owner key is already pinned to a different participant.
pinned maps participant ID to the thumbprint of its pinned owner key, for one Coalition.
jwk_thumbprint ¶
RFC 7638 SHA-256 thumbprint (base64url, no padding) of an Ed25519 (OKP) JWK.
jwk_to_public_key ¶
The public key in an Ed25519 JWK. Raises SignatureError when it is not one.
public_key_to_jwk ¶
An Ed25519 public key as the JWK shape of common.json#/$defs/ed25519_jwk.
sign_owner_proof ¶
sign_owner_proof(
coalition_id: str,
participant: str,
card_url: str,
owner_key: Mapping[str, Any],
owner_private_key: Ed25519PrivateKey,
) -> str
The owner_proof for a join; the JWS kid is the JWK's kid.
verify_owner_proof ¶
verify_owner_proof(
join: Envelope | Mapping[str, Any],
*,
agent_public_key: Ed25519PublicKey | None = None,
) -> Ed25519PublicKey
Check a coalition.join envelope's owner proof and return the key to pin.
The proof must verify under the key it carries, bind this Coalition, participant (the
envelope's on_behalf_of) and card, and the owner key must not be the agent's own key.
Raises SignatureError on any failure.
delivery_form ¶
The form of an event for one recipient, also used for the sender's acknowledgement.
A recipient outside the event's scope gets nothing but the receipt. Inside the scope, an event with a field redacted for the recipient, or one that is viewer-specific, is a projection; any other event is delivered as the original.
check_revision ¶
Compare as the host does inside the recording transaction. Older or newer both fail.
is_superseded ¶
A pending consent request for an older revision is superseded by a change.
principals ¶
The resolved principal set of one source: the members who may see it.
resolve_narrowest ¶
The scope a derived output takes: the intersection of its sources' principal sets.
Roles resolve to the members holding them now, self to the source sender's owner. An
empty intersection becomes host. A source with a non-empty redact list that is not
projected makes the output host (no redaction path survives a renamed field), and a
projected source contributes no redaction paths. When every source is coalition the
result is coalition; when every source lists the same roles it stays roles; otherwise
it is participants with the sorted intersection.
sign_detached ¶
Compact JWS with a detached payload over payload (already canonical bytes).
sign_envelope ¶
sign_envelope(
envelope: Envelope | Mapping[str, Any],
private_key: Ed25519PrivateKey,
kid: str,
) -> str
Sign an envelope and return the compact JWS to put in sig.
signing_payload ¶
The JCS bytes that are signed.
verify_detached ¶
verify_detached(
sig: object,
payload: bytes,
public_key: Ed25519PublicKey,
*,
expected_kid: str | None = None,
) -> str
Verify a detached-payload compact JWS against public_key only. Returns the kid.
Raises SignatureError on any failure.
verify_envelope ¶
verify_envelope(
envelope: Envelope | Mapping[str, Any],
public_key: Ed25519PublicKey,
*,
expected_kid: str | None = None,
) -> str
Verify envelope['sig'] against public_key only. Returns the kid.
Raises SignatureError on any failure.
schema_dir ¶
An explicit schema override, or the schemas shipped in this distribution.
validate_envelope ¶
Validate an envelope, then its payload by type.
validate_payload ¶
Validate a payload against the schema for its message type.