Skip to content

Contracts & Rights

A contract, on this platform, is not paperwork filed away after a deal closes. It is infrastructure. Nothing enters the platform for real use without one, and once one is in place the rights it records are enforced by the platform itself — not by each downstream team remembering the terms, not by a note in a spreadsheet, not by hoping the person building a product read the agreement first. A contract is the machine-readable answer to a single question the whole platform keeps asking: are we allowed to do this?

That matters because content is meant to be liquid here. A manuscript that arrives once flows into an ebook, an audiobook, a course, a newsletter, and an answer given by an AI assistant. Every one of those uses is governed by what an author or rights holder agreed to, and those permissions differ — an author may grant ebook rights but not audiobook rights, or permit an AI assistant to retrieve and cite a book while prohibiting its use to train a model. If each of those distinctions lived only in a PDF, the platform could not honour them automatically. Because they live in a contract, it can.

The Contracts service is the platform's system of record for those agreements. It owns the full lifecycle — creation, activation, amendment, renewal, suspension, termination — and the structured vocabulary the rest of the platform evaluates: which territories, which formats, which usages, which obligations, which commercial terms. Every service that needs to answer "what does this agreement permit?" — the Content Lake, Products, Distribution, Royalty — consumes the contract's terms and reacts to its events. Enforcement happens where the answer is needed; the contract supplies the truth.

This page is the overview of that domain: how a contract attaches to a Work, the difference between rights coming in and rights going out, the lifecycle a contract moves through, how history is preserved, and who the parties on a contract actually are. The Contract Model covers the term vocabulary in full; Royalties and Licences cover the commercial and open-licence sides; Examples works real deals end to end.

Contracts attach to Works

A Contract governs a Work — the intellectual-property anchor in the Content Lake entity model, the title as an idea rather than any single file. It never attaches to a document, a chapter, or a resource. This is deliberate: rights are a property of the thing you own, not of the many copies and formats you produce from it. Attach the author agreement to the Work once, and every Resource beneath that Work — every chapter, image, and narration track — inherits the same rights regime.

The consequence is a rule worth stating plainly: one Work, one rights regime. A contract cannot carve out an individual Resource inside a Work. So when source material mixes licences — an open-access chapter inside an otherwise proprietary title, a third-party asset licensed on its own terms — it is split into separate Works at ingestion, each with its own governing contract.

flowchart TD
    C["Contract<br/>ctr_chandra_2026"] -->|governs| W["Work<br/>wk_ml_go<br/>(rights source of truth)"]
    W -->|projected onto| R1["Resource<br/>Chapter 1"]
    W --> R2["Resource<br/>Chapter 2"]
    W --> R3["Resource<br/>Chapter 3"]

Rights are held once on the Work, cached per Resource as a projection plus search-index attributes, and revalidated at the point of use against the specific contract versions pinned in each Resource's rights_basis. The Work is always the source of truth; the per-Resource copy exists only so that reads and filtered searches never need a cross-service call. When a contract changes, the affected Works' rights are re-resolved and their Resources re-projected. The mechanics of that projection live in Works & rights; what matters here is the direction of authority — from contract, to Work, to content.

The rights model in one line

Rights are held once on the Work (the source of truth), cached per Resource (a projection plus search-index attributes), and revalidated at the point of use against the contract versions pinned in each Resource's rights_basis. Content must belong to a Work under a Contract before it can be used in a Product, a distribution, or any AI surface.

Inbound and outbound: the direction of rights

Every contract has a direction, and it is the single most important thing to understand about how rights flow through the platform.

An INBOUND contract records rights the platform acquires. This is an author agreement, a rights-holder deal, an open-source or Creative Commons licence — someone granting Packt the right to do things with a Work. An OUTBOUND contract records rights the platform grants onward: a distributor deal, a reseller agreement, a site licence, a serialisation or AI-training arrangement — Packt passing some of what it holds to a counterparty.

The asymmetry between them is the load-bearing rule of the whole domain:

Outbound can never widen what the platform may do

Only inbound contracts feed a Work's resolved rights. Outbound contracts contribute nothing to what the platform is allowed to do — they can only ever pass along a subset of rights already held. An outbound grant is validated against the Work's resolved inbound rights at the moment it becomes active: a contract cannot grant a territory, a format, or a usage the platform does not itself hold. You cannot sell what you never bought.

flowchart LR
    A["Author / rights holder<br/>open licence"] -->|INBOUND<br/>rights acquired| W["Work<br/>resolved rights"]
    W -->|OUTBOUND<br/>rights granted onward| D["Distributor / reseller<br/>licensee"]
    W -.->|validated against| G["Outbound grant<br/>cannot exceed held rights"]

