Skip to content

spec(brand-protocol): standing licensed relationships on brand.json — licensed_from[] / licensed_to[] #4589

@bokelley

Description

@bokelley

Follow-up from PR #4540 (brand verification RFC). Explicitly listed as out-of-scope there.

The gap

`brand.json` today expresses ownership relationships via `brand_refs[]` and `house_domain` — corporate parentage with mutual-assertion trust. It does not express standing licensed relationships, which are a real and distinct category.

The verification surface (`verify_trademark`) returns `licensed_in` / `licensed_out` as status values because the underlying relationships are real:

  • A Marriott franchisee uses the MARRIOTT mark under license — not owned, but contractually licensed for specific use cases in specific countries.
  • A music catalog owner licenses their catalog to a distribution partner per-territory — "I've licensed to Acme Distribution in CN; manage it myself everywhere else."
  • A sub-brand licenses rights bidirectionally with its parent — different in different countries.

The brand-agent can return these statuses because they live in its internal records. But the static brand.json file has no publishing surface for the underlying relationships. A consumer crawling brand.json files cannot infer them; they have to call the agent.

What the rights protocol does and doesn't cover

The brand-protocol's existing rights surface — `rights_agent` (typed agent, `type: "rights"`) + `get_rights` + `acquire_rights` tasks — handles transactional licensing. You negotiate a license through the rights agent. It declares `available_uses`, `right_types`, `countries` on the agent itself, which is jurisdictional and use-case-scoped.

What it doesn't do: provide a standing declaration that some other party has a license. The rights agent is the negotiation surface, not a record of executed licenses. There's no static-file field on brand.json that says "I license-in the MARRIOTT mark from Marriott Corp in DE, FR" or "I've granted standing rights to Acme Distribution for my catalog in CN."

Proposal sketch

Two new arrays on the brand definition (`#/definitions/brand`):

```json
{
"licensed_from": [
{
"licensor_domain": "marriott.com",
"licensor_brand_id": "marriott",
"available_uses": ["advertising", "merchandise_resale"],
"right_types": ["trademark", "likeness"],
"countries": ["DE", "FR"],
"effective_at": "2024-01-01",
"expires_at": "2028-12-31"
}
],
"licensed_to": [
{
"licensee_domain": "acme-distribution-cn.com",
"available_uses": ["merchandise_resale"],
"right_types": ["trademark"],
"countries": ["CN"],
"effective_at": "2025-06-01",
"expires_at": "2027-05-31"
}
]
}
```

Vocabulary reuses the rights protocol's existing `available_uses` / `right_types` / `countries` so the two surfaces stay coherent.

Trust model questions

  • Mutual assertion? A licensee declares it's licensed-in from a licensor. The licensor's brand.json could publish a reciprocal `licensed_to` entry. Same shape as `brand_refs[]` ↔ `house_domain` mutual assertion. Or: the licensor's rights_agent could confirm via a new task. Or both.
  • Privacy / commercial sensitivity. Some license agreements are confidential. Brands won't want to publish them. Probably needs an opt-out / explicit-only model rather than implying every license should be public.
  • Per-jurisdiction granularity. Same trademark licensed to different parties in different countries. The shape above handles this via per-entry `countries`, but resolution semantics need thought (e.g., "what does a consumer see when querying for CN vs FR?")
  • Time-bounded. Licenses expire. Need `effective_at` / `expires_at` (parallel to `brand_refs[].effective_at` from PR feat(brand-protocol): ratify distributed brand.json + fold + typed trademarks #4505). Consumer-side caching has to respect expiration.

Integration with verify_trademark

When this lands, `verify_trademark` returning `licensed_in` / `licensed_out` becomes a confirmation of an entry in the static `licensed_from` / `licensed_to` array — mutual-assertion floor for licensing parallels mutual-assertion floor for ownership.

What this unblocks downstream

  • Franchisee brands can publicly declare which marks they hold under license without negotiating a transactional rights deal first.
  • Catalog owners can publish their licensee network (where commercially appropriate) so consumers know who's authorized.
  • Per-jurisdiction rights publishing — the "China license, self-managed elsewhere" case becomes a static-file declaration.
  • The verification surface returning licensed states stops being orphaned without an underlying static-file substrate.

Cross-team coordination

This is a brand-protocol RFC but touches the rights-protocol vocabulary. Should be designed alongside the rights-protocol team to avoid drift.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    brandIssue concerns the brand protocol domainenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions