Arke
Understand

Entity Model

The Eidos schema—the universal envelope structure for every entity in Arke.

The Eidos Schema

Every entity in Arke—regardless of type—is stored as an Eidos manifest. The schema defines the envelope; type profiles define what goes inside.

interface EidosV1 {
  // Identity (immutable after creation)
  schema: 'arke/eidos@v1';
  id: string;                          // Entity ID (ULID)
  type: string;                        // Entity type name
  created_at: string;                  // ISO 8601 timestamp

  // Versioning
  ver: number;                         // Version number (starts at 1)
  ts: number;                          // Unix timestamp in milliseconds
  prev: { '/': string } | null;       // Previous version CID (null for v1)

  // Content
  properties: Record<string, unknown>; // Metadata key-value pairs
  relationships: Relationship[];       // Connections to other entities

  // Audit
  edited_by: EditInfo;                 // Who made this version
  note?: string;                       // Version description
}

The prev field uses the IPLD link convention { "/": "someCid" } to point to the previous version. This creates an immutable chain:

v3 (current tip)
  └── prev → v2
                └── prev → v1
                              └── prev → null

Every version is stored by its content hash. You can traverse the full history of any entity by following prev links.

Relationships

Relationships connect entities to each other:

interface Relationship {
  predicate: string;       // e.g. "contains", "references", "parent"
  peer: string;            // Target entity ID
  peer_type?: string;      // Target's type hint
  peer_label?: string;     // Display name (denormalized)
  properties?: Record<string, unknown>; // Relationship metadata
}

Relationships are directional and stored as part of the entity manifest. Common predicates include contains (parent to child), in (child to parent), extracted_from (reference to original source)

Edit Info

Every version records who made the change and how:

interface EditInfo {
  user_id: string;                     // User or agent entity ID
  method: 'manual' | 'ai_generated' | 'system' | 'import';
  on_behalf_of?: string;              // Original user if acting via agent
}

Example: A Chapter Entity

Here's what the Eidos manifest for "Chapter 1. Loomings" (01KFNR849AZNBWE9DYJRZR7PSA) might look like:

{
  "schema": "arke/eidos@v1",
  "id": "01KFNR849AZNBWE9DYJRZR7PSA",
  "type": "file",
  "created_at": "2025-01-15T10:30:00Z",
  "ver": 1,
  "ts": 1736937000000,
  "prev": null,
  "properties": {
    "label": "Chapter 1. Loomings",
    "chapter_number": 1,
    "first_line": "Call me Ishmael."
  },
  "relationships": [
    {
      "predicate": "in",
      "peer": "01KFNR81RMVAX2BBMMBW51V97D",
      "peer_type": "folder",
      "peer_label": "Moby Dick; Or, The Whale"
    },
    {
      "predicate": "collection",
      "peer": "01KFNR0H0Q791Y1SMZWEQ09FGV",
      "peer_type": "collection"
    }
  ],
  "edited_by": {
    "user_id": "01JUSER...",
    "method": "import"
  }
}

The chapter links back to its parent folder via the in relationship, while the folder entity would have a contains relationship pointing to this chapter. The collection relationship determines permissions.

Content Map

Any entity can have binary content attached via properties.content. This is a map of keys to content entries:

interface ContentEntry {
  cid: string;           // Content identifier (hash of bytes)
  size: number;          // Size in bytes
  content_type: string;  // MIME type
  filename?: string;     // Original filename
  uploaded_at: string;   // ISO 8601 timestamp
}

Example with multiple content slots:

{
  "properties": {
    "label": "Annual Report",
    "content": {
      "original": {
        "cid": "bafkrei...",
        "size": 2048576,
        "content_type": "application/pdf",
        "filename": "report.pdf",
        "uploaded_at": "2025-01-15T10:30:00Z"
      },
      "thumbnail": {
        "cid": "bafkrei...",
        "size": 10240,
        "content_type": "image/png",
        "uploaded_at": "2025-01-15T10:31:00Z"
      }
    }
  }
}

Type Profiles

The base Eidos schema is intentionally minimal. Type-specific validation, required properties, and expected relationships are defined by profiles:

TypeProfileWhat it adds
collectionarke/collection@v1Roles, membership, permission rules
filearke/file@v1Optimized for file management (any entity can have content)
folderarke/folder@v1Hierarchical containment within collections
userarke/user@v1Display name, email, auth provider mapping

See the Schema Reference for full details on each profile.

On this page