{"id":"98effa6b-0aba-4a52-a233-1936730bfe31","entityType":"agent","slug":"clawhub-oswalpalash-ontology-2","name":"ontology","canonicalUrl":"https://www.xpersona.co/agent/clawhub-oswalpalash-ontology-2","canonicalPath":"/agent/clawhub-oswalpalash-ontology-2","generatedAt":"2026-10-09T22:53:32.162Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-05-22T06:53:19.879Z","emptyReason":null},"description":"Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linkin...","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 183.2K downloads reported by the source. Last updated 5/22/2026.","installCommand":"clawhub skill install publishers:oswalpalash:ontology","sourceUrl":"https://clawhub.ai/oswalpalash/ontology","homepage":"https://clawhub.ai/oswalpalash/ontology","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/oswalpalash/ontology","kind":"source"}],"safetyScore":84,"overallRank":62,"popularityScore":100,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"ontology technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-05-22T06:53:19.879Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-05-22T06:53:19.879Z","emptyReason":null},"stars":null,"forks":null,"downloads":183169,"packageName":null,"latestVersion":"1.0.4","tractionLabel":"183.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-05-22T06:53:19.817Z","emptyReason":null},"lastUpdatedAt":"2026-05-22T06:53:19.879Z","lastCrawledAt":"2026-05-22T06:53:19.817Z","lastIndexedAt":null,"nextCrawlAt":"2026-05-23T06:53:19.817Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.4","createdAt":"2026-03-11T17:19:19.725Z","changelog":"- Initial release of the ontology skill for typed, constraint-validated knowledge graphs. - Supports entity and relation CRUD, property and relation validation, and graph traversal for common types such as Person, Project, Task, Event, and Document. - Provides schema-driven constraints including required properties, enums, forbidden fields, cardinality, and acyclicity. - Enables multi-step planning and shared memory across skills via structured ontology objects. - Includes CLI tooling for creating, querying, linking, and validating graph data using JSONL storage.","fileCount":5,"zipByteSize":12362},{"version":"0.1.2","createdAt":"2026-02-13T13:53:13.271Z","changelog":"No functional or documentation changes were detected in this release. - Version bumped to 0.1.2 with no file or content changes.","fileCount":5,"zipByteSize":12363},{"version":"0.1.1","createdAt":"2026-02-12T16:00:52.938Z","changelog":"- Added an \"Append-Only Rule\" to encourage appending or merging ontology data and schema changes rather than overwriting files, preserving history and prior definitions. - Updated quick start instructions to use `schema-append` for safely modifying schemas instead of direct file editing. - Expanded the documentation to clarify that runtime commands and validations operate on local files, create necessary directories, and are within the skill's supported behaviors. - Clarified the scope of validation: property, enum, forbidden checks, relation validation, acyclicity, and specific Event constraints are supported; higher-level constraints remain documentation unless implemented.","fileCount":5,"zipByteSize":11919},{"version":"0.1.0","createdAt":"2026-01-26T08:17:15.751Z","changelog":"Initial release: typed knowledge graph for agent memory, entity CRUD, relations, constraints, skill interop","fileCount":5,"zipByteSize":10053}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install publishers:oswalpalash:ontology","setupComplexity":"low","setupSteps":["Install using `clawhub skill install publishers:oswalpalash:ontology` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/oswalpalash/ontology before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-09T22:53:32.162Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology-2/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-05-22T06:53:19.879Z","emptyReason":null},"readme":"Skill: ontology\n\nOwner: oswalpalash\n\nSummary: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linkin...\n\nTags: latest:1.0.4\n\nVersion history:\n\nv1.0.4 | 2026-03-11T17:19:19.725Z | user\n\n- Initial release of the ontology skill for typed, constraint-validated knowledge graphs.\n- Supports entity and relation CRUD, property and relation validation, and graph traversal for common types such as Person, Project, Task, Event, and Document.\n- Provides schema-driven constraints including required properties, enums, forbidden fields, cardinality, and acyclicity.\n- Enables multi-step planning and shared memory across skills via structured ontology objects.\n- Includes CLI tooling for creating, querying, linking, and validating graph data using JSONL storage.\n\nv0.1.2 | 2026-02-13T13:53:13.271Z | user\n\nNo functional or documentation changes were detected in this release.\n\n- Version bumped to 0.1.2 with no file or content changes.\n\nv0.1.1 | 2026-02-12T16:00:52.938Z | user\n\n- Added an \"Append-Only Rule\" to encourage appending or merging ontology data and schema changes rather than overwriting files, preserving history and prior definitions.\n- Updated quick start instructions to use `schema-append` for safely modifying schemas instead of direct file editing.\n- Expanded the documentation to clarify that runtime commands and validations operate on local files, create necessary directories, and are within the skill's supported behaviors.\n- Clarified the scope of validation: property, enum, forbidden checks, relation validation, acyclicity, and specific Event constraints are supported; higher-level constraints remain documentation unless implemented.\n\nv0.1.0 | 2026-01-26T08:17:15.751Z | user\n\nInitial release: typed knowledge graph for agent memory, entity CRUD, relations, constraints, skill interop\n\nArchive index:\n\nArchive v1.0.4: 5 files, 12362 bytes\n\nFiles: references/queries.md (5471b), references/schema.md (6650b), scripts/ontology.py (21596b), SKILL.md (6703b), _meta.json (127b)\n\nFile v1.0.4:SKILL.md\n\n---\nname: ontology\ndescription: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on \"remember\", \"what do I know about\", \"link X to Y\", \"show dependencies\", entity CRUD, or cross-skill data access.\n---\n\n# Ontology\n\nA typed vocabulary + constraint system for representing knowledge as a verifiable graph.\n\n## Core Concept\n\nEverything is an **entity** with a **type**, **properties**, and **relations** to other entities. Every mutation is validated against type constraints before committing.\n\n```\nEntity: { id, type, properties, relations, created, updated }\nRelation: { from_id, relation_type, to_id, properties }\n```\n\n## When to Use\n\n| Trigger | Action |\n|---------|--------|\n| \"Remember that...\" | Create/update entity |\n| \"What do I know about X?\" | Query graph |\n| \"Link X to Y\" | Create relation |\n| \"Show all tasks for project Z\" | Graph traversal |\n| \"What depends on X?\" | Dependency query |\n| Planning multi-step work | Model as graph transformations |\n| Skill needs shared state | Read/write ontology objects |\n\n## Core Types\n\n```yaml\n# Agents & People\nPerson: { name, email?, phone?, notes? }\nOrganization: { name, type?, members[] }\n\n# Work\nProject: { name, status, goals[], owner? }\nTask: { title, status, due?, priority?, assignee?, blockers[] }\nGoal: { description, target_date?, metrics[] }\n\n# Time & Place\nEvent: { title, start, end?, location?, attendees[], recurrence? }\nLocation: { name, address?, coordinates? }\n\n# Information\nDocument: { title, path?, url?, summary? }\nMessage: { content, sender, recipients[], thread? }\nThread: { subject, participants[], messages[] }\nNote: { content, tags[], refs[] }\n\n# Resources\nAccount: { service, username, credential_ref? }\nDevice: { name, type, identifiers[] }\nCredential: { service, secret_ref }  # Never store secrets directly\n\n# Meta\nAction: { type, target, timestamp, outcome? }\nPolicy: { scope, rule, enforcement }\n```\n\n## Storage\n\nDefault: `memory/ontology/graph.jsonl`\n\n```jsonl\n{\"op\":\"create\",\"entity\":{\"id\":\"p_001\",\"type\":\"Person\",\"properties\":{\"name\":\"Alice\"}}}\n{\"op\":\"create\",\"entity\":{\"id\":\"proj_001\",\"type\":\"Project\",\"properties\":{\"name\":\"Website Redesign\",\"status\":\"active\"}}}\n{\"op\":\"relate\",\"from\":\"proj_001\",\"rel\":\"has_owner\",\"to\":\"p_001\"}\n```\n\nQuery via scripts or direct file ops. For complex graphs, migrate to SQLite.\n\n### Append-Only Rule\n\nWhen working with existing ontology data or schema, **append/merge** changes instead of overwriting files. This preserves history and avoids clobbering prior definitions.\n\n## Workflows\n\n### Create Entity\n\n```bash\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'\n```\n\n### Query\n\n```bash\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\npython3 scripts/ontology.py get --id task_001\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n```\n\n### Link Entities\n\n```bash\npython3 scripts/ontology.py relate --from proj_001 --rel has_task --to task_001\n```\n\n### Validate\n\n```bash\npython3 scripts/ontology.py validate  # Check all constraints\n```\n\n## Constraints\n\nDefine in `memory/ontology/schema.yaml`:\n\n```yaml\ntypes:\n  Task:\n    required: [title, status]\n    status_enum: [open, in_progress, blocked, done]\n  \n  Event:\n    required: [title, start]\n    validate: \"end >= start if end exists\"\n\n  Credential:\n    required: [service, secret_ref]\n    forbidden_properties: [password, secret, token]  # Force indirection\n\nrelations:\n  has_owner:\n    from_types: [Project, Task]\n    to_types: [Person]\n    cardinality: many_to_one\n  \n  blocks:\n    from_types: [Task]\n    to_types: [Task]\n    acyclic: true  # No circular dependencies\n```\n\n## Skill Contract\n\nSkills that use ontology should declare:\n\n```yaml\n# In SKILL.md frontmatter or header\nontology:\n  reads: [Task, Project, Person]\n  writes: [Task, Action]\n  preconditions:\n    - \"Task.assignee must exist\"\n  postconditions:\n    - \"Created Task has status=open\"\n```\n\n## Planning as Graph Transformation\n\nModel multi-step plans as a sequence of graph operations:\n\n```\nPlan: \"Schedule team meeting and create follow-up tasks\"\n\n1. CREATE Event { title: \"Team Sync\", attendees: [p_001, p_002] }\n2. RELATE Event -> has_project -> proj_001\n3. CREATE Task { title: \"Prepare agenda\", assignee: p_001 }\n4. RELATE Task -> for_event -> event_001\n5. CREATE Task { title: \"Send summary\", assignee: p_001, blockers: [task_001] }\n```\n\nEach step is validated before execution. Rollback on constraint violation.\n\n## Integration Patterns\n\n### With Causal Inference\n\nLog ontology mutations as causal actions:\n\n```python\n# When creating/updating entities, also log to causal action log\naction = {\n    \"action\": \"create_entity\",\n    \"domain\": \"ontology\", \n    \"context\": {\"type\": \"Task\", \"project\": \"proj_001\"},\n    \"outcome\": \"created\"\n}\n```\n\n### Cross-Skill Communication\n\n```python\n# Email skill creates commitment\ncommitment = ontology.create(\"Commitment\", {\n    \"source_message\": msg_id,\n    \"description\": \"Send report by Friday\",\n    \"due\": \"2026-01-31\"\n})\n\n# Task skill picks it up\ntasks = ontology.query(\"Commitment\", {\"status\": \"pending\"})\nfor c in tasks:\n    ontology.create(\"Task\", {\n        \"title\": c.description,\n        \"due\": c.due,\n        \"source\": c.id\n    })\n```\n\n## Quick Start\n\n```bash\n# Initialize ontology storage\nmkdir -p memory/ontology\ntouch memory/ontology/graph.jsonl\n\n# Create schema (optional but recommended)\npython3 scripts/ontology.py schema-append --data '{\n  \"types\": {\n    \"Task\": { \"required\": [\"title\", \"status\"] },\n    \"Project\": { \"required\": [\"name\"] },\n    \"Person\": { \"required\": [\"name\"] }\n  }\n}'\n\n# Start using\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\"}'\npython3 scripts/ontology.py list --type Person\n```\n\n## References\n\n- `references/schema.md` — Full type definitions and constraint patterns\n- `references/queries.md` — Query language and traversal examples\n\n## Instruction Scope\n\nRuntime instructions operate on local files (`memory/ontology/graph.jsonl` and `memory/ontology/schema.yaml`) and provide CLI usage for create/query/relate/validate; this is within scope. The skill reads/writes workspace files and will create the `memory/ontology` directory when used. Validation includes property/enum/forbidden checks, relation type/cardinality validation, acyclicity for relations marked `acyclic: true`, and Event `end >= start` checks; other higher-level constraints may still be documentation-only unless implemented in code.\n\nFile v1.0.4:_meta.json\n\n{\n  \"ownerId\": \"kn72dv4fm7ss7swbq47nnpad9x7zy2jh\",\n  \"slug\": \"ontology\",\n  \"version\": \"1.0.4\",\n  \"publishedAt\": 1773249559725\n}\n\nFile v1.0.4:references/queries.md\n\n# Query Reference\n\nQuery patterns and graph traversal examples.\n\n## Basic Queries\n\n### Get by ID\n\n```bash\npython3 scripts/ontology.py get --id task_001\n```\n\n### List by Type\n\n```bash\n# All tasks\npython3 scripts/ontology.py list --type Task\n\n# All people\npython3 scripts/ontology.py list --type Person\n```\n\n### Filter by Properties\n\n```bash\n# Open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n\n# High priority tasks\npython3 scripts/ontology.py query --type Task --where '{\"priority\":\"high\"}'\n\n# Tasks assigned to specific person (by property)\npython3 scripts/ontology.py query --type Task --where '{\"assignee\":\"p_001\"}'\n```\n\n## Relation Queries\n\n### Get Related Entities\n\n```bash\n# Tasks belonging to a project (outgoing)\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# What projects does this task belong to (incoming)\npython3 scripts/ontology.py related --id task_001 --rel part_of --dir incoming\n\n# All relations for an entity (both directions)\npython3 scripts/ontology.py related --id p_001 --dir both\n```\n\n### Common Patterns\n\n```bash\n# Who owns this project?\npython3 scripts/ontology.py related --id proj_001 --rel has_owner\n\n# What events is this person attending?\npython3 scripts/ontology.py related --id p_001 --rel attendee_of --dir outgoing\n\n# What's blocking this task?\npython3 scripts/ontology.py related --id task_001 --rel blocked_by --dir incoming\n```\n\n## Programmatic Queries\n\n### Python API\n\n```python\nfrom scripts.ontology import load_graph, query_entities, get_related\n\n# Load the graph\nentities, relations = load_graph(\"memory/ontology/graph.jsonl\")\n\n# Query entities\nopen_tasks = query_entities(\"Task\", {\"status\": \"open\"}, \"memory/ontology/graph.jsonl\")\n\n# Get related\nproject_tasks = get_related(\"proj_001\", \"has_task\", \"memory/ontology/graph.jsonl\")\n```\n\n### Complex Queries\n\n```python\n# Find all tasks blocked by incomplete dependencies\ndef find_blocked_tasks(graph_path):\n    entities, relations = load_graph(graph_path)\n    blocked = []\n    \n    for entity in entities.values():\n        if entity[\"type\"] != \"Task\":\n            continue\n        if entity[\"properties\"].get(\"status\") == \"blocked\":\n            # Find what's blocking it\n            blockers = get_related(entity[\"id\"], \"blocked_by\", graph_path, \"incoming\")\n            incomplete_blockers = [\n                b for b in blockers \n                if b[\"entity\"][\"properties\"].get(\"status\") != \"done\"\n            ]\n            if incomplete_blockers:\n                blocked.append({\n                    \"task\": entity,\n                    \"blockers\": incomplete_blockers\n                })\n    \n    return blocked\n```\n\n### Path Queries\n\n```python\n# Find path between two entities\ndef find_path(from_id, to_id, graph_path, max_depth=5):\n    entities, relations = load_graph(graph_path)\n    \n    visited = set()\n    queue = [(from_id, [])]\n    \n    while queue:\n        current, path = queue.pop(0)\n        \n        if current == to_id:\n            return path\n        \n        if current in visited or len(path) >= max_depth:\n            continue\n        \n        visited.add(current)\n        \n        for rel in relations:\n            if rel[\"from\"] == current and rel[\"to\"] not in visited:\n                queue.append((rel[\"to\"], path + [rel]))\n            if rel[\"to\"] == current and rel[\"from\"] not in visited:\n                queue.append((rel[\"from\"], path + [{**rel, \"direction\": \"incoming\"}]))\n    \n    return None  # No path found\n```\n\n## Query Patterns by Use Case\n\n### Task Management\n\n```bash\n# All my open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\",\"assignee\":\"p_me\"}'\n\n# Overdue tasks (requires custom script for date comparison)\n# See references/schema.md for date handling\n\n# Tasks with no blockers\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n# Then filter in code for those with no incoming \"blocks\" relations\n```\n\n### Project Overview\n\n```bash\n# All tasks in project\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# Project team members\npython3 scripts/ontology.py related --id proj_001 --rel has_member\n\n# Project goals\npython3 scripts/ontology.py related --id proj_001 --rel has_goal\n```\n\n### People & Contacts\n\n```bash\n# All people\npython3 scripts/ontology.py list --type Person\n\n# People in an organization\npython3 scripts/ontology.py related --id org_001 --rel has_member\n\n# What's assigned to this person\npython3 scripts/ontology.py related --id p_001 --rel assigned_to --dir incoming\n```\n\n### Events & Calendar\n\n```bash\n# All events\npython3 scripts/ontology.py list --type Event\n\n# Events at a location\npython3 scripts/ontology.py related --id loc_001 --rel located_at --dir incoming\n\n# Event attendees\npython3 scripts/ontology.py related --id event_001 --rel attendee_of --dir incoming\n```\n\n## Aggregations\n\nFor complex aggregations, use Python:\n\n```python\nfrom collections import Counter\n\ndef task_status_summary(project_id, graph_path):\n    \"\"\"Count tasks by status for a project.\"\"\"\n    tasks = get_related(project_id, \"has_task\", graph_path)\n    statuses = Counter(t[\"entity\"][\"properties\"].get(\"status\", \"unknown\") for t in tasks)\n    return dict(statuses)\n\ndef workload_by_person(graph_path):\n    \"\"\"Count open tasks per person.\"\"\"\n    open_tasks = query_entities(\"Task\", {\"status\": \"open\"}, graph_path)\n    workload = Counter(t[\"properties\"].get(\"assignee\") for t in open_tasks)\n    return dict(workload)\n```\n\nFile v1.0.4:references/schema.md\n\n# Ontology Schema Reference\n\nFull type definitions and constraint patterns for the ontology graph.\n\n## Core Types\n\n### Agents & People\n\n```yaml\nPerson:\n  required: [name]\n  properties:\n    name: string\n    email: string?\n    phone: string?\n    organization: ref(Organization)?\n    notes: string?\n    tags: string[]?\n\nOrganization:\n  required: [name]\n  properties:\n    name: string\n    type: enum(company, team, community, government, other)?\n    website: url?\n    members: ref(Person)[]?\n```\n\n### Work Management\n\n```yaml\nProject:\n  required: [name]\n  properties:\n    name: string\n    description: string?\n    status: enum(planning, active, paused, completed, archived)\n    owner: ref(Person)?\n    team: ref(Person)[]?\n    goals: ref(Goal)[]?\n    start_date: date?\n    end_date: date?\n    tags: string[]?\n\nTask:\n  required: [title, status]\n  properties:\n    title: string\n    description: string?\n    status: enum(open, in_progress, blocked, done, cancelled)\n    priority: enum(low, medium, high, urgent)?\n    assignee: ref(Person)?\n    project: ref(Project)?\n    due: datetime?\n    estimate_hours: number?\n    blockers: ref(Task)[]?\n    tags: string[]?\n\nGoal:\n  required: [description]\n  properties:\n    description: string\n    target_date: date?\n    status: enum(active, achieved, abandoned)?\n    metrics: object[]?\n    key_results: string[]?\n```\n\n### Time & Location\n\n```yaml\nEvent:\n  required: [title, start]\n  properties:\n    title: string\n    description: string?\n    start: datetime\n    end: datetime?\n    location: ref(Location)?\n    attendees: ref(Person)[]?\n    recurrence: object?  # iCal RRULE format\n    status: enum(confirmed, tentative, cancelled)?\n    reminders: object[]?\n\nLocation:\n  required: [name]\n  properties:\n    name: string\n    address: string?\n    city: string?\n    country: string?\n    coordinates: object?  # {lat, lng}\n    timezone: string?\n```\n\n### Information\n\n```yaml\nDocument:\n  required: [title]\n  properties:\n    title: string\n    path: string?  # Local file path\n    url: url?      # Remote URL\n    mime_type: string?\n    summary: string?\n    content_hash: string?\n    tags: string[]?\n\nMessage:\n  required: [content, sender]\n  properties:\n    content: string\n    sender: ref(Person)\n    recipients: ref(Person)[]\n    thread: ref(Thread)?\n    timestamp: datetime\n    platform: string?  # email, slack, whatsapp, etc.\n    external_id: string?\n\nThread:\n  required: [subject]\n  properties:\n    subject: string\n    participants: ref(Person)[]\n    messages: ref(Message)[]\n    status: enum(active, archived)?\n    last_activity: datetime?\n\nNote:\n  required: [content]\n  properties:\n    content: string\n    title: string?\n    tags: string[]?\n    refs: ref(Entity)[]?  # Links to any entity\n    created: datetime\n```\n\n### Resources\n\n```yaml\nAccount:\n  required: [service, username]\n  properties:\n    service: string  # github, gmail, aws, etc.\n    username: string\n    url: url?\n    credential_ref: ref(Credential)?\n\nDevice:\n  required: [name, type]\n  properties:\n    name: string\n    type: enum(computer, phone, tablet, server, iot, other)\n    os: string?\n    identifiers: object?  # {mac, serial, etc.}\n    owner: ref(Person)?\n\nCredential:\n  required: [service, secret_ref]\n  forbidden_properties: [password, secret, token, key, api_key]\n  properties:\n    service: string\n    secret_ref: string  # Reference to secret store (e.g., \"keychain:github-token\")\n    expires: datetime?\n    scope: string[]?\n```\n\n### Meta\n\n```yaml\nAction:\n  required: [type, target, timestamp]\n  properties:\n    type: string  # create, update, delete, send, etc.\n    target: ref(Entity)\n    timestamp: datetime\n    actor: ref(Person|Agent)?\n    outcome: enum(success, failure, pending)?\n    details: object?\n\nPolicy:\n  required: [scope, rule]\n  properties:\n    scope: string  # What this policy applies to\n    rule: string   # The constraint in natural language or code\n    enforcement: enum(block, warn, log)\n    enabled: boolean\n```\n\n## Relation Types\n\n### Ownership & Assignment\n\n```yaml\nowns:\n  from_types: [Person, Organization]\n  to_types: [Account, Device, Document, Project]\n  cardinality: one_to_many\n\nhas_owner:\n  from_types: [Project, Task, Document]\n  to_types: [Person]\n  cardinality: many_to_one\n\nassigned_to:\n  from_types: [Task]\n  to_types: [Person]\n  cardinality: many_to_one\n```\n\n### Hierarchy & Containment\n\n```yaml\nhas_task:\n  from_types: [Project]\n  to_types: [Task]\n  cardinality: one_to_many\n\nhas_goal:\n  from_types: [Project]\n  to_types: [Goal]\n  cardinality: one_to_many\n\nmember_of:\n  from_types: [Person]\n  to_types: [Organization]\n  cardinality: many_to_many\n\npart_of:\n  from_types: [Task, Document, Event]\n  to_types: [Project]\n  cardinality: many_to_one\n```\n\n### Dependencies\n\n```yaml\nblocks:\n  from_types: [Task]\n  to_types: [Task]\n  acyclic: true  # Prevents circular dependencies\n  cardinality: many_to_many\n\ndepends_on:\n  from_types: [Task, Project]\n  to_types: [Task, Project, Event]\n  acyclic: true\n  cardinality: many_to_many\n\nrequires:\n  from_types: [Action]\n  to_types: [Credential, Policy]\n  cardinality: many_to_many\n```\n\n### References\n\n```yaml\nmentions:\n  from_types: [Document, Message, Note]\n  to_types: [Person, Project, Task, Event]\n  cardinality: many_to_many\n\nreferences:\n  from_types: [Document, Note]\n  to_types: [Document, Note]\n  cardinality: many_to_many\n\nfollows_up:\n  from_types: [Task, Event]\n  to_types: [Event, Message]\n  cardinality: many_to_one\n```\n\n### Events\n\n```yaml\nattendee_of:\n  from_types: [Person]\n  to_types: [Event]\n  cardinality: many_to_many\n  properties:\n    status: enum(accepted, declined, tentative, pending)\n\nlocated_at:\n  from_types: [Event, Person, Device]\n  to_types: [Location]\n  cardinality: many_to_one\n```\n\n## Global Constraints\n\n```yaml\nconstraints:\n  # Credentials must never store secrets directly\n  - type: Credential\n    rule: \"forbidden_properties: [password, secret, token]\"\n    message: \"Credentials must use secret_ref to reference external secret storage\"\n\n  # Tasks must have valid status transitions\n  - type: Task\n    rule: \"status transitions: open -> in_progress -> (done|blocked) -> done\"\n    enforcement: warn\n\n  # Events must have end >= start\n  - type: Event\n    rule: \"if end exists: end >= start\"\n    message: \"Event end time must be after start time\"\n\n  # No orphan tasks (should belong to a project or have explicit owner)\n  - type: Task\n    rule: \"has_relation(part_of, Project) OR has_property(owner)\"\n    enforcement: warn\n    message: \"Task should belong to a project or have an explicit owner\"\n\n  # Circular dependency prevention\n  - relation: blocks\n    rule: \"acyclic\"\n    message: \"Circular task dependencies are not allowed\"\n```\n\nArchive v0.1.2: 5 files, 12363 bytes\n\nFiles: references/queries.md (5471b), references/schema.md (6650b), scripts/ontology.py (21596b), SKILL.md (6703b), _meta.json (127b)\n\nFile v0.1.2:SKILL.md\n\n---\nname: ontology\ndescription: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on \"remember\", \"what do I know about\", \"link X to Y\", \"show dependencies\", entity CRUD, or cross-skill data access.\n---\n\n# Ontology\n\nA typed vocabulary + constraint system for representing knowledge as a verifiable graph.\n\n## Core Concept\n\nEverything is an **entity** with a **type**, **properties**, and **relations** to other entities. Every mutation is validated against type constraints before committing.\n\n```\nEntity: { id, type, properties, relations, created, updated }\nRelation: { from_id, relation_type, to_id, properties }\n```\n\n## When to Use\n\n| Trigger | Action |\n|---------|--------|\n| \"Remember that...\" | Create/update entity |\n| \"What do I know about X?\" | Query graph |\n| \"Link X to Y\" | Create relation |\n| \"Show all tasks for project Z\" | Graph traversal |\n| \"What depends on X?\" | Dependency query |\n| Planning multi-step work | Model as graph transformations |\n| Skill needs shared state | Read/write ontology objects |\n\n## Core Types\n\n```yaml\n# Agents & People\nPerson: { name, email?, phone?, notes? }\nOrganization: { name, type?, members[] }\n\n# Work\nProject: { name, status, goals[], owner? }\nTask: { title, status, due?, priority?, assignee?, blockers[] }\nGoal: { description, target_date?, metrics[] }\n\n# Time & Place\nEvent: { title, start, end?, location?, attendees[], recurrence? }\nLocation: { name, address?, coordinates? }\n\n# Information\nDocument: { title, path?, url?, summary? }\nMessage: { content, sender, recipients[], thread? }\nThread: { subject, participants[], messages[] }\nNote: { content, tags[], refs[] }\n\n# Resources\nAccount: { service, username, credential_ref? }\nDevice: { name, type, identifiers[] }\nCredential: { service, secret_ref }  # Never store secrets directly\n\n# Meta\nAction: { type, target, timestamp, outcome? }\nPolicy: { scope, rule, enforcement }\n```\n\n## Storage\n\nDefault: `memory/ontology/graph.jsonl`\n\n```jsonl\n{\"op\":\"create\",\"entity\":{\"id\":\"p_001\",\"type\":\"Person\",\"properties\":{\"name\":\"Alice\"}}}\n{\"op\":\"create\",\"entity\":{\"id\":\"proj_001\",\"type\":\"Project\",\"properties\":{\"name\":\"Website Redesign\",\"status\":\"active\"}}}\n{\"op\":\"relate\",\"from\":\"proj_001\",\"rel\":\"has_owner\",\"to\":\"p_001\"}\n```\n\nQuery via scripts or direct file ops. For complex graphs, migrate to SQLite.\n\n### Append-Only Rule\n\nWhen working with existing ontology data or schema, **append/merge** changes instead of overwriting files. This preserves history and avoids clobbering prior definitions.\n\n## Workflows\n\n### Create Entity\n\n```bash\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'\n```\n\n### Query\n\n```bash\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\npython3 scripts/ontology.py get --id task_001\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n```\n\n### Link Entities\n\n```bash\npython3 scripts/ontology.py relate --from proj_001 --rel has_task --to task_001\n```\n\n### Validate\n\n```bash\npython3 scripts/ontology.py validate  # Check all constraints\n```\n\n## Constraints\n\nDefine in `memory/ontology/schema.yaml`:\n\n```yaml\ntypes:\n  Task:\n    required: [title, status]\n    status_enum: [open, in_progress, blocked, done]\n  \n  Event:\n    required: [title, start]\n    validate: \"end >= start if end exists\"\n\n  Credential:\n    required: [service, secret_ref]\n    forbidden_properties: [password, secret, token]  # Force indirection\n\nrelations:\n  has_owner:\n    from_types: [Project, Task]\n    to_types: [Person]\n    cardinality: many_to_one\n  \n  blocks:\n    from_types: [Task]\n    to_types: [Task]\n    acyclic: true  # No circular dependencies\n```\n\n## Skill Contract\n\nSkills that use ontology should declare:\n\n```yaml\n# In SKILL.md frontmatter or header\nontology:\n  reads: [Task, Project, Person]\n  writes: [Task, Action]\n  preconditions:\n    - \"Task.assignee must exist\"\n  postconditions:\n    - \"Created Task has status=open\"\n```\n\n## Planning as Graph Transformation\n\nModel multi-step plans as a sequence of graph operations:\n\n```\nPlan: \"Schedule team meeting and create follow-up tasks\"\n\n1. CREATE Event { title: \"Team Sync\", attendees: [p_001, p_002] }\n2. RELATE Event -> has_project -> proj_001\n3. CREATE Task { title: \"Prepare agenda\", assignee: p_001 }\n4. RELATE Task -> for_event -> event_001\n5. CREATE Task { title: \"Send summary\", assignee: p_001, blockers: [task_001] }\n```\n\nEach step is validated before execution. Rollback on constraint violation.\n\n## Integration Patterns\n\n### With Causal Inference\n\nLog ontology mutations as causal actions:\n\n```python\n# When creating/updating entities, also log to causal action log\naction = {\n    \"action\": \"create_entity\",\n    \"domain\": \"ontology\", \n    \"context\": {\"type\": \"Task\", \"project\": \"proj_001\"},\n    \"outcome\": \"created\"\n}\n```\n\n### Cross-Skill Communication\n\n```python\n# Email skill creates commitment\ncommitment = ontology.create(\"Commitment\", {\n    \"source_message\": msg_id,\n    \"description\": \"Send report by Friday\",\n    \"due\": \"2026-01-31\"\n})\n\n# Task skill picks it up\ntasks = ontology.query(\"Commitment\", {\"status\": \"pending\"})\nfor c in tasks:\n    ontology.create(\"Task\", {\n        \"title\": c.description,\n        \"due\": c.due,\n        \"source\": c.id\n    })\n```\n\n## Quick Start\n\n```bash\n# Initialize ontology storage\nmkdir -p memory/ontology\ntouch memory/ontology/graph.jsonl\n\n# Create schema (optional but recommended)\npython3 scripts/ontology.py schema-append --data '{\n  \"types\": {\n    \"Task\": { \"required\": [\"title\", \"status\"] },\n    \"Project\": { \"required\": [\"name\"] },\n    \"Person\": { \"required\": [\"name\"] }\n  }\n}'\n\n# Start using\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\"}'\npython3 scripts/ontology.py list --type Person\n```\n\n## References\n\n- `references/schema.md` — Full type definitions and constraint patterns\n- `references/queries.md` — Query language and traversal examples\n\n## Instruction Scope\n\nRuntime instructions operate on local files (`memory/ontology/graph.jsonl` and `memory/ontology/schema.yaml`) and provide CLI usage for create/query/relate/validate; this is within scope. The skill reads/writes workspace files and will create the `memory/ontology` directory when used. Validation includes property/enum/forbidden checks, relation type/cardinality validation, acyclicity for relations marked `acyclic: true`, and Event `end >= start` checks; other higher-level constraints may still be documentation-only unless implemented in code.\n\nFile v0.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn72dv4fm7ss7swbq47nnpad9x7zy2jh\",\n  \"slug\": \"ontology\",\n  \"version\": \"0.1.2\",\n  \"publishedAt\": 1770990793271\n}\n\nFile v0.1.2:references/queries.md\n\n# Query Reference\n\nQuery patterns and graph traversal examples.\n\n## Basic Queries\n\n### Get by ID\n\n```bash\npython3 scripts/ontology.py get --id task_001\n```\n\n### List by Type\n\n```bash\n# All tasks\npython3 scripts/ontology.py list --type Task\n\n# All people\npython3 scripts/ontology.py list --type Person\n```\n\n### Filter by Properties\n\n```bash\n# Open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n\n# High priority tasks\npython3 scripts/ontology.py query --type Task --where '{\"priority\":\"high\"}'\n\n# Tasks assigned to specific person (by property)\npython3 scripts/ontology.py query --type Task --where '{\"assignee\":\"p_001\"}'\n```\n\n## Relation Queries\n\n### Get Related Entities\n\n```bash\n# Tasks belonging to a project (outgoing)\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# What projects does this task belong to (incoming)\npython3 scripts/ontology.py related --id task_001 --rel part_of --dir incoming\n\n# All relations for an entity (both directions)\npython3 scripts/ontology.py related --id p_001 --dir both\n```\n\n### Common Patterns\n\n```bash\n# Who owns this project?\npython3 scripts/ontology.py related --id proj_001 --rel has_owner\n\n# What events is this person attending?\npython3 scripts/ontology.py related --id p_001 --rel attendee_of --dir outgoing\n\n# What's blocking this task?\npython3 scripts/ontology.py related --id task_001 --rel blocked_by --dir incoming\n```\n\n## Programmatic Queries\n\n### Python API\n\n```python\nfrom scripts.ontology import load_graph, query_entities, get_related\n\n# Load the graph\nentities, relations = load_graph(\"memory/ontology/graph.jsonl\")\n\n# Query entities\nopen_tasks = query_entities(\"Task\", {\"status\": \"open\"}, \"memory/ontology/graph.jsonl\")\n\n# Get related\nproject_tasks = get_related(\"proj_001\", \"has_task\", \"memory/ontology/graph.jsonl\")\n```\n\n### Complex Queries\n\n```python\n# Find all tasks blocked by incomplete dependencies\ndef find_blocked_tasks(graph_path):\n    entities, relations = load_graph(graph_path)\n    blocked = []\n    \n    for entity in entities.values():\n        if entity[\"type\"] != \"Task\":\n            continue\n        if entity[\"properties\"].get(\"status\") == \"blocked\":\n            # Find what's blocking it\n            blockers = get_related(entity[\"id\"], \"blocked_by\", graph_path, \"incoming\")\n            incomplete_blockers = [\n                b for b in blockers \n                if b[\"entity\"][\"properties\"].get(\"status\") != \"done\"\n            ]\n            if incomplete_blockers:\n                blocked.append({\n                    \"task\": entity,\n                    \"blockers\": incomplete_blockers\n                })\n    \n    return blocked\n```\n\n### Path Queries\n\n```python\n# Find path between two entities\ndef find_path(from_id, to_id, graph_path, max_depth=5):\n    entities, relations = load_graph(graph_path)\n    \n    visited = set()\n    queue = [(from_id, [])]\n    \n    while queue:\n        current, path = queue.pop(0)\n        \n        if current == to_id:\n            return path\n        \n        if current in visited or len(path) >= max_depth:\n            continue\n        \n        visited.add(current)\n        \n        for rel in relations:\n            if rel[\"from\"] == current and rel[\"to\"] not in visited:\n                queue.append((rel[\"to\"], path + [rel]))\n            if rel[\"to\"] == current and rel[\"from\"] not in visited:\n                queue.append((rel[\"from\"], path + [{**rel, \"direction\": \"incoming\"}]))\n    \n    return None  # No path found\n```\n\n## Query Patterns by Use Case\n\n### Task Management\n\n```bash\n# All my open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\",\"assignee\":\"p_me\"}'\n\n# Overdue tasks (requires custom script for date comparison)\n# See references/schema.md for date handling\n\n# Tasks with no blockers\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n# Then filter in code for those with no incoming \"blocks\" relations\n```\n\n### Project Overview\n\n```bash\n# All tasks in project\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# Project team members\npython3 scripts/ontology.py related --id proj_001 --rel has_member\n\n# Project goals\npython3 scripts/ontology.py related --id proj_001 --rel has_goal\n```\n\n### People & Contacts\n\n```bash\n# All people\npython3 scripts/ontology.py list --type Person\n\n# People in an organization\npython3 scripts/ontology.py related --id org_001 --rel has_member\n\n# What's assigned to this person\npython3 scripts/ontology.py related --id p_001 --rel assigned_to --dir incoming\n```\n\n### Events & Calendar\n\n```bash\n# All events\npython3 scripts/ontology.py list --type Event\n\n# Events at a location\npython3 scripts/ontology.py related --id loc_001 --rel located_at --dir incoming\n\n# Event attendees\npython3 scripts/ontology.py related --id event_001 --rel attendee_of --dir incoming\n```\n\n## Aggregations\n\nFor complex aggregations, use Python:\n\n```python\nfrom collections import Counter\n\ndef task_status_summary(project_id, graph_path):\n    \"\"\"Count tasks by status for a project.\"\"\"\n    tasks = get_related(project_id, \"has_task\", graph_path)\n    statuses = Counter(t[\"entity\"][\"properties\"].get(\"status\", \"unknown\") for t in tasks)\n    return dict(statuses)\n\ndef workload_by_person(graph_path):\n    \"\"\"Count open tasks per person.\"\"\"\n    open_tasks = query_entities(\"Task\", {\"status\": \"open\"}, graph_path)\n    workload = Counter(t[\"properties\"].get(\"assignee\") for t in open_tasks)\n    return dict(workload)\n```\n\nFile v0.1.2:references/schema.md\n\n# Ontology Schema Reference\n\nFull type definitions and constraint patterns for the ontology graph.\n\n## Core Types\n\n### Agents & People\n\n```yaml\nPerson:\n  required: [name]\n  properties:\n    name: string\n    email: string?\n    phone: string?\n    organization: ref(Organization)?\n    notes: string?\n    tags: string[]?\n\nOrganization:\n  required: [name]\n  properties:\n    name: string\n    type: enum(company, team, community, government, other)?\n    website: url?\n    members: ref(Person)[]?\n```\n\n### Work Management\n\n```yaml\nProject:\n  required: [name]\n  properties:\n    name: string\n    description: string?\n    status: enum(planning, active, paused, completed, archived)\n    owner: ref(Person)?\n    team: ref(Person)[]?\n    goals: ref(Goal)[]?\n    start_date: date?\n    end_date: date?\n    tags: string[]?\n\nTask:\n  required: [title, status]\n  properties:\n    title: string\n    description: string?\n    status: enum(open, in_progress, blocked, done, cancelled)\n    priority: enum(low, medium, high, urgent)?\n    assignee: ref(Person)?\n    project: ref(Project)?\n    due: datetime?\n    estimate_hours: number?\n    blockers: ref(Task)[]?\n    tags: string[]?\n\nGoal:\n  required: [description]\n  properties:\n    description: string\n    target_date: date?\n    status: enum(active, achieved, abandoned)?\n    metrics: object[]?\n    key_results: string[]?\n```\n\n### Time & Location\n\n```yaml\nEvent:\n  required: [title, start]\n  properties:\n    title: string\n    description: string?\n    start: datetime\n    end: datetime?\n    location: ref(Location)?\n    attendees: ref(Person)[]?\n    recurrence: object?  # iCal RRULE format\n    status: enum(confirmed, tentative, cancelled)?\n    reminders: object[]?\n\nLocation:\n  required: [name]\n  properties:\n    name: string\n    address: string?\n    city: string?\n    country: string?\n    coordinates: object?  # {lat, lng}\n    timezone: string?\n```\n\n### Information\n\n```yaml\nDocument:\n  required: [title]\n  properties:\n    title: string\n    path: string?  # Local file path\n    url: url?      # Remote URL\n    mime_type: string?\n    summary: string?\n    content_hash: string?\n    tags: string[]?\n\nMessage:\n  required: [content, sender]\n  properties:\n    content: string\n    sender: ref(Person)\n    recipients: ref(Person)[]\n    thread: ref(Thread)?\n    timestamp: datetime\n    platform: string?  # email, slack, whatsapp, etc.\n    external_id: string?\n\nThread:\n  required: [subject]\n  properties:\n    subject: string\n    participants: ref(Person)[]\n    messages: ref(Message)[]\n    status: enum(active, archived)?\n    last_activity: datetime?\n\nNote:\n  required: [content]\n  properties:\n    content: string\n    title: string?\n    tags: string[]?\n    refs: ref(Entity)[]?  # Links to any entity\n    created: datetime\n```\n\n### Resources\n\n```yaml\nAccount:\n  required: [service, username]\n  properties:\n    service: string  # github, gmail, aws, etc.\n    username: string\n    url: url?\n    credential_ref: ref(Credential)?\n\nDevice:\n  required: [name, type]\n  properties:\n    name: string\n    type: enum(computer, phone, tablet, server, iot, other)\n    os: string?\n    identifiers: object?  # {mac, serial, etc.}\n    owner: ref(Person)?\n\nCredential:\n  required: [service, secret_ref]\n  forbidden_properties: [password, secret, token, key, api_key]\n  properties:\n    service: string\n    secret_ref: string  # Reference to secret store (e.g., \"keychain:github-token\")\n    expires: datetime?\n    scope: string[]?\n```\n\n### Meta\n\n```yaml\nAction:\n  required: [type, target, timestamp]\n  properties:\n    type: string  # create, update, delete, send, etc.\n    target: ref(Entity)\n    timestamp: datetime\n    actor: ref(Person|Agent)?\n    outcome: enum(success, failure, pending)?\n    details: object?\n\nPolicy:\n  required: [scope, rule]\n  properties:\n    scope: string  # What this policy applies to\n    rule: string   # The constraint in natural language or code\n    enforcement: enum(block, warn, log)\n    enabled: boolean\n```\n\n## Relation Types\n\n### Ownership & Assignment\n\n```yaml\nowns:\n  from_types: [Person, Organization]\n  to_types: [Account, Device, Document, Project]\n  cardinality: one_to_many\n\nhas_owner:\n  from_types: [Project, Task, Document]\n  to_types: [Person]\n  cardinality: many_to_one\n\nassigned_to:\n  from_types: [Task]\n  to_types: [Person]\n  cardinality: many_to_one\n```\n\n### Hierarchy & Containment\n\n```yaml\nhas_task:\n  from_types: [Project]\n  to_types: [Task]\n  cardinality: one_to_many\n\nhas_goal:\n  from_types: [Project]\n  to_types: [Goal]\n  cardinality: one_to_many\n\nmember_of:\n  from_types: [Person]\n  to_types: [Organization]\n  cardinality: many_to_many\n\npart_of:\n  from_types: [Task, Document, Event]\n  to_types: [Project]\n  cardinality: many_to_one\n```\n\n### Dependencies\n\n```yaml\nblocks:\n  from_types: [Task]\n  to_types: [Task]\n  acyclic: true  # Prevents circular dependencies\n  cardinality: many_to_many\n\ndepends_on:\n  from_types: [Task, Project]\n  to_types: [Task, Project, Event]\n  acyclic: true\n  cardinality: many_to_many\n\nrequires:\n  from_types: [Action]\n  to_types: [Credential, Policy]\n  cardinality: many_to_many\n```\n\n### References\n\n```yaml\nmentions:\n  from_types: [Document, Message, Note]\n  to_types: [Person, Project, Task, Event]\n  cardinality: many_to_many\n\nreferences:\n  from_types: [Document, Note]\n  to_types: [Document, Note]\n  cardinality: many_to_many\n\nfollows_up:\n  from_types: [Task, Event]\n  to_types: [Event, Message]\n  cardinality: many_to_one\n```\n\n### Events\n\n```yaml\nattendee_of:\n  from_types: [Person]\n  to_types: [Event]\n  cardinality: many_to_many\n  properties:\n    status: enum(accepted, declined, tentative, pending)\n\nlocated_at:\n  from_types: [Event, Person, Device]\n  to_types: [Location]\n  cardinality: many_to_one\n```\n\n## Global Constraints\n\n```yaml\nconstraints:\n  # Credentials must never store secrets directly\n  - type: Credential\n    rule: \"forbidden_properties: [password, secret, token]\"\n    message: \"Credentials must use secret_ref to reference external secret storage\"\n\n  # Tasks must have valid status transitions\n  - type: Task\n    rule: \"status transitions: open -> in_progress -> (done|blocked) -> done\"\n    enforcement: warn\n\n  # Events must have end >= start\n  - type: Event\n    rule: \"if end exists: end >= start\"\n    message: \"Event end time must be after start time\"\n\n  # No orphan tasks (should belong to a project or have explicit owner)\n  - type: Task\n    rule: \"has_relation(part_of, Project) OR has_property(owner)\"\n    enforcement: warn\n    message: \"Task should belong to a project or have an explicit owner\"\n\n  # Circular dependency prevention\n  - relation: blocks\n    rule: \"acyclic\"\n    message: \"Circular task dependencies are not allowed\"\n```\n\nArchive v0.1.1: 5 files, 11919 bytes\n\nFiles: references/queries.md (5471b), references/schema.md (6650b), scripts/ontology.py (20192b), SKILL.md (6703b), _meta.json (127b)\n\nFile v0.1.1:SKILL.md\n\n---\nname: ontology\ndescription: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on \"remember\", \"what do I know about\", \"link X to Y\", \"show dependencies\", entity CRUD, or cross-skill data access.\n---\n\n# Ontology\n\nA typed vocabulary + constraint system for representing knowledge as a verifiable graph.\n\n## Core Concept\n\nEverything is an **entity** with a **type**, **properties**, and **relations** to other entities. Every mutation is validated against type constraints before committing.\n\n```\nEntity: { id, type, properties, relations, created, updated }\nRelation: { from_id, relation_type, to_id, properties }\n```\n\n## When to Use\n\n| Trigger | Action |\n|---------|--------|\n| \"Remember that...\" | Create/update entity |\n| \"What do I know about X?\" | Query graph |\n| \"Link X to Y\" | Create relation |\n| \"Show all tasks for project Z\" | Graph traversal |\n| \"What depends on X?\" | Dependency query |\n| Planning multi-step work | Model as graph transformations |\n| Skill needs shared state | Read/write ontology objects |\n\n## Core Types\n\n```yaml\n# Agents & People\nPerson: { name, email?, phone?, notes? }\nOrganization: { name, type?, members[] }\n\n# Work\nProject: { name, status, goals[], owner? }\nTask: { title, status, due?, priority?, assignee?, blockers[] }\nGoal: { description, target_date?, metrics[] }\n\n# Time & Place\nEvent: { title, start, end?, location?, attendees[], recurrence? }\nLocation: { name, address?, coordinates? }\n\n# Information\nDocument: { title, path?, url?, summary? }\nMessage: { content, sender, recipients[], thread? }\nThread: { subject, participants[], messages[] }\nNote: { content, tags[], refs[] }\n\n# Resources\nAccount: { service, username, credential_ref? }\nDevice: { name, type, identifiers[] }\nCredential: { service, secret_ref }  # Never store secrets directly\n\n# Meta\nAction: { type, target, timestamp, outcome? }\nPolicy: { scope, rule, enforcement }\n```\n\n## Storage\n\nDefault: `memory/ontology/graph.jsonl`\n\n```jsonl\n{\"op\":\"create\",\"entity\":{\"id\":\"p_001\",\"type\":\"Person\",\"properties\":{\"name\":\"Alice\"}}}\n{\"op\":\"create\",\"entity\":{\"id\":\"proj_001\",\"type\":\"Project\",\"properties\":{\"name\":\"Website Redesign\",\"status\":\"active\"}}}\n{\"op\":\"relate\",\"from\":\"proj_001\",\"rel\":\"has_owner\",\"to\":\"p_001\"}\n```\n\nQuery via scripts or direct file ops. For complex graphs, migrate to SQLite.\n\n### Append-Only Rule\n\nWhen working with existing ontology data or schema, **append/merge** changes instead of overwriting files. This preserves history and avoids clobbering prior definitions.\n\n## Workflows\n\n### Create Entity\n\n```bash\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'\n```\n\n### Query\n\n```bash\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\npython3 scripts/ontology.py get --id task_001\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n```\n\n### Link Entities\n\n```bash\npython3 scripts/ontology.py relate --from proj_001 --rel has_task --to task_001\n```\n\n### Validate\n\n```bash\npython3 scripts/ontology.py validate  # Check all constraints\n```\n\n## Constraints\n\nDefine in `memory/ontology/schema.yaml`:\n\n```yaml\ntypes:\n  Task:\n    required: [title, status]\n    status_enum: [open, in_progress, blocked, done]\n  \n  Event:\n    required: [title, start]\n    validate: \"end >= start if end exists\"\n\n  Credential:\n    required: [service, secret_ref]\n    forbidden_properties: [password, secret, token]  # Force indirection\n\nrelations:\n  has_owner:\n    from_types: [Project, Task]\n    to_types: [Person]\n    cardinality: many_to_one\n  \n  blocks:\n    from_types: [Task]\n    to_types: [Task]\n    acyclic: true  # No circular dependencies\n```\n\n## Skill Contract\n\nSkills that use ontology should declare:\n\n```yaml\n# In SKILL.md frontmatter or header\nontology:\n  reads: [Task, Project, Person]\n  writes: [Task, Action]\n  preconditions:\n    - \"Task.assignee must exist\"\n  postconditions:\n    - \"Created Task has status=open\"\n```\n\n## Planning as Graph Transformation\n\nModel multi-step plans as a sequence of graph operations:\n\n```\nPlan: \"Schedule team meeting and create follow-up tasks\"\n\n1. CREATE Event { title: \"Team Sync\", attendees: [p_001, p_002] }\n2. RELATE Event -> has_project -> proj_001\n3. CREATE Task { title: \"Prepare agenda\", assignee: p_001 }\n4. RELATE Task -> for_event -> event_001\n5. CREATE Task { title: \"Send summary\", assignee: p_001, blockers: [task_001] }\n```\n\nEach step is validated before execution. Rollback on constraint violation.\n\n## Integration Patterns\n\n### With Causal Inference\n\nLog ontology mutations as causal actions:\n\n```python\n# When creating/updating entities, also log to causal action log\naction = {\n    \"action\": \"create_entity\",\n    \"domain\": \"ontology\", \n    \"context\": {\"type\": \"Task\", \"project\": \"proj_001\"},\n    \"outcome\": \"created\"\n}\n```\n\n### Cross-Skill Communication\n\n```python\n# Email skill creates commitment\ncommitment = ontology.create(\"Commitment\", {\n    \"source_message\": msg_id,\n    \"description\": \"Send report by Friday\",\n    \"due\": \"2026-01-31\"\n})\n\n# Task skill picks it up\ntasks = ontology.query(\"Commitment\", {\"status\": \"pending\"})\nfor c in tasks:\n    ontology.create(\"Task\", {\n        \"title\": c.description,\n        \"due\": c.due,\n        \"source\": c.id\n    })\n```\n\n## Quick Start\n\n```bash\n# Initialize ontology storage\nmkdir -p memory/ontology\ntouch memory/ontology/graph.jsonl\n\n# Create schema (optional but recommended)\npython3 scripts/ontology.py schema-append --data '{\n  \"types\": {\n    \"Task\": { \"required\": [\"title\", \"status\"] },\n    \"Project\": { \"required\": [\"name\"] },\n    \"Person\": { \"required\": [\"name\"] }\n  }\n}'\n\n# Start using\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\"}'\npython3 scripts/ontology.py list --type Person\n```\n\n## References\n\n- `references/schema.md` — Full type definitions and constraint patterns\n- `references/queries.md` — Query language and traversal examples\n\n## Instruction Scope\n\nRuntime instructions operate on local files (`memory/ontology/graph.jsonl` and `memory/ontology/schema.yaml`) and provide CLI usage for create/query/relate/validate; this is within scope. The skill reads/writes workspace files and will create the `memory/ontology` directory when used. Validation includes property/enum/forbidden checks, relation type/cardinality validation, acyclicity for relations marked `acyclic: true`, and Event `end >= start` checks; other higher-level constraints may still be documentation-only unless implemented in code.\n\nFile v0.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn72dv4fm7ss7swbq47nnpad9x7zy2jh\",\n  \"slug\": \"ontology\",\n  \"version\": \"0.1.1\",\n  \"publishedAt\": 1770912052938\n}\n\nFile v0.1.1:references/queries.md\n\n# Query Reference\n\nQuery patterns and graph traversal examples.\n\n## Basic Queries\n\n### Get by ID\n\n```bash\npython3 scripts/ontology.py get --id task_001\n```\n\n### List by Type\n\n```bash\n# All tasks\npython3 scripts/ontology.py list --type Task\n\n# All people\npython3 scripts/ontology.py list --type Person\n```\n\n### Filter by Properties\n\n```bash\n# Open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n\n# High priority tasks\npython3 scripts/ontology.py query --type Task --where '{\"priority\":\"high\"}'\n\n# Tasks assigned to specific person (by property)\npython3 scripts/ontology.py query --type Task --where '{\"assignee\":\"p_001\"}'\n```\n\n## Relation Queries\n\n### Get Related Entities\n\n```bash\n# Tasks belonging to a project (outgoing)\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# What projects does this task belong to (incoming)\npython3 scripts/ontology.py related --id task_001 --rel part_of --dir incoming\n\n# All relations for an entity (both directions)\npython3 scripts/ontology.py related --id p_001 --dir both\n```\n\n### Common Patterns\n\n```bash\n# Who owns this project?\npython3 scripts/ontology.py related --id proj_001 --rel has_owner\n\n# What events is this person attending?\npython3 scripts/ontology.py related --id p_001 --rel attendee_of --dir outgoing\n\n# What's blocking this task?\npython3 scripts/ontology.py related --id task_001 --rel blocked_by --dir incoming\n```\n\n## Programmatic Queries\n\n### Python API\n\n```python\nfrom scripts.ontology import load_graph, query_entities, get_related\n\n# Load the graph\nentities, relations = load_graph(\"memory/ontology/graph.jsonl\")\n\n# Query entities\nopen_tasks = query_entities(\"Task\", {\"status\": \"open\"}, \"memory/ontology/graph.jsonl\")\n\n# Get related\nproject_tasks = get_related(\"proj_001\", \"has_task\", \"memory/ontology/graph.jsonl\")\n```\n\n### Complex Queries\n\n```python\n# Find all tasks blocked by incomplete dependencies\ndef find_blocked_tasks(graph_path):\n    entities, relations = load_graph(graph_path)\n    blocked = []\n    \n    for entity in entities.values():\n        if entity[\"type\"] != \"Task\":\n            continue\n        if entity[\"properties\"].get(\"status\") == \"blocked\":\n            # Find what's blocking it\n            blockers = get_related(entity[\"id\"], \"blocked_by\", graph_path, \"incoming\")\n            incomplete_blockers = [\n                b for b in blockers \n                if b[\"entity\"][\"properties\"].get(\"status\") != \"done\"\n            ]\n            if incomplete_blockers:\n                blocked.append({\n                    \"task\": entity,\n                    \"blockers\": incomplete_blockers\n                })\n    \n    return blocked\n```\n\n### Path Queries\n\n```python\n# Find path between two entities\ndef find_path(from_id, to_id, graph_path, max_depth=5):\n    entities, relations = load_graph(graph_path)\n    \n    visited = set()\n    queue = [(from_id, [])]\n    \n    while queue:\n        current, path = queue.pop(0)\n        \n        if current == to_id:\n            return path\n        \n        if current in visited or len(path) >= max_depth:\n            continue\n        \n        visited.add(current)\n        \n        for rel in relations:\n            if rel[\"from\"] == current and rel[\"to\"] not in visited:\n                queue.append((rel[\"to\"], path + [rel]))\n            if rel[\"to\"] == current and rel[\"from\"] not in visited:\n                queue.append((rel[\"from\"], path + [{**rel, \"direction\": \"incoming\"}]))\n    \n    return None  # No path found\n```\n\n## Query Patterns by Use Case\n\n### Task Management\n\n```bash\n# All my open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\",\"assignee\":\"p_me\"}'\n\n# Overdue tasks (requires custom script for date comparison)\n# See references/schema.md for date handling\n\n# Tasks with no blockers\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n# Then filter in code for those with no incoming \"blocks\" relations\n```\n\n### Project Overview\n\n```bash\n# All tasks in project\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# Project team members\npython3 scripts/ontology.py related --id proj_001 --rel has_member\n\n# Project goals\npython3 scripts/ontology.py related --id proj_001 --rel has_goal\n```\n\n### People & Contacts\n\n```bash\n# All people\npython3 scripts/ontology.py list --type Person\n\n# People in an organization\npython3 scripts/ontology.py related --id org_001 --rel has_member\n\n# What's assigned to this person\npython3 scripts/ontology.py related --id p_001 --rel assigned_to --dir incoming\n```\n\n### Events & Calendar\n\n```bash\n# All events\npython3 scripts/ontology.py list --type Event\n\n# Events at a location\npython3 scripts/ontology.py related --id loc_001 --rel located_at --dir incoming\n\n# Event attendees\npython3 scripts/ontology.py related --id event_001 --rel attendee_of --dir incoming\n```\n\n## Aggregations\n\nFor complex aggregations, use Python:\n\n```python\nfrom collections import Counter\n\ndef task_status_summary(project_id, graph_path):\n    \"\"\"Count tasks by status for a project.\"\"\"\n    tasks = get_related(project_id, \"has_task\", graph_path)\n    statuses = Counter(t[\"entity\"][\"properties\"].get(\"status\", \"unknown\") for t in tasks)\n    return dict(statuses)\n\ndef workload_by_person(graph_path):\n    \"\"\"Count open tasks per person.\"\"\"\n    open_tasks = query_entities(\"Task\", {\"status\": \"open\"}, graph_path)\n    workload = Counter(t[\"properties\"].get(\"assignee\") for t in open_tasks)\n    return dict(workload)\n```\n\nFile v0.1.1:references/schema.md\n\n# Ontology Schema Reference\n\nFull type definitions and constraint patterns for the ontology graph.\n\n## Core Types\n\n### Agents & People\n\n```yaml\nPerson:\n  required: [name]\n  properties:\n    name: string\n    email: string?\n    phone: string?\n    organization: ref(Organization)?\n    notes: string?\n    tags: string[]?\n\nOrganization:\n  required: [name]\n  properties:\n    name: string\n    type: enum(company, team, community, government, other)?\n    website: url?\n    members: ref(Person)[]?\n```\n\n### Work Management\n\n```yaml\nProject:\n  required: [name]\n  properties:\n    name: string\n    description: string?\n    status: enum(planning, active, paused, completed, archived)\n    owner: ref(Person)?\n    team: ref(Person)[]?\n    goals: ref(Goal)[]?\n    start_date: date?\n    end_date: date?\n    tags: string[]?\n\nTask:\n  required: [title, status]\n  properties:\n    title: string\n    description: string?\n    status: enum(open, in_progress, blocked, done, cancelled)\n    priority: enum(low, medium, high, urgent)?\n    assignee: ref(Person)?\n    project: ref(Project)?\n    due: datetime?\n    estimate_hours: number?\n    blockers: ref(Task)[]?\n    tags: string[]?\n\nGoal:\n  required: [description]\n  properties:\n    description: string\n    target_date: date?\n    status: enum(active, achieved, abandoned)?\n    metrics: object[]?\n    key_results: string[]?\n```\n\n### Time & Location\n\n```yaml\nEvent:\n  required: [title, start]\n  properties:\n    title: string\n    description: string?\n    start: datetime\n    end: datetime?\n    location: ref(Location)?\n    attendees: ref(Person)[]?\n    recurrence: object?  # iCal RRULE format\n    status: enum(confirmed, tentative, cancelled)?\n    reminders: object[]?\n\nLocation:\n  required: [name]\n  properties:\n    name: string\n    address: string?\n    city: string?\n    country: string?\n    coordinates: object?  # {lat, lng}\n    timezone: string?\n```\n\n### Information\n\n```yaml\nDocument:\n  required: [title]\n  properties:\n    title: string\n    path: string?  # Local file path\n    url: url?      # Remote URL\n    mime_type: string?\n    summary: string?\n    content_hash: string?\n    tags: string[]?\n\nMessage:\n  required: [content, sender]\n  properties:\n    content: string\n    sender: ref(Person)\n    recipients: ref(Person)[]\n    thread: ref(Thread)?\n    timestamp: datetime\n    platform: string?  # email, slack, whatsapp, etc.\n    external_id: string?\n\nThread:\n  required: [subject]\n  properties:\n    subject: string\n    participants: ref(Person)[]\n    messages: ref(Message)[]\n    status: enum(active, archived)?\n    last_activity: datetime?\n\nNote:\n  required: [content]\n  properties:\n    content: string\n    title: string?\n    tags: string[]?\n    refs: ref(Entity)[]?  # Links to any entity\n    created: datetime\n```\n\n### Resources\n\n```yaml\nAccount:\n  required: [service, username]\n  properties:\n    service: string  # github, gmail, aws, etc.\n    username: string\n    url: url?\n    credential_ref: ref(Credential)?\n\nDevice:\n  required: [name, type]\n  properties:\n    name: string\n    type: enum(computer, phone, tablet, server, iot, other)\n    os: string?\n    identifiers: object?  # {mac, serial, etc.}\n    owner: ref(Person)?\n\nCredential:\n  required: [service, secret_ref]\n  forbidden_properties: [password, secret, token, key, api_key]\n  properties:\n    service: string\n    secret_ref: string  # Reference to secret store (e.g., \"keychain:github-token\")\n    expires: datetime?\n    scope: string[]?\n```\n\n### Meta\n\n```yaml\nAction:\n  required: [type, target, timestamp]\n  properties:\n    type: string  # create, update, delete, send, etc.\n    target: ref(Entity)\n    timestamp: datetime\n    actor: ref(Person|Agent)?\n    outcome: enum(success, failure, pending)?\n    details: object?\n\nPolicy:\n  required: [scope, rule]\n  properties:\n    scope: string  # What this policy applies to\n    rule: string   # The constraint in natural language or code\n    enforcement: enum(block, warn, log)\n    enabled: boolean\n```\n\n## Relation Types\n\n### Ownership & Assignment\n\n```yaml\nowns:\n  from_types: [Person, Organization]\n  to_types: [Account, Device, Document, Project]\n  cardinality: one_to_many\n\nhas_owner:\n  from_types: [Project, Task, Document]\n  to_types: [Person]\n  cardinality: many_to_one\n\nassigned_to:\n  from_types: [Task]\n  to_types: [Person]\n  cardinality: many_to_one\n```\n\n### Hierarchy & Containment\n\n```yaml\nhas_task:\n  from_types: [Project]\n  to_types: [Task]\n  cardinality: one_to_many\n\nhas_goal:\n  from_types: [Project]\n  to_types: [Goal]\n  cardinality: one_to_many\n\nmember_of:\n  from_types: [Person]\n  to_types: [Organization]\n  cardinality: many_to_many\n\npart_of:\n  from_types: [Task, Document, Event]\n  to_types: [Project]\n  cardinality: many_to_one\n```\n\n### Dependencies\n\n```yaml\nblocks:\n  from_types: [Task]\n  to_types: [Task]\n  acyclic: true  # Prevents circular dependencies\n  cardinality: many_to_many\n\ndepends_on:\n  from_types: [Task, Project]\n  to_types: [Task, Project, Event]\n  acyclic: true\n  cardinality: many_to_many\n\nrequires:\n  from_types: [Action]\n  to_types: [Credential, Policy]\n  cardinality: many_to_many\n```\n\n### References\n\n```yaml\nmentions:\n  from_types: [Document, Message, Note]\n  to_types: [Person, Project, Task, Event]\n  cardinality: many_to_many\n\nreferences:\n  from_types: [Document, Note]\n  to_types: [Document, Note]\n  cardinality: many_to_many\n\nfollows_up:\n  from_types: [Task, Event]\n  to_types: [Event, Message]\n  cardinality: many_to_one\n```\n\n### Events\n\n```yaml\nattendee_of:\n  from_types: [Person]\n  to_types: [Event]\n  cardinality: many_to_many\n  properties:\n    status: enum(accepted, declined, tentative, pending)\n\nlocated_at:\n  from_types: [Event, Person, Device]\n  to_types: [Location]\n  cardinality: many_to_one\n```\n\n## Global Constraints\n\n```yaml\nconstraints:\n  # Credentials must never store secrets directly\n  - type: Credential\n    rule: \"forbidden_properties: [password, secret, token]\"\n    message: \"Credentials must use secret_ref to reference external secret storage\"\n\n  # Tasks must have valid status transitions\n  - type: Task\n    rule: \"status transitions: open -> in_progress -> (done|blocked) -> done\"\n    enforcement: warn\n\n  # Events must have end >= start\n  - type: Event\n    rule: \"if end exists: end >= start\"\n    message: \"Event end time must be after start time\"\n\n  # No orphan tasks (should belong to a project or have explicit owner)\n  - type: Task\n    rule: \"has_relation(part_of, Project) OR has_property(owner)\"\n    enforcement: warn\n    message: \"Task should belong to a project or have an explicit owner\"\n\n  # Circular dependency prevention\n  - relation: blocks\n    rule: \"acyclic\"\n    message: \"Circular task dependencies are not allowed\"\n```\n\nArchive v0.1.0: 5 files, 10053 bytes\n\nFiles: references/queries.md (5471b), references/schema.md (6650b), scripts/ontology.py (13547b), SKILL.md (5891b), _meta.json (127b)\n\nFile v0.1.0:SKILL.md\n\n---\nname: ontology\ndescription: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on \"remember\", \"what do I know about\", \"link X to Y\", \"show dependencies\", entity CRUD, or cross-skill data access.\n---\n\n# Ontology\n\nA typed vocabulary + constraint system for representing knowledge as a verifiable graph.\n\n## Core Concept\n\nEverything is an **entity** with a **type**, **properties**, and **relations** to other entities. Every mutation is validated against type constraints before committing.\n\n```\nEntity: { id, type, properties, relations, created, updated }\nRelation: { from_id, relation_type, to_id, properties }\n```\n\n## When to Use\n\n| Trigger | Action |\n|---------|--------|\n| \"Remember that...\" | Create/update entity |\n| \"What do I know about X?\" | Query graph |\n| \"Link X to Y\" | Create relation |\n| \"Show all tasks for project Z\" | Graph traversal |\n| \"What depends on X?\" | Dependency query |\n| Planning multi-step work | Model as graph transformations |\n| Skill needs shared state | Read/write ontology objects |\n\n## Core Types\n\n```yaml\n# Agents & People\nPerson: { name, email?, phone?, notes? }\nOrganization: { name, type?, members[] }\n\n# Work\nProject: { name, status, goals[], owner? }\nTask: { title, status, due?, priority?, assignee?, blockers[] }\nGoal: { description, target_date?, metrics[] }\n\n# Time & Place\nEvent: { title, start, end?, location?, attendees[], recurrence? }\nLocation: { name, address?, coordinates? }\n\n# Information\nDocument: { title, path?, url?, summary? }\nMessage: { content, sender, recipients[], thread? }\nThread: { subject, participants[], messages[] }\nNote: { content, tags[], refs[] }\n\n# Resources\nAccount: { service, username, credential_ref? }\nDevice: { name, type, identifiers[] }\nCredential: { service, secret_ref }  # Never store secrets directly\n\n# Meta\nAction: { type, target, timestamp, outcome? }\nPolicy: { scope, rule, enforcement }\n```\n\n## Storage\n\nDefault: `memory/ontology/graph.jsonl`\n\n```jsonl\n{\"op\":\"create\",\"entity\":{\"id\":\"p_001\",\"type\":\"Person\",\"properties\":{\"name\":\"Alice\"}}}\n{\"op\":\"create\",\"entity\":{\"id\":\"proj_001\",\"type\":\"Project\",\"properties\":{\"name\":\"Website Redesign\",\"status\":\"active\"}}}\n{\"op\":\"relate\",\"from\":\"proj_001\",\"rel\":\"has_owner\",\"to\":\"p_001\"}\n```\n\nQuery via scripts or direct file ops. For complex graphs, migrate to SQLite.\n\n## Workflows\n\n### Create Entity\n\n```bash\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'\n```\n\n### Query\n\n```bash\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\npython3 scripts/ontology.py get --id task_001\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n```\n\n### Link Entities\n\n```bash\npython3 scripts/ontology.py relate --from proj_001 --rel has_task --to task_001\n```\n\n### Validate\n\n```bash\npython3 scripts/ontology.py validate  # Check all constraints\n```\n\n## Constraints\n\nDefine in `memory/ontology/schema.yaml`:\n\n```yaml\ntypes:\n  Task:\n    required: [title, status]\n    status_enum: [open, in_progress, blocked, done]\n  \n  Event:\n    required: [title, start]\n    validate: \"end >= start if end exists\"\n\n  Credential:\n    required: [service, secret_ref]\n    forbidden_properties: [password, secret, token]  # Force indirection\n\nrelations:\n  has_owner:\n    from_types: [Project, Task]\n    to_types: [Person]\n    cardinality: many_to_one\n  \n  blocks:\n    from_types: [Task]\n    to_types: [Task]\n    acyclic: true  # No circular dependencies\n```\n\n## Skill Contract\n\nSkills that use ontology should declare:\n\n```yaml\n# In SKILL.md frontmatter or header\nontology:\n  reads: [Task, Project, Person]\n  writes: [Task, Action]\n  preconditions:\n    - \"Task.assignee must exist\"\n  postconditions:\n    - \"Created Task has status=open\"\n```\n\n## Planning as Graph Transformation\n\nModel multi-step plans as a sequence of graph operations:\n\n```\nPlan: \"Schedule team meeting and create follow-up tasks\"\n\n1. CREATE Event { title: \"Team Sync\", attendees: [p_001, p_002] }\n2. RELATE Event -> has_project -> proj_001\n3. CREATE Task { title: \"Prepare agenda\", assignee: p_001 }\n4. RELATE Task -> for_event -> event_001\n5. CREATE Task { title: \"Send summary\", assignee: p_001, blockers: [task_001] }\n```\n\nEach step is validated before execution. Rollback on constraint violation.\n\n## Integration Patterns\n\n### With Causal Inference\n\nLog ontology mutations as causal actions:\n\n```python\n# When creating/updating entities, also log to causal action log\naction = {\n    \"action\": \"create_entity\",\n    \"domain\": \"ontology\", \n    \"context\": {\"type\": \"Task\", \"project\": \"proj_001\"},\n    \"outcome\": \"created\"\n}\n```\n\n### Cross-Skill Communication\n\n```python\n# Email skill creates commitment\ncommitment = ontology.create(\"Commitment\", {\n    \"source_message\": msg_id,\n    \"description\": \"Send report by Friday\",\n    \"due\": \"2026-01-31\"\n})\n\n# Task skill picks it up\ntasks = ontology.query(\"Commitment\", {\"status\": \"pending\"})\nfor c in tasks:\n    ontology.create(\"Task\", {\n        \"title\": c.description,\n        \"due\": c.due,\n        \"source\": c.id\n    })\n```\n\n## Quick Start\n\n```bash\n# Initialize ontology storage\nmkdir -p memory/ontology\ntouch memory/ontology/graph.jsonl\n\n# Create schema (optional but recommended)\ncat > memory/ontology/schema.yaml << 'EOF'\ntypes:\n  Task:\n    required: [title, status]\n  Project:\n    required: [name]\n  Person:\n    required: [name]\nEOF\n\n# Start using\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\"}'\npython3 scripts/ontology.py list --type Person\n```\n\n## References\n\n- `references/schema.md` — Full type definitions and constraint patterns\n- `references/queries.md` — Query language and traversal examples\n\nFile v0.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn72dv4fm7ss7swbq47nnpad9x7zy2jh\",\n  \"slug\": \"ontology\",\n  \"version\": \"0.1.0\",\n  \"publishedAt\": 1769415435751\n}\n\nFile v0.1.0:references/queries.md\n\n# Query Reference\n\nQuery patterns and graph traversal examples.\n\n## Basic Queries\n\n### Get by ID\n\n```bash\npython3 scripts/ontology.py get --id task_001\n```\n\n### List by Type\n\n```bash\n# All tasks\npython3 scripts/ontology.py list --type Task\n\n# All people\npython3 scripts/ontology.py list --type Person\n```\n\n### Filter by Properties\n\n```bash\n# Open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n\n# High priority tasks\npython3 scripts/ontology.py query --type Task --where '{\"priority\":\"high\"}'\n\n# Tasks assigned to specific person (by property)\npython3 scripts/ontology.py query --type Task --where '{\"assignee\":\"p_001\"}'\n```\n\n## Relation Queries\n\n### Get Related Entities\n\n```bash\n# Tasks belonging to a project (outgoing)\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# What projects does this task belong to (incoming)\npython3 scripts/ontology.py related --id task_001 --rel part_of --dir incoming\n\n# All relations for an entity (both directions)\npython3 scripts/ontology.py related --id p_001 --dir both\n```\n\n### Common Patterns\n\n```bash\n# Who owns this project?\npython3 scripts/ontology.py related --id proj_001 --rel has_owner\n\n# What events is this person attending?\npython3 scripts/ontology.py related --id p_001 --rel attendee_of --dir outgoing\n\n# What's blocking this task?\npython3 scripts/ontology.py related --id task_001 --rel blocked_by --dir incoming\n```\n\n## Programmatic Queries\n\n### Python API\n\n```python\nfrom scripts.ontology import load_graph, query_entities, get_related\n\n# Load the graph\nentities, relations = load_graph(\"memory/ontology/graph.jsonl\")\n\n# Query entities\nopen_tasks = query_entities(\"Task\", {\"status\": \"open\"}, \"memory/ontology/graph.jsonl\")\n\n# Get related\nproject_tasks = get_related(\"proj_001\", \"has_task\", \"memory/ontology/graph.jsonl\")\n```\n\n### Complex Queries\n\n```python\n# Find all tasks blocked by incomplete dependencies\ndef find_blocked_tasks(graph_path):\n    entities, relations = load_graph(graph_path)\n    blocked = []\n    \n    for entity in entities.values():\n        if entity[\"type\"] != \"Task\":\n            continue\n        if entity[\"properties\"].get(\"status\") == \"blocked\":\n            # Find what's blocking it\n            blockers = get_related(entity[\"id\"], \"blocked_by\", graph_path, \"incoming\")\n            incomplete_blockers = [\n                b for b in blockers \n                if b[\"entity\"][\"properties\"].get(\"status\") != \"done\"\n            ]\n            if incomplete_blockers:\n                blocked.append({\n                    \"task\": entity,\n                    \"blockers\": incomplete_blockers\n                })\n    \n    return blocked\n```\n\n### Path Queries\n\n```python\n# Find path between two entities\ndef find_path(from_id, to_id, graph_path, max_depth=5):\n    entities, relations = load_graph(graph_path)\n    \n    visited = set()\n    queue = [(from_id, [])]\n    \n    while queue:\n        current, path = queue.pop(0)\n        \n        if current == to_id:\n            return path\n        \n        if current in visited or len(path) >= max_depth:\n            continue\n        \n        visited.add(current)\n        \n        for rel in relations:\n            if rel[\"from\"] == current and rel[\"to\"] not in visited:\n                queue.append((rel[\"to\"], path + [rel]))\n            if rel[\"to\"] == current and rel[\"from\"] not in visited:\n                queue.append((rel[\"from\"], path + [{**rel, \"direction\": \"incoming\"}]))\n    \n    return None  # No path found\n```\n\n## Query Patterns by Use Case\n\n### Task Management\n\n```bash\n# All my open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\",\"assignee\":\"p_me\"}'\n\n# Overdue tasks (requires custom script for date comparison)\n# See references/schema.md for date handling\n\n# Tasks with no blockers\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n# Then filter in code for those with no incoming \"blocks\" relations\n```\n\n### Project Overview\n\n```bash\n# All tasks in project\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# Project team members\npython3 scripts/ontology.py related --id proj_001 --rel has_member\n\n# Project goals\npython3 scripts/ontology.py related --id proj_001 --rel has_goal\n```\n\n### People & Contacts\n\n```bash\n# All people\npython3 scripts/ontology.py list --type Person\n\n# People in an organization\npython3 scripts/ontology.py related --id org_001 --rel has_member\n\n# What's assigned to this person\npython3 scripts/ontology.py related --id p_001 --rel assigned_to --dir incoming\n```\n\n### Events & Calendar\n\n```bash\n# All events\npython3 scripts/ontology.py list --type Event\n\n# Events at a location\npython3 scripts/ontology.py related --id loc_001 --rel located_at --dir incoming\n\n# Event attendees\npython3 scripts/ontology.py related --id event_001 --rel attendee_of --dir incoming\n```\n\n## Aggregations\n\nFor complex aggregations, use Python:\n\n```python\nfrom collections import Counter\n\ndef task_status_summary(project_id, graph_path):\n    \"\"\"Count tasks by status for a project.\"\"\"\n    tasks = get_related(project_id, \"has_task\", graph_path)\n    statuses = Counter(t[\"entity\"][\"properties\"].get(\"status\", \"unknown\") for t in tasks)\n    return dict(statuses)\n\ndef workload_by_person(graph_path):\n    \"\"\"Count open tasks per person.\"\"\"\n    open_tasks = query_entities(\"Task\", {\"status\": \"open\"}, graph_path)\n    workload = Counter(t[\"properties\"].get(\"assignee\") for t in open_tasks)\n    return dict(workload)\n```\n\nFile v0.1.0:references/schema.md\n\n# Ontology Schema Reference\n\nFull type definitions and constraint patterns for the ontology graph.\n\n## Core Types\n\n### Agents & People\n\n```yaml\nPerson:\n  required: [name]\n  properties:\n    name: string\n    email: string?\n    phone: string?\n    organization: ref(Organization)?\n    notes: string?\n    tags: string[]?\n\nOrganization:\n  required: [name]\n  properties:\n    name: string\n    type: enum(company, team, community, government, other)?\n    website: url?\n    members: ref(Person)[]?\n```\n\n### Work Management\n\n```yaml\nProject:\n  required: [name]\n  properties:\n    name: string\n    description: string?\n    status: enum(planning, active, paused, completed, archived)\n    owner: ref(Person)?\n    team: ref(Person)[]?\n    goals: ref(Goal)[]?\n    start_date: date?\n    end_date: date?\n    tags: string[]?\n\nTask:\n  required: [title, status]\n  properties:\n    title: string\n    description: string?\n    status: enum(open, in_progress, blocked, done, cancelled)\n    priority: enum(low, medium, high, urgent)?\n    assignee: ref(Person)?\n    project: ref(Project)?\n    due: datetime?\n    estimate_hours: number?\n    blockers: ref(Task)[]?\n    tags: string[]?\n\nGoal:\n  required: [description]\n  properties:\n    description: string\n    target_date: date?\n    status: enum(active, achieved, abandoned)?\n    metrics: object[]?\n    key_results: string[]?\n```\n\n### Time & Location\n\n```yaml\nEvent:\n  required: [title, start]\n  properties:\n    title: string\n    description: string?\n    start: datetime\n    end: datetime?\n    location: ref(Location)?\n    attendees: ref(Person)[]?\n    recurrence: object?  # iCal RRULE format\n    status: enum(confirmed, tentative, cancelled)?\n    reminders: object[]?\n\nLocation:\n  required: [name]\n  properties:\n    name: string\n    address: string?\n    city: string?\n    country: string?\n    coordinates: object?  # {lat, lng}\n    timezone: string?\n```\n\n### Information\n\n```yaml\nDocument:\n  required: [title]\n  properties:\n    title: string\n    path: string?  # Local file path\n    url: url?      # Remote URL\n    mime_type: string?\n    summary: string?\n    content_hash: string?\n    tags: string[]?\n\nMessage:\n  required: [content, sender]\n  properties:\n    content: string\n    sender: ref(Person)\n    recipients: ref(Person)[]\n    thread: ref(Thread)?\n    timestamp: datetime\n    platform: string?  # email, slack, whatsapp, etc.\n    external_id: string?\n\nThread:\n  required: [subject]\n  properties:\n    subject: string\n    participants: ref(Person)[]\n    messages: ref(Message)[]\n    status: enum(active, archived)?\n    last_activity: datetime?\n\nNote:\n  required: [content]\n  properties:\n    content: string\n    title: string?\n    tags: string[]?\n    refs: ref(Entity)[]?  # Links to any entity\n    created: datetime\n```\n\n### Resources\n\n```yaml\nAccount:\n  required: [service, username]\n  properties:\n    service: string  # github, gmail, aws, etc.\n    username: string\n    url: url?\n    credential_ref: ref(Credential)?\n\nDevice:\n  required: [name, type]\n  properties:\n    name: string\n    type: enum(computer, phone, tablet, server, iot, other)\n    os: string?\n    identifiers: object?  # {mac, serial, etc.}\n    owner: ref(Person)?\n\nCredential:\n  required: [service, secret_ref]\n  forbidden_properties: [password, secret, token, key, api_key]\n  properties:\n    service: string\n    secret_ref: string  # Reference to secret store (e.g., \"keychain:github-token\")\n    expires: datetime?\n    scope: string[]?\n```\n\n### Meta\n\n```yaml\nAction:\n  required: [type, target, timestamp]\n  properties:\n    type: string  # create, update, delete, send, etc.\n    target: ref(Entity)\n    timestamp: datetime\n    actor: ref(Person|Agent)?\n    outcome: enum(success, failure, pending)?\n    details: object?\n\nPolicy:\n  required: [scope, rule]\n  properties:\n    scope: string  # What this policy applies to\n    rule: string   # The constraint in natural language or code\n    enforcement: enum(block, warn, log)\n    enabled: boolean\n```\n\n## Relation Types\n\n### Ownership & Assignment\n\n```yaml\nowns:\n  from_types: [Person, Organization]\n  to_types: [Account, Device, Document, Project]\n  cardinality: one_to_many\n\nhas_owner:\n  from_types: [Project, Task, Document]\n  to_types: [Person]\n  cardinality: many_to_one\n\nassigned_to:\n  from_types: [Task]\n  to_types: [Person]\n  cardinality: many_to_one\n```\n\n### Hierarchy & Containment\n\n```yaml\nhas_task:\n  from_types: [Project]\n  to_types: [Task]\n  cardinality: one_to_many\n\nhas_goal:\n  from_types: [Project]\n  to_types: [Goal]\n  cardinality: one_to_many\n\nmember_of:\n  from_types: [Person]\n  to_types: [Organization]\n  cardinality: many_to_many\n\npart_of:\n  from_types: [Task, Document, Event]\n  to_types: [Project]\n  cardinality: many_to_one\n```\n\n### Dependencies\n\n```yaml\nblocks:\n  from_types: [Task]\n  to_types: [Task]\n  acyclic: true  # Prevents circular dependencies\n  cardinality: many_to_many\n\ndepends_on:\n  from_types: [Task, Project]\n  to_types: [Task, Project, Event]\n  acyclic: true\n  cardinality: many_to_many\n\nrequires:\n  from_types: [Action]\n  to_types: [Credential, Policy]\n  cardinality: many_to_many\n```\n\n### References\n\n```yaml\nmentions:\n  from_types: [Document, Message, Note]\n  to_types: [Person, Project, Task, Event]\n  cardinality: many_to_many\n\nreferences:\n  from_types: [Document, Note]\n  to_types: [Document, Note]\n  cardinality: many_to_many\n\nfollows_up:\n  from_types: [Task, Event]\n  to_types: [Event, Message]\n  cardinality: many_to_one\n```\n\n### Events\n\n```yaml\nattendee_of:\n  from_types: [Person]\n  to_types: [Event]\n  cardinality: many_to_many\n  properties:\n    status: enum(accepted, declined, tentative, pending)\n\nlocated_at:\n  from_types: [Event, Person, Device]\n  to_types: [Location]\n  cardinality: many_to_one\n```\n\n## Global Constraints\n\n```yaml\nconstraints:\n  # Credentials must never store secrets directly\n  - type: Credential\n    rule: \"forbidden_properties: [password, secret, token]\"\n    message: \"Credentials must use secret_ref to reference external secret storage\"\n\n  # Tasks must have valid status transitions\n  - type: Task\n    rule: \"status transitions: open -> in_progress -> (done|blocked) -> done\"\n    enforcement: warn\n\n  # Events must have end >= start\n  - type: Event\n    rule: \"if end exists: end >= start\"\n    message: \"Event end time must be after start time\"\n\n  # No orphan tasks (should belong to a project or have explicit owner)\n  - type: Task\n    rule: \"has_relation(part_of, Project) OR has_property(owner)\"\n    enforcement: warn\n    message: \"Task should belong to a project or have an explicit owner\"\n\n  # Circular dependency prevention\n  - relation: blocks\n    rule: \"acyclic\"\n    message: \"Circular task dependencies are not allowed\"\n```","readmeExcerpt":"Skill: ontology Owner: oswalpalash Summary: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linkin... Tags: latest:1.0.4 Version history: v1.0.4 | 2026-03-11T17:19:19.725Z | user - Initial release of the ontology skill for typed, constraint-validated knowledge graphs. - Supports entity and relation CRUD, property an","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"Entity: { id, type, properties, relations, created, updated }\nRelation: { from_id, relation_type, to_id, properties }"},{"language":"yaml","snippet":"# Agents & People\nPerson: { name, email?, phone?, notes? }\nOrganization: { name, type?, members[] }\n\n# Work\nProject: { name, status, goals[], owner? }\nTask: { title, status, due?, priority?, assignee?, blockers[] }\nGoal: { description, target_date?, metrics[] }\n\n# Time & Place\nEvent: { title, start, end?, location?, attendees[], recurrence? }\nLocation: { name, address?, coordinates? }\n\n# Information\nDocument: { title, path?, url?, summary? }\nMessage: { content, sender, recipients[], thread? }\nThread: { subject, participants[], messages[] }\nNote: { content, tags[], refs[] }\n\n# Resources\nAccount: { service, username, credential_ref? }\nDevice: { name, type, identifiers[] }\nCredential: { service, secret_ref }  # Never store secrets directly\n\n# Meta\nAction: { type, target, timestamp, outcome? }\nPolicy: { scope, rule, enforcement }"},{"language":"jsonl","snippet":"{\"op\":\"create\",\"entity\":{\"id\":\"p_001\",\"type\":\"Person\",\"properties\":{\"name\":\"Alice\"}}}\n{\"op\":\"create\",\"entity\":{\"id\":\"proj_001\",\"type\":\"Project\",\"properties\":{\"name\":\"Website Redesign\",\"status\":\"active\"}}}\n{\"op\":\"relate\",\"from\":\"proj_001\",\"rel\":\"has_owner\",\"to\":\"p_001\"}"},{"language":"bash","snippet":"python3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'"},{"language":"bash","snippet":"python3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\npython3 scripts/ontology.py get --id task_001\npython3 scripts/ontology.py related --id proj_001 --rel has_task"},{"language":"bash","snippet":"python3 scripts/ontology.py relate --from proj_001 --rel has_task --to task_001"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: ontology\ndescription: Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on \"remember\", \"what do I know about\", \"link X to Y\", \"show dependencies\", entity CRUD, or cross-skill data access.\n---\n\n# Ontology\n\nA typed vocabulary + constraint system for representing knowledge as a verifiable graph.\n\n## Core Concept\n\nEverything is an **entity** with a **type**, **properties**, and **relations** to other entities. Every mutation is validated against type constraints before committing.\n\n```\nEntity: { id, type, properties, relations, created, updated }\nRelation: { from_id, relation_type, to_id, properties }\n```\n\n## When to Use\n\n| Trigger | Action |\n|---------|--------|\n| \"Remember that...\" | Create/update entity |\n| \"What do I know about X?\" | Query graph |\n| \"Link X to Y\" | Create relation |\n| \"Show all tasks for project Z\" | Graph traversal |\n| \"What depends on X?\" | Dependency query |\n| Planning multi-step work | Model as graph transformations |\n| Skill needs shared state | Read/write ontology objects |\n\n## Core Types\n\n```yaml\n# Agents & People\nPerson: { name, email?, phone?, notes? }\nOrganization: { name, type?, members[] }\n\n# Work\nProject: { name, status, goals[], owner? }\nTask: { title, status, due?, priority?, assignee?, blockers[] }\nGoal: { description, target_date?, metrics[] }\n\n# Time & Place\nEvent: { title, start, end?, location?, attendees[], recurrence? }\nLocation: { name, address?, coordinates? }\n\n# Information\nDocument: { title, path?, url?, summary? }\nMessage: { content, sender, recipients[], thread? }\nThread: { subject, participants[], messages[] }\nNote: { content, tags[], refs[] }\n\n# Resources\nAccount: { service, username, credential_ref? }\nDevice: { name, type, identifiers[] }\nCredential: { service, secret_ref }  # Never store secrets directly\n\n# Meta\nAction: { type, target, timestamp, outcome? }\nPolicy: { scope, rule, enforcement }\n```\n\n## Storage\n\nDefault: `memory/ontology/graph.jsonl`\n\n```jsonl\n{\"op\":\"create\",\"entity\":{\"id\":\"p_001\",\"type\":\"Person\",\"properties\":{\"name\":\"Alice\"}}}\n{\"op\":\"create\",\"entity\":{\"id\":\"proj_001\",\"type\":\"Project\",\"properties\":{\"name\":\"Website Redesign\",\"status\":\"active\"}}}\n{\"op\":\"relate\",\"from\":\"proj_001\",\"rel\":\"has_owner\",\"to\":\"p_001\"}\n```\n\nQuery via scripts or direct file ops. For complex graphs, migrate to SQLite.\n\n### Append-Only Rule\n\nWhen working with existing ontology data or schema, **append/merge** changes instead of overwriting files. This preserves history and avoids clobbering prior definitions.\n\n## Workflows\n\n### Create Entity\n\n```bash\npython3 scripts/ontology.py create --type Person --props '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'\n```\n\n### Query\n\n```bash\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\npython3 scrip"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn72dv4fm7ss7swbq47nnpad9x7zy2jh\",\n  \"slug\": \"ontology\",\n  \"version\": \"1.0.4\",\n  \"publishedAt\": 1773249559725\n}"},{"path":"references/queries.md","content":"# Query Reference\n\nQuery patterns and graph traversal examples.\n\n## Basic Queries\n\n### Get by ID\n\n```bash\npython3 scripts/ontology.py get --id task_001\n```\n\n### List by Type\n\n```bash\n# All tasks\npython3 scripts/ontology.py list --type Task\n\n# All people\npython3 scripts/ontology.py list --type Person\n```\n\n### Filter by Properties\n\n```bash\n# Open tasks\npython3 scripts/ontology.py query --type Task --where '{\"status\":\"open\"}'\n\n# High priority tasks\npython3 scripts/ontology.py query --type Task --where '{\"priority\":\"high\"}'\n\n# Tasks assigned to specific person (by property)\npython3 scripts/ontology.py query --type Task --where '{\"assignee\":\"p_001\"}'\n```\n\n## Relation Queries\n\n### Get Related Entities\n\n```bash\n# Tasks belonging to a project (outgoing)\npython3 scripts/ontology.py related --id proj_001 --rel has_task\n\n# What projects does this task belong to (incoming)\npython3 scripts/ontology.py related --id task_001 --rel part_of --dir incoming\n\n# All relations for an entity (both directions)\npython3 scripts/ontology.py related --id p_001 --dir both\n```\n\n### Common Patterns\n\n```bash\n# Who owns this project?\npython3 scripts/ontology.py related --id proj_001 --rel has_owner\n\n# What events is this person attending?\npython3 scripts/ontology.py related --id p_001 --rel attendee_of --dir outgoing\n\n# What's blocking this task?\npython3 scripts/ontology.py related --id task_001 --rel blocked_by --dir incoming\n```\n\n## Programmatic Queries\n\n### Python API\n\n```python\nfrom scripts.ontology import load_graph, query_entities, get_related\n\n# Load the graph\nentities, relations = load_graph(\"memory/ontology/graph.jsonl\")\n\n# Query entities\nopen_tasks = query_entities(\"Task\", {\"status\": \"open\"}, \"memory/ontology/graph.jsonl\")\n\n# Get related\nproject_tasks = get_related(\"proj_001\", \"has_task\", \"memory/ontology/graph.jsonl\")\n```\n\n### Complex Queries\n\n```python\n# Find all tasks blocked by incomplete dependencies\ndef find_blocked_tasks(graph_path):\n    entities, relations = load_graph(graph_path)\n    blocked = []\n    \n    for entity in entities.values():\n        if entity[\"type\"] != \"Task\":\n            continue\n        if entity[\"properties\"].get(\"status\") == \"blocked\":\n            # Find what's blocking it\n            blockers = get_related(entity[\"id\"], \"blocked_by\", graph_path, \"incoming\")\n            incomplete_blockers = [\n                b for b in blockers \n                if b[\"entity\"][\"properties\"].get(\"status\") != \"done\"\n            ]\n            if incomplete_blockers:\n                blocked.append({\n                    \"task\": entity,\n                    \"blockers\": incomplete_blockers\n                })\n    \n    return blocked\n```\n\n### Path Queries\n\n```python\n# Find path between two entities\ndef find_path(from_id, to_id, graph_path, max_depth=5):\n    entities, relations = load_graph(graph_path)\n    \n    visited = set()\n    queue = [(from_id, [])]\n    \n    while queue:\n        current, path = queue.pop(0)\n        \n        if current == to_id:\n            return p"},{"path":"references/schema.md","content":"# Ontology Schema Reference\n\nFull type definitions and constraint patterns for the ontology graph.\n\n## Core Types\n\n### Agents & People\n\n```yaml\nPerson:\n  required: [name]\n  properties:\n    name: string\n    email: string?\n    phone: string?\n    organization: ref(Organization)?\n    notes: string?\n    tags: string[]?\n\nOrganization:\n  required: [name]\n  properties:\n    name: string\n    type: enum(company, team, community, government, other)?\n    website: url?\n    members: ref(Person)[]?\n```\n\n### Work Management\n\n```yaml\nProject:\n  required: [name]\n  properties:\n    name: string\n    description: string?\n    status: enum(planning, active, paused, completed, archived)\n    owner: ref(Person)?\n    team: ref(Person)[]?\n    goals: ref(Goal)[]?\n    start_date: date?\n    end_date: date?\n    tags: string[]?\n\nTask:\n  required: [title, status]\n  properties:\n    title: string\n    description: string?\n    status: enum(open, in_progress, blocked, done, cancelled)\n    priority: enum(low, medium, high, urgent)?\n    assignee: ref(Person)?\n    project: ref(Project)?\n    due: datetime?\n    estimate_hours: number?\n    blockers: ref(Task)[]?\n    tags: string[]?\n\nGoal:\n  required: [description]\n  properties:\n    description: string\n    target_date: date?\n    status: enum(active, achieved, abandoned)?\n    metrics: object[]?\n    key_results: string[]?\n```\n\n### Time & Location\n\n```yaml\nEvent:\n  required: [title, start]\n  properties:\n    title: string\n    description: string?\n    start: datetime\n    end: datetime?\n    location: ref(Location)?\n    attendees: ref(Person)[]?\n    recurrence: object?  # iCal RRULE format\n    status: enum(confirmed, tentative, cancelled)?\n    reminders: object[]?\n\nLocation:\n  required: [name]\n  properties:\n    name: string\n    address: string?\n    city: string?\n    country: string?\n    coordinates: object?  # {lat, lng}\n    timezone: string?\n```\n\n### Information\n\n```yaml\nDocument:\n  required: [title]\n  properties:\n    title: string\n    path: string?  # Local file path\n    url: url?      # Remote URL\n    mime_type: string?\n    summary: string?\n    content_hash: string?\n    tags: string[]?\n\nMessage:\n  required: [content, sender]\n  properties:\n    content: string\n    sender: ref(Person)\n    recipients: ref(Person)[]\n    thread: ref(Thread)?\n    timestamp: datetime\n    platform: string?  # email, slack, whatsapp, etc.\n    external_id: string?\n\nThread:\n  required: [subject]\n  properties:\n    subject: string\n    participants: ref(Person)[]\n    messages: ref(Message)[]\n    status: enum(active, archived)?\n    last_activity: datetime?\n\nNote:\n  required: [content]\n  properties:\n    content: string\n    title: string?\n    tags: string[]?\n    refs: ref(Entity)[]?  # Links to any entity\n    created: datetime\n```\n\n### Resources\n\n```yaml\nAccount:\n  required: [service, username]\n  properties:\n    service: string  # github, gmail, aws, etc.\n    username: string\n    url: url?\n    credential_ref: ref(Credential)?\n\nDevice:\n  required: [name, type]\n  properties:\n    name"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1149,"uniquenessScore":44,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-05-22T06:53:19.879Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-05-22T06:53:19.879Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-09T22:53:32.162Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}