Skip to content

Reference Patterns

Advanced patterns for using $id and $ref in toolkit manifests.

How References Work

Toolkit manifests use a JSON Schema-inspired reference system:

Field Purpose Example
$id Declare a local identifier "$id": "my-template"
$ref Reference another entity by its $id "$ref": "my-template"

When you install a toolkit, Contio:

  1. Parses all entities and their $id values
  2. Creates database records for each entity
  3. Resolves $ref pointers to actual database IDs
  4. Establishes foreign key relationships

Basic Reference Pattern

Define an entity with $id, reference it with $ref:

{
  "next_steps": [
    {
      "spec": {
        "$id": "follow-up",           // ← Declare identifier
        "name": "Follow-up Email",
        "type": "ai",
        "ai_prompt": "Draft a follow-up email based on the meeting notes.",
        "sort_order": 1
      }
    }
  ],
  "templates": [
    {
      "spec": {
        "$id": "sales-call",
        "name": "Sales Call",
        "description": "Standard sales meeting template"
      },
      "next_steps": [
        {
          "next_step": { "$ref": "follow-up" },  // ← Reference by $id
          "sort_order": 1,
          "autopilot": false
        }
      ]
    }
  ]
}

Referencing Existing Database Entities

Use $id (without declaring it in the manifest) to reference pre-existing entities:

{
  "templates": [
    {
      "spec": {
        "$id": "new-template",
        "name": "My New Template",
        "description": "A template extending existing next steps"
      },
      "next_steps": [
        {
          "next_step": { "$id": "abc123-existing-nextstep-uuid" },
          "sort_order": 1,
          "autopilot": false
        }
      ]
    }
  ],
  "next_steps": []  // Note: We're not defining the next step here
}

This is useful when: - Linking to next steps from another toolkit - Reusing shared action buttons across toolkits - Extending existing templates with new relationships

ManifestRef: The Reference Object

Every reference in a manifest uses the ManifestRef structure:

{
  "$ref": "local-id",     // Reference manifest-defined entity
  "$id": "database-uuid"  // Reference existing database entity
}

Choose One

A ManifestRef must contain either $ref or $id, not both. If both are provided, $ref takes precedence.

Shared Components Pattern

Define reusable components once, reference them multiple times:

{
  "action_buttons": [
    {
      "spec": {
        "$id": "clipboard-btn",
        "name": "Copy to Clipboard",
        "delivery_mechanism": "clipboard",
        "content_format": "plain_text"
      }
    }
  ],
  "next_steps": [
    {
      "spec": {
        "$id": "summary",
        "name": "Meeting Summary",
        "type": "ai",
        "ai_prompt": "Generate a concise summary of the meeting."
      },
      "action_buttons": [
        { "action_button": { "$ref": "clipboard-btn" }, "sort_order": 1 }
      ]
    },
    {
      "spec": {
        "$id": "action-items",
        "name": "Action Items",
        "type": "ai",
        "ai_prompt": "Extract action items from the meeting."
      },
      "action_buttons": [
        { "action_button": { "$ref": "clipboard-btn" }, "sort_order": 1 }  // Same button!
      ]
    }
  ]
}

Resolution Order

References are resolved in a single pass after all entities are created:

  1. Parse Phase: All entities with $id are collected
  2. Create Phase: Database records created for each entity
  3. Link Phase: $ref pointers resolved to database IDs
  4. Commit Phase: All relationships established atomically

If any $ref cannot be resolved, the entire installation fails and rolls back.

Error Cases

Error Cause Fix
unknown reference: xyz $ref points to undefined $id Add entity with matching $id
duplicate $id: abc Same $id used twice Use unique identifiers
circular reference A references B, B references A Redesign entity hierarchy
invalid $id format When referencing database entity, UUID is malformed Use valid UUID

Best Practices

  1. Use descriptive $id values: "follow-up-email" > "ns1"
  2. Keep references shallow: Avoid deep nesting of references
  3. Group related entities: Keep templates and their next steps adjacent in the manifest
  4. Document external references: Comment when using $id for database entities
{
  "templates": [
    {
      "spec": {
        "$id": "my-template",
        "name": "My Template"
      },
      "next_steps": [
        {
          "next_step": { "$id": "shared-summary-step" },  // From "Core Templates" toolkit
          "sort_order": 1,
          "autopilot": false
        }
      ]
    }
  ]
}

See Also