429 lines
17 KiB
Org Mode
429 lines
17 KiB
Org Mode
#+TITLE: Agora Requirements - 04: The Primitive
|
|
#+author: Amero Garcia
|
|
#+created: [2026-03-16 Mon 14:28]
|
|
#+DATE: 2026-03-15
|
|
#+ID: agora-requirements-04-the-primitive
|
|
#+STARTUP: content
|
|
|
|
* The Primitive: The Atomic Foundation of Agora
|
|
|
|
** Concept: The Universal Data Primitive
|
|
|
|
The Primitive is Agora's foundational content layer—the base data structure upon which all social interaction, economic exchange, and identity management is built. Before there are posts, contracts, or profiles, there are Notes. The Note is the atomic, universal unit of information in Agora.
|
|
|
|
This elegant simplicity—the "Everything is a Note" paradigm—enables Agora's powerful interoperability, immutable audit trails, and seamless cross-application compatibility. By reducing all digital interactions to a single, cryptographically verifiable primitive, Agora creates a unified ecosystem where any application can understand and process any data, breaking down the silos that plague traditional digital platforms.
|
|
|
|
** The Note Structure
|
|
|
|
A Note is the atomic unit of information in Agora. Everything—posts, messages, contracts, profiles—is a Note with behavioral flags.
|
|
|
|
*** Technical Specification
|
|
|
|
Every Note is identified by its CID (Content Identifier):
|
|
- *Format:* CIDv1 with configurable codec and hash (Default: `dag-pb` + `sha2-256`).
|
|
- *Property:* Same content = same CID (deterministic).
|
|
- *Immutability:* Content cannot change without CID changing.
|
|
|
|
#+begin_src json
|
|
{
|
|
"cid": "string", // Unique content identifier
|
|
"owner": "DID", // Source of authority (Persona DID)
|
|
|
|
"is_feed": boolean, // Behavioral Intent: Chronological Flow (true) vs Static Page (false)
|
|
|
|
"contract": { ... }, // Optional: Rules of engagement (JSON Object)
|
|
"payload": "string", // Optional: The asset (Inline data or P2P CID)
|
|
"content_type": "string", // MIME type (e.g., text/markdown, image/jpeg)
|
|
|
|
"priority_fee": integer, // Optional: Relay routing priority (millisats)
|
|
"access_control": ["DID"], // Permissions (Omitted=Personal, []=Public)
|
|
"notify": ["DID"], // Attention (Target entities for push notifications)
|
|
|
|
"references": ["CID"], // Semantic links/citations
|
|
"reply_to": "CID", // Parent CID (for threading/negotiation)
|
|
"thread_root": "CID", // Root CID of the conversation/exchange
|
|
|
|
"ephemeral_duration": integer, // Expiry in seconds (0 = persistent)
|
|
"createdAt": "timestamp", // ISO-8601 creation time
|
|
|
|
"proof": { // Cryptographic authenticity
|
|
"editor": "DID", // Optional: The signer (defaults to owner)
|
|
"signature": "string" // Signature over Note content
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
** Behavioral Intent & Schema Validation
|
|
|
|
The single `is_feed` property defines the behavioral intent of a Note without changing its underlying technical structure.
|
|
|
|
*** Core Behavioral Intent
|
|
|
|
| Property | Type | Description |
|
|
|------|---------|----------|
|
|
| `is_feed` | boolean | Chronological timeline item (Post, Status, Update). If false/omitted, the Note is a static Page. |
|
|
|
|
*** The Contract & Payload Split
|
|
Every signed Note in Agora is inherently a contract. To clearly separate the "Rules of Engagement" from the "Asset", the Note structure defines two distinct fields:
|
|
|
|
- *`contract` (JSON Object):* Defines the terms. This includes both human-readable terms (e.g., `"license": "CC0"`) and machine-readable state (e.g., `"price_satoshis": 5000`).
|
|
- *`payload` (Polymorphic String):* Defines the asset governed by the contract. This can be:
|
|
1. *Inline Data:* Raw text, markdown, or small base64 blobs embedded directly.
|
|
2. *P2P Reference (CID):* A URI (e.g., `ipfs://Qm...`) pointing to a distributed Merkle DAG hosted by the PDS or the Swarm.
|
|
|
|
*** Audience & Visibility (access_control)
|
|
|
|
The visibility and routing of a Note are determined by the `access_control` array:
|
|
- *Personal (Private):* Omitted or `null`. The Note remains internal to the PDS.
|
|
- *Public (Broadcast):* Explicit empty array `[]`. The Note is pushed to all subscribed Relays for global indexing.
|
|
- *Restricted (Directed):* Array of target DIDs `["did:agora:bob"]`. The Note is routed only to the specified recipients.
|
|
|
|
*** Attention & Intent (notify)
|
|
|
|
The `notify` array defines who should receive a push notification or "Inbox" alert for the Note:
|
|
- *Personal/Silent:* Omitted or `null`. No entities are notified.
|
|
- *Targeted Ping:* Array of target DIDs `["did:agora:bob"]`. Triggers a notification for the specified entities.
|
|
|
|
*** Semantic Derivations
|
|
|
|
Because Agora uses a minimalist flag system, high-level social and economic concepts are reconstructed by clients using core flags, audience scope (`access_control`), and Note relationships (`references`, `reply_to`, `notify`).
|
|
|
|
**** Basic Content
|
|
- *Public Post:* `is_feed:true` + `access_control:[]`
|
|
- *Private DM:* `access_control:["did:agora:bob"]` + `notify:["did:agora:bob"]`
|
|
- *Static Page:* `is_feed:false` + `access_control:[]`
|
|
- *File:* A Note with a binary `content_type` (e.g., `image/jpeg`).
|
|
|
|
**** Social Graph & Interaction
|
|
- *Like / Reaction:* A Note that `references` a Content CID and contains a reaction payload. Typically `is_feed: false`.
|
|
- *Boost / Repost:* A Note that `references` a Content CID with `is_feed: true`, injecting it into the owner's chronological timeline.
|
|
- *Follow:* A Note that `references` a Persona DID.
|
|
- *Public Mention:* `access_control:[]` + `notify:[Target_DID]`.
|
|
- *Private Connection:* `access_control:[Target_DID]` + `notify:[Target_DID]`.
|
|
|
|
**** Economic & Contract Lifecycle
|
|
- *Contract Negotiation (Offer/Take/Task):* A Note represents a proposal (*Offer*), an acceptance (*Take*), or a commitment to perform work (*Task*) depending on its place in the `reply_to` chain.
|
|
- *Economic Lifecycle (Invoice/Payment/Escrow):*
|
|
- *Invoice*: A Note with a payment request in its `contract` (`price_satoshis`).
|
|
- *Payment*: A fulfillment Note (`Take`) containing cryptographic proof (e.g., `preimage`).
|
|
- *Escrow*: A Note referencing a multi-signature threshold in its `contract`.
|
|
- *Support / Subscribe:* A Note referencing a Persona DID, establishing a recurring payment stream or premium access in its `contract`.
|
|
|
|
**** Events & Coordination
|
|
- *Event Announcement:* A Note (usually `is_feed: true`) where the `contract` defines temporal/spatial rules (start time, location, capacity).
|
|
- *Invite:* A directed Note (`access_control: [DID]`, `notify: [DID]`) that `references` an Event Announcement. It serves as a contract *Offer* for attendance.
|
|
- *RSVP:* A Note that `reply_to` an Invite. The `contract` field contains the acceptance state (`{"rsvp": "attending"}`), acting as a *Take*.
|
|
|
|
*** Flag Combination Rules
|
|
|
|
Agora implements strict validation to ensure network integrity.
|
|
|
|
**** Rule 1: Flow (Feed vs. Page)
|
|
- `is_feed: true` indicates chronological content.
|
|
- `is_feed: false` (default) indicates static resource.
|
|
|
|
**** Rule 2: Audience Scope
|
|
- *Public Broadcast:* MUST use an explicit empty array `access_control: []`.
|
|
- *Restricted Routing:* MUST provide at least one recipient DID in `access_control`.
|
|
- *Personal:* Omission of `access_control` defaults to private storage on the PDS.
|
|
|
|
**** Rule 3: Requirements & Dependencies
|
|
- *Ephemerality:* The presence of `ephemeral_duration > 0` indicates the Note is ephemeral.
|
|
- *Restricted Access:* If `access_control` is populated, both the `contract` and `payload` SHOULD be encrypted into a single envelope for the specified audience.
|
|
|
|
*** Technical Specification (JSON Schema)
|
|
|
|
#+begin_src json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"$id": "https://agora.ai/schemas/content-flags.json",
|
|
"title": "Agora Note Flags",
|
|
"description": "Validation schema for the Binary Core flag set",
|
|
"type": "object",
|
|
"properties": {
|
|
"cid": {
|
|
"type": "string",
|
|
"description": "Unique content identifier.",
|
|
"pattern": "^[a-zA-Z0-9]+$"
|
|
},
|
|
"owner": {
|
|
"type": "string",
|
|
"description": "DID of the owner persona.",
|
|
"pattern": "^did:agora:[a-zA-Z0-9]+$"
|
|
},
|
|
"is_feed": {
|
|
"type": "boolean",
|
|
"description": "Chronological timeline item (Post/Update). If false, it's a static Page.",
|
|
"default": true
|
|
},
|
|
"contract": {
|
|
"type": "object",
|
|
"description": "Optional rules of engagement governing the payload (e.g. licensing, price).",
|
|
"additionalProperties": true
|
|
},
|
|
"payload": {
|
|
"type": "string",
|
|
"description": "The asset content (inline or P2P reference CID)."
|
|
},
|
|
"content_type": {
|
|
"type": "string",
|
|
"description": "MIME type of the content.",
|
|
"enum": [
|
|
"text/plain",
|
|
"text/markdown",
|
|
"text/html",
|
|
"application/json",
|
|
"image/jpeg",
|
|
"image/png",
|
|
"image/gif",
|
|
"video/mp4",
|
|
"audio/mpeg",
|
|
"application/pdf",
|
|
"application/zip",
|
|
"application/jwe"
|
|
]
|
|
},
|
|
"priority_fee": {
|
|
"type": "integer",
|
|
"description": "Relay routing priority in millisats.",
|
|
"minimum": 0
|
|
},
|
|
"access_control": {
|
|
"type": "array",
|
|
"description": "Determines audience. Omitted=Personal, []=Public, [DIDs]=Restricted.",
|
|
"items": {
|
|
"type": "string",
|
|
"pattern": "^did:agora:[a-zA-Z0-9]+$"
|
|
}
|
|
},
|
|
"notify": {
|
|
"type": "array",
|
|
"description": "Targets for push notifications.",
|
|
"items": {
|
|
"type": "string",
|
|
"pattern": "^did:agora:[a-zA-Z0-9]+$"
|
|
}
|
|
},
|
|
"references": {
|
|
"type": "array",
|
|
"description": "CIDs of related content objects.",
|
|
"items": {
|
|
"type": "string",
|
|
"pattern": "^[a-zA-Z0-9]+$"
|
|
}
|
|
},
|
|
"reply_to": {
|
|
"type": "string",
|
|
"description": "CID of content this is a reply to. Required for reply types.",
|
|
"pattern": "^[a-zA-Z0-9]+$"
|
|
},
|
|
"thread_root": {
|
|
"type": "string",
|
|
"description": "CID of the root post in a thread.",
|
|
"pattern": "^[a-zA-Z0-9]+$"
|
|
},
|
|
"ephemeral_duration": {
|
|
"type": "integer",
|
|
"description": "Duration in seconds for ephemeral content. If 0 or omitted, the Note is persistent.",
|
|
"minimum": 0,
|
|
"maximum": 31536000
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO-8601 creation timestamp."
|
|
},
|
|
"proof": {
|
|
"type": "object",
|
|
"description": "Cryptographic proof of authenticity.",
|
|
"properties": {
|
|
"editor": {
|
|
"type": "string",
|
|
"description": "Optional: DID of the signing persona. Defaults to owner if omitted.",
|
|
"pattern": "^did:agora:[a-zA-Z0-9]+$"
|
|
},
|
|
"signature": {
|
|
"type": "string",
|
|
"description": "Ed25519 signature over content hash.",
|
|
"pattern": "^[A-Za-z0-9+/]+=*$"
|
|
}
|
|
},
|
|
"required": ["signature"]
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
#+end_src
|
|
|
|
** Content Lifecycle & Persistence
|
|
|
|
*** Encryption: Security by Design
|
|
|
|
Security is woven into the fabric of the protocol. Agora uses industry-standard primitives to ensure that only intended recipients can access private content.
|
|
|
|
- *End-to-End Encryption (E2EE):* Private Notes use AES-256-GCM for payloads and X25519 for ECDH key exchange.
|
|
- *Forward Secrecy:* Agora employs Double Ratchet for 1-on-1 messaging and MLS (Messaging Layer Security) for groups, rotating keys per-message.
|
|
|
|
*** Ephemeral Content Enforcement
|
|
|
|
The `is_ephemeral: true` flag is enforced through three complementary mechanisms:
|
|
|
|
1. *Time-Locked Encryption (Primary):* Payloads are encrypted with keys that can only be retrieved from a Decentralized Key Management Network (DKMN) or solved via a Time-Lock Puzzle before the expiration time.
|
|
2. *Key Shedding (Forward Secrecy):* For DMs, the client securely deletes the specific message key after the display duration expires.
|
|
3. *Voluntary Infrastructure Compliance:* PDS nodes MUST garbage collect expired CIDs, and Relays MUST drop them from routing tables.
|
|
|
|
*** Note Persistence (PDS)
|
|
|
|
- *Home Base:* All Notes are stored in the owner's Personal Data Store (PDS) by default.
|
|
- *Availability:* Content is hosted by the PDS, replicated across mirrors, and cached by Relays/clients for performance.
|
|
- *Lifecycle:* Create → Store (PDS) → Announce (Relay) → Fetch → Decrypt → Render.
|
|
|
|
** Relationships, Sync & Performance
|
|
|
|
*** Note Relationships
|
|
Agora uses three distinct fields to define relationships between Notes, balancing semantic precision with high-performance discovery.
|
|
|
|
**** Threading & Reference Logic
|
|
|
|
- *`references` (Array, 0-N):* General semantic linking. This field is used for citations, user mentions, quoting other posts, or attaching auxiliary Content Objects. It tells the network: "This Note is related to these other things."
|
|
- *`reply_to` (Single, 0-1):* Direct parentage. This field is mandatory for any Note that is part of a branching conversation. It defines the exact hierarchy for UI indentation and determines which owner should receive a notification.
|
|
- *`thread_root` (Single, 0-1):* The Global Anchor. This points to the very first Note that initiated the entire conversation. It allows clients to fetch thousands of replies in a single batch query, avoiding the "N+1 fetch" performance bottleneck.
|
|
|
|
***** Comparison Summary
|
|
|
|
| Field | Cardinality | Primary Role | UI Impact |
|
|
| :--- | :--- | :--- | :--- |
|
|
| *`references`* | Array (0-N) | Citation/Linking | Link previews, mentions |
|
|
| *`reply_to`* | Single (0-1) | Parentage | Nesting/Indentation |
|
|
| *`thread_root`* | Single (0-1) | Grouping | "View Full Thread" performance |
|
|
|
|
***** Example Implementation Scenario
|
|
Alice posts a product listing (Note A). Bob asks a question (Note B) about the listing. Charlie replies to Bob (Note C) but also quotes Alice's original product photo (Note D) in his comment.
|
|
|
|
*Charlie's Note (Note C) logic:*
|
|
- `thread_root`: CID of Note A (The listing anchor).
|
|
- `reply_to`: CID of Note B (The immediate parent).
|
|
- `references`: [CID of Note B, CID of Note D] (The citations).
|
|
|
|
*** Large Payload Handling
|
|
- *Streaming Protocol:* Files >100MB are split into 1MB chunks and represented as a Merkle DAG.
|
|
- *Streaming CIDs:* The root CID points to the tree, allowing concurrent, prioritized downloading of chunks.
|
|
|
|
*** Real-time Sync & Collaboration
|
|
- *Live Collaboration:* Agora uses CRDTs (Conflict-free Replicated Data Types) for shared state (e.g., co-editing a document).
|
|
- *Ephemeral Channels:* Real-time updates (like typing indicators) are broadcast via Relay WebSockets without being committed to the PDS as permanent Notes.
|
|
|
|
*** Content Deduplication
|
|
- *Block-level Deduplication:* Since payloads are content-addressed, PDS nodes only store identical data once, using reference counting to manage garbage collection.
|
|
|
|
** Validation Reference (Examples)
|
|
|
|
*** Valid: Public Post
|
|
#+begin_src json
|
|
{
|
|
"cid": "QmPost123",
|
|
"owner": "did:agora:alice",
|
|
"is_feed": true,
|
|
"contract": {
|
|
"license": "CC-BY-4.0"
|
|
},
|
|
"payload": "Hello, Agora!",
|
|
"content_type": "text/markdown",
|
|
"access_control": [],
|
|
"createdAt": "2026-03-25T14:30:00Z",
|
|
"proof": {
|
|
"signature": "abc123..."
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** Valid: Private DM
|
|
#+begin_src json
|
|
{
|
|
"cid": "QmDM456",
|
|
"owner": "did:agora:alice",
|
|
"payload": "eyhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0...",
|
|
"content_type": "application/jwe",
|
|
"access_control": ["did:agora:bob", "did:agora:alice"],
|
|
"notify": ["did:agora:bob"],
|
|
"createdAt": "2026-03-25T14:35:00Z",
|
|
"proof": {
|
|
"signature": "def456..."
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** Valid: Digital Storefront (Split-State Encryption)
|
|
#+begin_src json
|
|
{
|
|
"cid": "QmStore789",
|
|
"owner": "did:agora:alice",
|
|
"is_feed": false,
|
|
"contract": {
|
|
"title": "Exclusive Indie Film",
|
|
"price_satoshis": 50000,
|
|
"decryption_method": "LSAT"
|
|
},
|
|
"payload": "ipfs://QmEncryptedVideoChunks...",
|
|
"content_type": "application/vnd.agora.encrypted+video/mp4",
|
|
"priority_fee": 1000,
|
|
"access_control": [],
|
|
"createdAt": "2026-03-25T14:40:00Z",
|
|
"proof": {
|
|
"signature": "xyz012..."
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** Valid: Ephemeral Story (Public)
|
|
#+begin_src json
|
|
{
|
|
"cid": "QmStory789",
|
|
"owner": "did:agora:alice",
|
|
"is_feed": true,
|
|
"payload": "This disappears in 24 hours",
|
|
"access_control": [],
|
|
"ephemeral_duration": 86400,
|
|
"createdAt": "2026-03-25T14:45:00Z",
|
|
"proof": {
|
|
"editor": "did:agora:bot_agent",
|
|
"signature": "ghi789..."
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** Invalid: Broadcast Conflict
|
|
#+begin_src json
|
|
{
|
|
"cid": "QmInvalid001",
|
|
"access_control": [],
|
|
"payload": "encrypted-blob-here",
|
|
"content_type": "application/jwe"
|
|
}
|
|
#+end_src
|
|
Validation error: Public broadcast (`access_control: []`) cannot contain an encrypted payload.
|
|
|
|
*** Invalid: Restricted without Audience
|
|
#+begin_src json
|
|
{
|
|
"cid": "QmInvalid002",
|
|
"notify": ["did:agora:bob"]
|
|
}
|
|
#+end_src
|
|
Validation error: Notifications (`notify`) require the target DID to be present in the `access_control` list or for the Note to be public.
|
|
|
|
** Related Documents
|
|
|
|
- [[file:agora-requirements-02-identity.org][Identity]] - Personas and contracts
|
|
- [[file:agora-requirements-03-infrastructure.org][Infrastructure]] - PDS and Relay
|
|
- [[file:agora-requirements-05-social.org][Social]] - Relationships and communication
|
|
- [[file:agora-requirements-06-exchange.org][Exchange]] - Economic layer
|
|
|
|
** Gaps
|
|
|
|
- *None.* All identified gaps in the primitive layer have been resolved.
|
|
|
|
# Local Variables:
|
|
# org-confirm-babel-evaluate: nil
|
|
# End:
|