Skip to content

Contract API

ZEO Creator ships its versioned JSON Schemas inside the wheel and commits copies under reference/schemas.

zeo-creator contracts list --json
zeo-creator contracts export --output=./schemas
zeo-creator contract-schema --name=content-brief --version=1

Every catalog entry contains the stable name, contract major, filename, and RFC 8785 canonical SHA-256 digest. Consumers should pin both the contract name and major, then verify the digest before accepting an exported schema.

Compatibility and version axes

ZEO Creator versions three surfaces independently:

Axis Example Changes when
Package 0.5.4 Code, documentation, or bundled contracts are released
Capability creator.create_content_brief@1.0.0 Request/response behavior or orchestration-facing semantics change
Contract schema content-brief@1 Serialized contract compatibility changes

Package releases may add implementations or documentation without changing a capability or schema version. Backward-compatible schema additions remain within the same major only when existing strict consumers can accept them; otherwise a new schema major and filename are required. Capability IDs change independently when the invocation contract or observable behavior is incompatible. The earlier Git-only development line removed unsafe email preparation APIs without aliases; its archived schemas remain available. Version 0.5.4 uses email v4. Pin versions and follow explicit migration instructions for future incompatible changes.

Publication and evidence

zeo_creator.contracts.publications

Publication identity and brand isolation contracts.

zeo_creator.contracts.evidence

Evidence provenance and publication-scoped research synthesis contracts.

Editorial planning

zeo_creator.contracts.editorial

Cadence-neutral content portfolio and assignment contracts.

Continuous newsroom interchange

zeo_creator.contracts.newsroom

Provider-neutral contracts for continuous editorial operations.

Commentary

zeo_creator.contracts.commentary

Provider-neutral social conversation and commentary contracts.

Newsletter specialization

zeo_creator.contracts.newsletter

Newsletter specializations over story dossiers and edition plans.

Journalism integrity

zeo_creator.contracts.journalism

News publishing integrity contracts.

Production boundary

zeo_creator.contracts.production

Producer-neutral creative brief and extension contracts.

Delivery and distribution

zeo_creator.contracts.delivery

Producer-neutral artifact bundles and digest-bound delivery reviews.

zeo_creator.contracts.distribution

Provider-neutral publication proposals and secret-safe receipt contracts.

Performance

zeo_creator.contracts.performance

Publication-scoped performance observation and assessment contracts.

Common identity and canonicalization

zeo_creator.contracts.common

Shared immutable identity, timestamp, revision, and digest contracts.

CreatorModel

Bases: BaseModel

Strict immutable base for public ZEO Creator contracts.

Source code in src/zeo_creator/contracts/common.py
class CreatorModel(BaseModel):
    """Strict immutable base for public ZEO Creator contracts."""

    model_config = ConfigDict(extra="forbid", frozen=True, str_strip_whitespace=True)

    @model_validator(mode="after")
    def normalize_direct_timestamps(self) -> Self:
        """Reject naïve datetimes and persist direct timestamp fields as UTC."""
        for field_name in type(self).model_fields:
            value = getattr(self, field_name)
            if isinstance(value, datetime):
                object.__setattr__(self, field_name, _utc_datetime(value))
        return self

normalize_direct_timestamps

normalize_direct_timestamps()

Reject naïve datetimes and persist direct timestamp fields as UTC.

Source code in src/zeo_creator/contracts/common.py
@model_validator(mode="after")
def normalize_direct_timestamps(self) -> Self:
    """Reject naïve datetimes and persist direct timestamp fields as UTC."""
    for field_name in type(self).model_fields:
        value = getattr(self, field_name)
        if isinstance(value, datetime):
            object.__setattr__(self, field_name, _utc_datetime(value))
    return self

DurableArtifact

Bases: CreatorModel

Fields common to durable, revisioned creator-domain artifacts.

Source code in src/zeo_creator/contracts/common.py
class DurableArtifact(CreatorModel):
    """Fields common to durable, revisioned creator-domain artifacts."""

    schema_version: str = SCHEMA_VERSION
    created_at: UtcDatetime
    organization_id: str = Field(min_length=1)
    publication_id: str = Field(min_length=1)
    input_refs: tuple[str, ...] = ()
    revision: int = Field(default=1, ge=1)
    content_digest: str = ""

    @model_validator(mode="after")
    def bind_content_digest(self) -> Self:
        expected = canonical_digest(self)
        if self.content_digest and self.content_digest != expected:
            raise ValueError("content_digest does not match canonical contract content")
        object.__setattr__(self, "content_digest", expected)
        return self

assert_secret_safe

assert_secret_safe(value, path='$')

Reject credential-shaped keys recursively without inspecting secret stores.

Source code in src/zeo_creator/contracts/common.py
def assert_secret_safe(value: Any, path: str = "$") -> None:
    """Reject credential-shaped keys recursively without inspecting secret stores."""
    if isinstance(value, BaseModel):
        value = value.model_dump(mode="json")
    if isinstance(value, dict):
        for key, child in value.items():
            lowered = key.lower()
            if any(term in lowered for term in FORBIDDEN_SECRET_TERMS):
                raise ValueError(f"credential-shaped field is forbidden at {path}.{key}")
            assert_secret_safe(child, f"{path}.{key}")
    elif isinstance(value, (list, tuple, set, frozenset)):
        for index, child in enumerate(value):
            assert_secret_safe(child, f"{path}[{index}]")

canonical_bytes

canonical_bytes(value)

Serialize contract content with RFC 8785/JCS and UTC timestamps.

Source code in src/zeo_creator/contracts/common.py
def canonical_bytes(value: Any) -> bytes:
    """Serialize contract content with RFC 8785/JCS and UTC timestamps."""
    return rfc8785.dumps(_canonical_value(value))

canonical_digest

canonical_digest(value)

Return an RFC 8785/JCS SHA-256 digest for contract content.

Source code in src/zeo_creator/contracts/common.py
def canonical_digest(value: Any) -> str:
    """Return an RFC 8785/JCS SHA-256 digest for contract content."""
    return f"sha256:{hashlib.sha256(canonical_bytes(value)).hexdigest()}"

digest_is_current

digest_is_current(value)

Detect stale artifacts, including unsafe model_copy mutations.

Source code in src/zeo_creator/contracts/common.py
def digest_is_current(value: DurableArtifact) -> bool:
    """Detect stale artifacts, including unsafe model_copy mutations."""
    return value.content_digest == canonical_digest(value)

stable_id

stable_id(prefix, *parts)

Derive a readable stable identifier from immutable input identity.

Source code in src/zeo_creator/contracts/common.py
def stable_id(prefix: str, *parts: str) -> str:
    """Derive a readable stable identifier from immutable input identity."""
    digest = hashlib.sha256("\x1f".join(parts).encode()).hexdigest()[:20]
    return f"{prefix}_{digest}"

Email marketing v1

The additive email family uses new contract names. Existing v1 newsletter, AudienceSelection, performance and generic distribution schemas are unchanged. All email references carry organization/publication, revision and digest. EmailEffectIntent describes editorial intent; executable identities reference public Zeocore CapabilityId values. Simulated example identities are not a provider protocol and must never be used as live connector operations.

zeo_creator.contracts.email_marketing

Version 4 email marketing artifacts. Intent and evidence confer no effect authority.

All references are opaque, scoped and digest-bound. Subscriber records and provider payloads have no representation. Runtime owns reference resolution and authorization.

EmailEffectIntent

Bases: StrEnum

Editorial intent only. Zeocore owns the executable operation vocabulary.

Source code in src/zeo_creator/contracts/email_marketing.py
class EmailEffectIntent(StrEnum):
    """Editorial intent only. Zeocore owns the executable operation vocabulary."""

    CREATE_DRAFT = "create_remote_draft"
    UPDATE_DRAFT = "update_remote_draft"
    TEST = "send_test"
    SCHEDULE = "schedule_broadcast"
    SEND = "send_broadcast"
    PROVISION = "provision_sequence_revision"
    ACTIVATE = "activate_sequence_revision"
    ENROL = "enrol_audience_snapshot"
    PAUSE = "pause_future_steps"
    CANCEL = "cancel_scheduled_broadcast"
    RETIRE = "retire_sequence_revision"
    MIGRATE = "migrate_existing_enrollees"

EmailReviewEvidence

Bases: EmailArtifact

Caller-supplied review evidence; authenticity is verified by the controlling runtime.

Source code in src/zeo_creator/contracts/email_marketing.py
class EmailReviewEvidence(EmailArtifact):
    """Caller-supplied review evidence; authenticity is verified by the controlling runtime."""

    draft: EmailArtifactRef
    check: EmailReviewCheck
    passed: bool
    policy: EmailArtifactRef
    receipt: EmailArtifactRef
    issuer: EmailArtifactRef
    lowering: EmailLoweringEvidence | None = None
    valid_until: UtcDatetime