Creators paid by any platform
Your agent writes these files into openspec/changes/integrate-aisot-source-terms/ in your repo, runs openspec validate integrate-aisot-source-terms, and works the task list. The setup guide explains each step for people.
language: http · python · typescript with: none fits this use case
OPENSPEC/CHANGES/INTEGRATE-AISOT-SOURCE-TERMS/PROPOSAL.MD
# Proposal: Creators paid by any platform
## Why
Each platform runs its own creator program, and creators sign up one by one. A claim and a terms record here are read by every platform that adopts them, and payout records show who paid.
## What Changes
- The creator claims a domain, GitHub account or DOI and proves control.
- The creator publishes standing terms: deny, attribute or a royalty rate.
- A platform reads the terms, pays on its own rails, and publishes a payout record.
## Capabilities
### New Capabilities
- `source-terms`: Claim a domain once and publish signed terms. Platforms read them, pay on their own rails, and record the payout.
## Impact
- External service: AI Source of Truth at https://aisourceoftruth.com. Reads are anonymous. Writes need a publisher key pair you generate, a client id and secret from registration, and a token from `/oauth/token`.
- Routes used: `POST /v1/source-claims`, `POST /v1/source-claims/verify`, `POST /v1/terms`, `GET /v1/sources/{source_id}/terms`, `POST /v1/records`.
- No PromptReports product is required.
- Source of this plan: https://aisourceoftruth.com/use-cases/creators-paid (CC0). Regenerate it with `curl -H 'Accept: application/json' 'https://aisourceoftruth.com/use-cases/creators-paid/openspec?lang=python'`.
OPENSPEC/CHANGES/INTEGRATE-AISOT-SOURCE-TERMS/DESIGN.MD
# Design: Creators paid by any platform
## Context
Writers and creators, and the platforms that use their work. Each platform runs its own creator program, and creators sign up one by one. A claim and a terms record here are read by every platform that adopts them, and payout records show who paid.
## Where it sits in your agent
Creators do this once. Platforms put the terms read in the ingest step and the payout record in their monthly payout job.
Over MCP, point the agent at `https://aisourceoftruth.com/mcp` (Streamable HTTP, JSON-RPC 2.0; read tools need no token). The tools this change uses: `publish_record`, `lookup`.
## Decisions
- Treat the registry as a source of facts about records, never about the world. Show what it says, with the digest, and do not turn a verdict into a quality score.
- If the registry cannot be reached, treat the answer as unknown (the same as `check`), never as `rely`, and retry later.
- Keep content private: send hashes. Never put personal data in a record; it is public and permanent.
- Keep the private key and client secret in your secret store. Rotate keys at `POST /v1/keys`; a revoked key cannot sign.
## Setup and signing helper
```python
# pip install requests cryptography
import base64, json, os, uuid
import requests
from cryptography.hazmat.primitives.serialization import load_pem_private_key
AISOT = os.environ.get("AISOT_ORIGIN", "https://aisourceoftruth.com")
KEY = load_pem_private_key(open(os.environ["AISOT_KEY_PEM"], "rb").read(), password=None) # Ed25519
def token():
r = requests.post(f"{AISOT}/oauth/token", json={
"grant_type": "client_credentials",
"client_id": os.environ["AISOT_CLIENT_ID"],
"client_secret": os.environ["AISOT_CLIENT_SECRET"],
})
r.raise_for_status()
return r.json()["access_token"] # lasts 60 minutes
def signed_post(path, body, content_type="application/json", token=token):
raw = json.dumps(body, separators=(",", ":")).encode()
sig = base64.urlsafe_b64encode(KEY.sign(raw)).rstrip(b"=").decode()
headers = {"Content-Type": content_type, "X-AISOT-Signature": sig, "Idempotency-Key": str(uuid.uuid4())}
if token:
headers["Authorization"] = f"Bearer {token()}"
headers["X-AISOT-Key-Id"] = os.environ["AISOT_KEY_ID"]
r = requests.post(f"{AISOT}{path}", data=raw, headers=headers)
r.raise_for_status()
return r.json()
```
## Calls
### POST /v1/source-claims
claim a source (pending until verified).
```python
answer = signed_post("/v1/source-claims", {"source_id":"{domain, github.com/owner or DOI}","method":"dns-txt","proof":"{proof}"})
```
### POST /v1/source-claims/verify
check the claim's proof and promote it.
```python
answer = signed_post("/v1/source-claims/verify", {"source_id":"{source id}"})
```
### POST /v1/terms
publish standing terms for a claimed source.
```python
answer = signed_post("/v1/terms", {"source_id":"{source id}","license_id":"AISOT-ATTRIB"})
```
### GET /v1/sources/{source_id}/terms
read a source's standing terms.
```python
r = requests.get(f"{AISOT}/v1/sources/{source_id}/terms", headers={"Accept": "application/json"})
r.raise_for_status()
answer = r.json()
```
### POST /v1/records
append a signed record; the answer carries its digest and inclusion proof.
```python
answer = signed_post("/v1/records", record, content_type="application/vnd.aisot.record+json")
```
## What this does not prove
- The registry records terms and payments. It never holds, moves or settles money.
OPENSPEC/CHANGES/INTEGRATE-AISOT-SOURCE-TERMS/TASKS.MD
# Tasks: Creators paid by any platform
## 1. Configure
- [ ] 1.1 Set `AISOT_ORIGIN=https://aisourceoftruth.com` in the agent's environment.
- [ ] 1.2 Generate an Ed25519 key pair, register the publisher (`POST /v1/publishers`), and store `AISOT_CLIENT_ID`, `AISOT_CLIENT_SECRET`, `AISOT_KEY_ID` and the private key as secrets.
- [ ] 1.3 Mint a token at `/oauth/token` and confirm `GET /v1/me` answers with your publisher id.
- [ ] 1.4 Optional: add the MCP server `https://aisourceoftruth.com/mcp` to the agent's MCP config.
## 2. Build
- [ ] 2.1 Claim the source: Claim your domain with DNS TXT (`_aisot.<domain>` carries `aisot-verify=<publisher_id>`), your GitHub account with OAuth, or a DOI. (`POST /v1/source-claims`)
- [ ] 2.2 Verify the claim: Run the verify call once the proof is in place. (`POST /v1/source-claims/verify`)
- [ ] 2.3 Publish terms: Choose `AISOT-DENY`, `AISOT-ATTRIB` or `AISOT-ROYALTY-{rate}` such as `AISOT-ROYALTY-0.05`. (`POST /v1/terms`)
- [ ] 2.4 Platforms read and pay: A platform reads the terms before use, pays on its own rails, and posts a `payout` record with source, period, amount as a string, currency and settlement provider. (`GET /v1/sources/{source_id}/terms`)
## 3. Verify against the live registry
- [ ] 3.1 Claim the source: The claim is listed as pending.
- [ ] 3.2 Verify the claim: The claim shows as verified.
- [ ] 3.3 Publish terms: The terms read back at the GET route.
- [ ] 3.4 Platforms read and pay: The source page lists the payout.
## 4. Done when
- [ ] 4.1 One claim makes a creator addressable by every adopting platform.
- [ ] 4.2 Payouts are public records any creator can check.
OPENSPEC/CHANGES/INTEGRATE-AISOT-SOURCE-TERMS/SPECS/SOURCE-TERMS/SPEC.MD
# source-terms Specification ## ADDED Requirements ### Requirement: Terms are read before use The platform SHALL read a claimed source's terms before using its work and SHALL exclude work under `AISOT-DENY`. #### Scenario: Royalty terms - **WHEN** a source's terms are `AISOT-ROYALTY-0.05` - **THEN** the platform accrues the royalty and later publishes a payout record
$ curl -H 'Accept: application/json' https://aisourceoftruth.com/use-cases/creators-paid/openspec?lang=python # this page is a rendering of the API. Reproduce it as data.