Grants on both sides speak the same Work → Expression → Manifestation vocabulary as the Content Lake: rights are held at the Work, language and medium scoping address its Expressions, and manifestation rights name the sellable embodiments — a class such as PRINT or EBOOK, optionally narrowed to a form such as PAPERBACK — the platform may produce. Commercial packagings such as Course or Certification are product types, never grant axes; a grant that names one has leaked a layer.

Not every contract moves rights

Direction only exists on rights contracts, and a contract's kind says which world it lives in. A RIGHTS contract carries the full term vocabulary. A SERVICES contract is an engagement — a technical-reviewer letter, a freelance editing agreement, a live training booking — with real parties, real compensation (often paid in copies or subscription access rather than cash), and real risk, but no rights terms at all. It has no direction, contributes nothing to any Work's resolved rights, and never blocks or widens anything; its Work links record which title the engagement served, purely as provenance.

Recording engagements matters precisely because of what they don't say: a reviewer who contributes text under a letter with no IP clause is a genuine rights exposure, and the platform can list every engagement missing a licence-back term — a query, not a PDF audit. The services engagement example shows a full record.

Two instruments sit beside contracts rather than inside them:

  • Related-contract edges link agreements — a new edition superseding the old, a call-off under a framework, an inducement letter beside a main agreement, a book deal derived from a video deal. Edges are recorded for navigation and audit, never evaluated: linking never changes a verdict.
  • Payee redirects record instruments (deeds of assignment of benefits, bank-change letters) that re-route a party's payments to a beneficiary. A redirect changes where money is sent — never who earns it and never a single rights term, so it produces no new contract version.

The status lifecycle

A contract moves through a small, fixed set of states. Only an ACTIVE contract grants rights; every other state either grants nothing or grants only its wind-down terms.

stateDiagram-v2
    [*] --> DRAFT
    DRAFT --> ACTIVE
    DRAFT --> TERMINATED
    ACTIVE --> SUSPENDED
    ACTIVE --> EXPIRED
    ACTIVE --> TERMINATED
    SUSPENDED --> ACTIVE
    SUSPENDED --> EXPIRED
    SUSPENDED --> TERMINATED
    EXPIRED --> [*]
    TERMINATED --> [*]
Status What it means
DRAFT Being negotiated. Grants no rights at all.
ACTIVE In force. Rights resolve from the latest version.
SUSPENDED Temporarily not in force (e.g. a dispute). Rights resolve as if the contract were absent, then restore on return to ACTIVE.
EXPIRED Past its expiry date. Any continuing-access terms still apply.
TERMINATED Ended before expiry. Any continuing-access terms still apply.

EXPIRED and TERMINATED are terminal — a contract never leaves them. A suspended contract can return to ACTIVE only while it remains within its duration window; once past its expiry date it moves to EXPIRED, never back. Every transition publishes a state_changed event and triggers re-resolution of the affected Works' rights, so a suspension or termination ripples out to content within moments, without anyone re-checking each product by hand.

Expiry is swept, not requested

Whether a contract is in force is computed from its duration window and its effective end date, not from the stored status label. A scheduled sweep keeps the stored status truthful (and applies auto-renewal where a contract is set to renew), but a contract past its expiry date is already out of force — and its continuing-access terms already in force — from the moment the date passes, whatever the label says.

History is never lost

Contracts are versioned, and versioning here is absolute: every change produces a new immutable version, and nothing is ever lost. Creation is version 1; each amendment, update, or automatic renewal increments it. A version records the complete contract state at that point in time — never a diff, never a mutated-in-place record — so the full history of how terms evolved is always reconstructable.

The usual way to change a live contract is an addendum. The caller submits the complete amended term set together with the uploaded addendum document, and a new version records both. A crucial boundary: the service never parses or extracts terms from documents. It archives the original contract PDF and every addendum PDF as source documents, and it stores the structured terms the caller supplies — but turning a PDF into terms is upstream work (including any AI-assisted drafting), never something the service infers. What it stores is what a human put there.

Two tiers of the platform read versions differently. Everyday browsing and filtered search resolve rights from the latest active version — fast, good enough to decide what to show. Consequential actions — publishing a product, shipping to a channel, serving content to an AI model — revalidate against the exact contract versions pinned in the consuming Resource's rights_basis, so the decision to act is always made against the precise terms that were in force, not a cached approximation.

A contract record (JSON)

A contract is identified by a ctr_ ID with a readable slug. This is a trimmed record; the Contract Model documents every field and the term arrays elided here.

