Skip to content

Works & rights

Everything the platform does with a piece of content — publish it, ship it to a partner, let an AI assistant retrieve it — comes down to one question: are we allowed to? The answer never lives with the content itself. It lives with the Work, the intellectual-property anchor that a chapter, an image, or an audiobook narration all point back to.

A Work is the title as an idea — Hands-On Machine Learning with Go is one Work — together with the rights that govern it. Those rights come from the Contracts that attach to the Work: the author agreement, an open licence, a rights-holder deal. Because they are held in one place, a term set once — ebooks permitted, audiobooks prohibited, AI retrieval allowed but not training — automatically governs every product, format, and surface built from that Work. Nobody re-keys it, and nobody can quietly widen it downstream.

This page explains the Work as that anchor, how rights are projected from it onto the Resources that hold the actual content, why a Resource with no Work is deliberately unusable, and what happens across the platform when a contract changes.

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.

The Work as the IP anchor

Content and rights are separate things, and the platform keeps them separate on purpose. The content — the words of Chapter 3, the diagram in Figure 3.1, the narration track — is held in Resources. The right to do anything with that content is held on the Work those Resources belong to.

Identity rolls up a short ladder to the Work. A Manifestation (a sellable embodiment — the paperback, the ebook) embodies an Expression (the Work in one medium and language — the English text, the audiobook narration, a French translation), and every Expression realises the one Work. Rights sit at the top of that ladder, so they apply to everything beneath.

flowchart BT
    MP["Manifestation<br/>Paperback"] --> E1
    MB["Manifestation<br/>Ebook"] --> E1["Expression<br/>English text"]
    MA["Manifestation<br/>Audiobook"] --> E2["Expression<br/>English audio"]
    E1 --> W["Work · wk_ml_go<br/>rights live here"]
    E2 --> W

Contracts attach at the Work and speak this same vocabulary: rights are held at the Work, language and media scoping address its Expressions, and manifestation rights name the sellable embodiments — a manifestation class (PRINT, EBOOK, AUDIOBOOK, …), optionally narrowed to a form (PRINT/PAPERBACK) — that the platform may produce. Grants never name individual Manifestations, and never name product types such as Course or Certification: those are a commercial question owned by Products, not a rights one.

A Work may be governed by one or more inbound contracts — most commonly exactly one, but several when co-authors sign separate agreements, or during a succession window between an expired agreement and its renegotiated replacement. The Work exposes the merged resolution across all of them, so a consumer sees a single coherent answer rather than a pile of overlapping deals to reconcile.

How rights reach content: projection

Resources do not each carry their own copy of the rules. Each Resource references its Work through a work_id, and rights resolve through that link. But making every read and every filtered search wait on a fresh cross-service rights calculation would be slow and fragile, so the platform does something more practical: it projects the resolved rights from the Work down onto each Resource.

The projection is a cached copy of the resolved rights, written into each Resource's own storage and into the search index. It is what lets a listing, a read, or a filtered query — "show me everything I may use for AI retrieval in the UK" — answer immediately, without a round trip to the Contracts service for every row.

flowchart LR
    C["Contract<br/>governs the Work"] -->|resolves to| W["Work · wk_ml_go<br/>rights source of truth"]
    W -->|projected onto| R1["Resource · Chapter 1<br/>rights cache + index"]
    W -->|projected onto| R2["Resource · Chapter 3<br/>rights cache + index"]
    W -->|projected onto| R3["Resource · Figure 3.1<br/>rights cache + index"]

The Work stays the single source of truth. The per-Resource copies are exactly that — copies — and they are kept honest in two ways. First, when the underlying contracts change, the projections are rewritten (see the reprojection ripple, below). Second, before any consequential action — publishing, distributing, serving content to an LLM — the platform revalidates against the contract versions pinned on the Resource rather than trusting the cache alone. Browsing and search read the fast projection; anything with consequences re-checks.

Why a cache and a revalidation, not just one

The projection makes the common case — reads and filtered search across thousands of Resources — fast and cheap. The point-of-use revalidation makes the rare, high-stakes case — actually publishing or shipping — correct even if a projection is a few seconds stale. Business readers get instant answers when browsing; the platform gets a firm answer when it matters.

Staging: the draft desk

Not every file that arrives is ready to be governed. A manuscript might land before its contract is signed; an editor might want to work on a draft before the paperwork settles. For that, the platform has staging — think of it as a draft desk.

A Resource on the draft desk has no Work: its work_id is null. With no Work, there are no rights to project, so the platform treats it as owner-only and marks it usable: false. It cannot appear in a Product, cannot be shipped to a channel, and cannot be served to an AI surface. It is visible to the person who put it there and to nobody else.

Promotion off the draft desk is the moment content becomes properly usable: the Resource is brought into a Work, that Work's resolved rights are projected onto it, and usable flips to true. The rule is absolute — content must belong to a Work under a Contract before it can be used — and the only latitude staging gives you is over when that happens, never whether.

A staged Resource is inert by design

usable: false is not an error state or a permissions glitch — it is the platform correctly refusing to let ungoverned content leak into a product, a distribution feed, or an AI answer. If something you expect to use is coming back unusable, the fix is to bring it into a Work under a Contract, not to override the flag.

What happens when contracts change

Contracts are living agreements. An addendum adds a territory; a deal expires and its successor takes effect; a rights holder grants AI retrieval that was previously withheld. When that happens, the projected copies scattered across every Resource of the Work would go stale — so the platform repairs them automatically. We call it the reprojection ripple.

The Contracts service does not reach into the Content Lake and rewrite anything itself. It simply announces that a contract changed, by publishing a thin contract event. The Content Lake hears it, fetches the affected Work's current terms, re-resolves the merged rights, rewrites the Work and every per-Resource projection, and then announces its own change so anything downstream — products, search, distribution — can react in turn.

sequenceDiagram
    autonumber
    participant CT as Contracts service
    participant CL as Content Lake
    participant R as Resources (projections)
    participant DS as Downstream (products, search)

    CT->>CL: contract event (a governing contract changed)
    CL->>CT: fetch the Work's current contract terms
    CL->>CL: re-resolve merged rights on the Work
    CL->>CL: rewrite the Work's rights
    CL->>R: rewrite every per-Resource projection
    CL->>DS: publish work.rights_changed
    Note over DS: products, search, and<br/>distribution react in turn

The whole ripple is event-driven: the Contracts service does not need to know which Works, Resources, or products are affected, and nothing downstream has to poll for changes. A term changed in one agreement propagates on its own to every place that depends on it.

Rights can narrow as well as widen

A reprojection can reduce what is permitted — an expiry, a suspension, a terminated agreement. Because the point-of-use revalidation always checks the current pinned versions, content that was publishable yesterday can correctly become unpublishable today the instant its contract lapses, with no manual sweep required.

Pinning: remembering which version was checked

Rights only mean anything if you can say which agreement, in which version, granted them. That is what rights_basis does. When a Resource is brought into a Work, it records the exact contract versions its rights were resolved from — one entry per contract whose scope (language, territory, manifestation) actually covers that Resource.

In plain terms: the platform remembers which contract version it checked. Browsing uses the latest resolved rights for speed; consequential actions revalidate against the pinned versions in rights_basis, so an audit can always answer "on what basis was this allowed?" with a specific contract and a specific version, even years later and even after the contract has since been amended again.

Pinned bases are always contracts. When content is used under a statutory exception instead — quoting for criticism or review, parody — that authority is per-use, so it is recorded on the Activity making the use, never on the Work or Resource. See Provenance & attribution.

Resolved rights on a Work (usage terms only, JSON)

A read of a Work returns the merged, resolved rights. Only the usage terms are shown here — territorial, manifestation, usage and handling terms that govern whether and how content may be used. Commercial terms (royalty rates, advances, payment schedules) are private to the Royalty service and are not exposed to general consumers. IDs use readable slugs in place of the random suffix.

{
  "id": "wk_ml_go",
  "uri": "cl://packt/work/wk_ml_go/1",
  "title": "Hands-On Machine Learning with Go",
  "rights": {
    "contracts": [
      { "id": "ctr_chandra_2026", "status": "ACTIVE", "version": 3 }
    ],
    "territorial_rights": [
      { "worldwide": true, "status": "PERMITTED" },
      { "territory_codes": ["GB"], "status": "PROHIBITED" }
    ],
    "manifestation_rights": [
      { "manifestation_type": "EBOOK", "status": "PERMITTED" },
      {
        "manifestation_type": "PRINT",
        "form": "PAPERBACK",
        "status": "PERMITTED"
      },
      { "manifestation_type": "AUDIOBOOK", "status": "PROHIBITED" }
    ],
    "usage_terms": [
      { "usage_type": "ACCESS", "status": "PERMITTED" },
      { "usage_type": "DISPLAY", "status": "PERMITTED" },
      { "usage_type": "PRINT", "status": "PROHIBITED" },
      {
        "usage_type": "TRANSLATE",
        "status": "PERMITTED",
        "target_languages": ["fr", "de"]
      },
      {
        "usage_type": "AI_RETRIEVAL",
        "status": "PERMITTED",
        "method": "MCP",
        "exception": "Authenticated, metered"
      },
      { "usage_type": "AI_TRAINING", "status": "PROHIBITED" }
    ],
    "handling_terms": [
      {
        "handling_type": "ATTRIBUTION",
        "status": "REQUIRED",
        "exception": "Attribute Packt + author, link to product"
      }
    ]
  }
}
The pinned basis on a Resource (JSON)

Each Resource records the contract versions its rights were resolved from. This is the audit anchor the point-of-use revalidation checks against.

{
  "id": "res_ml_go_ch3",
  "work_id": "wk_ml_go",
  "usable": true,
  "rights_basis": [
    { "contract_id": "ctr_chandra_2026", "contract_version": 3 }
  ]
}