{
  "id": "ctr_chandra_2026",
  "tenant": "packt",
  "title": "Author Agreement — Hands-On Machine Learning with Go",
  "status": "ACTIVE",
  "direction": "INBOUND",
  "version": 3,
  "agents": [
    { "agent_id": "agt_chandra", "role": "AUTHOR", "name": "A. Chandra" },
    { "agent_id": "agt_packt", "role": "PUBLISHER", "name": "Packt Publishing" }
  ],
  "work_ids": ["wk_ml_go"],
  "external_reference": "SF-OPP-2025-00142",
  "created": "2025-01-01T00:00:00Z",
  "updated": "2026-04-01T12:00:00Z"
}

The agent registry: parties are the platform's agents

The parties to a contract — authors, publishers, distributors, rights holders, licensees — are not free-text names. Each is an agent, a first-class registry record identified by an agt_ ID, and the Contracts service owns that registry. An author who signs an agreement, the co-author who shares the royalty split, the distributor on an outbound deal: all are agent records, referenced by ID on the contract rather than typed in by hand.

This is more than tidy data. The same registry that supplies a contract's parties also supplies the actors attributed on every Activity in the provenance record. The author named on ctr_chandra_2026 and the author credited with writing a chapter are one record — so "who is owed?" and "who did this?" resolve to the same identity. Human agents are synced from the CRM (Attio); SYSTEM agents — pipelines and platform services — are provisioned registry records. When a caller presents a token, the platform resolves it to an agent through this registry; see Platform Authentication for how a validated principal becomes an attributable agent.

Role On which side Who it is
AUTHOR Inbound The creator granting rights over the Work.
PUBLISHER Inbound Packt, holding the acquired rights.
RIGHTS_HOLDER Inbound A non-author party granting rights (e.g. an estate, a licensor).
DISTRIBUTOR Outbound A partner taking product onward to customers.
RESELLER Outbound A partner reselling under its own arrangement.
LICENSEE Outbound A counterparty licensed to use the content itself — a site licence, a serialisation, an AI-training deal — rather than distribute it.

Where agent records come from — the periodic CRM sync from Attio, manual creation, linking the two — and why a signed contract keeps the names it was signed with, is covered in depth in Agents.

Default contracts for open licences

Not every Work needs a bespoke agreement. The platform ships default contracts for the common open-source and Creative Commons licences — MIT, Apache 2.0, GPL, BSD, the CC BY family, and CC0 — each modelling that licence's standard terms as ready-to-attach manifestation, usage, handling, and royalty terms. They are all INBOUND (a licence is a grant of rights to the platform) and carry well-known IDs of the form ctr_default_<slug> — for example ctr_default_mit, ctr_default_cc_by_4_0. Identifiers pin the licence version, because licence revisions differ materially: a new revision is a new contract, never a mutation of an old one. Licences covers the full catalogue and the terms each one seeds.

How the platform lands: a three-phase mission

The Contracts service arrives in phases. Everything above — the system of record, versioning, the lifecycle, default contracts — is Phase 1 and is the whole of what these overview pages describe as shipped behaviour. The later phases are named commitments, not yet live.

Roadmap

  • Phase 1 — System of record. Contract creation, versioning and addendums, the status lifecycle, default contracts, the agent registry, contract events, and the read interface. This is the foundation every rights decision on the platform already rests on.
  • Phase 2 — Channel distribution rule evaluation. The service evaluates a channel's declared usage against a Work's outbound grants, so Distribution can match products to channels automatically — no item ships to a partner whose needs the rights do not cover.
  • Phase 3 — Signing automation. Drafted agreements are dispatched to signatories for electronic signature, and the executed document is recorded as the contract's source. A contract stays in DRAFT until signature completes, closing the loop from negotiation to a live, enforced agreement.

Where to go next

The rest of this section covers the contract domain in depth:

  • Contract Model — the full term vocabulary: territorial, manifestation, usage, handling and duration terms, the rights-resolution merge rules, and how a many-contract Work resolves to one answer.
  • Agents — the agent registry: where the parties come from (the Attio CRM sync and manual creation), and why signed contracts keep the names they were signed with.
  • Royalties — the commercial terms: rate rules, advances, splits, and how retail sales and subscription attributions accrue royalty per contract.
  • Licences — the default open-source and Creative Commons contracts and the terms each one models.
  • Examples — real deals worked end to end: acquisitions, licensing-out, suspensions, reversions, and addendums.
  • Complete examples — three maximal records distilled from the real contract archive, plus a lookup from any real-world clause to the field that holds it.