{"id":"896f5f7d-5e5b-4ea0-b289-771aed3cb182","entityType":"agent","slug":"clawhub-oswalpalash-ontology","name":"ontology","canonicalUrl":"https://www.xpersona.co/agent/clawhub-oswalpalash-ontology","canonicalPath":"/agent/clawhub-oswalpalash-ontology","generatedAt":"2026-10-09T00:23:58.642Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-06-01T00:29:27.634Z","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. 186.7K downloads reported by the source. Last updated 6/1/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-06-01T00:29:27.634Z","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-06-01T00:29:27.634Z","emptyReason":null},"stars":null,"forks":null,"downloads":186706,"packageName":null,"latestVersion":"1.0.4","tractionLabel":"186.7K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-06-01T00:29:27.634Z","emptyReason":null},"lastUpdatedAt":"2026-06-01T00:29:27.634Z","lastCrawledAt":"2026-06-01T00:29:27.634Z","lastIndexedAt":null,"nextCrawlAt":"2026-06-02T00:29:27.634Z","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":6,"zipByteSize":13628},{"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/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/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-09T00:23:58.641Z"}},"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/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-oswalpalash-ontology/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-06-01T00:29:27.634Z","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: 6 files, 13628 bytes\n\nFiles: references/queries.md (5471b), references/schema.md (6650b), scripts/ontology.py (21596b), skill-card.md (2441b), 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\nFile v1.0.4:skill-card.md\n\n## Description: <br>\nTyped knowledge graph for structured agent memory and composable skills. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[oswalpalash](https://clawhub.ai/user/oswalpalash) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agents use this skill to maintain a typed local knowledge graph for people, projects, tasks, events, documents, and related objects. It supports entity and relation CRUD, graph traversal, schema constraints, validation, and shared state across composable skills. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill stores durable local knowledge graph data that may include sensitive workspace context. <br>\nMitigation: Control what agents are allowed to remember and periodically inspect memory/ontology/graph.jsonl and memory/ontology/schema.yaml. <br>\nRisk: Passwords, tokens, or raw secrets could be placed into ontology records if a user or agent ignores the documented credential pattern. <br>\nMitigation: Do not store raw secrets; store references to a separate secret store and validate schemas that forbid secret-like credential properties. <br>\nRisk: Updates and deletes are append-only, so prior values can remain in graph history. <br>\nMitigation: Avoid recording information that must be erased from local history, and review the append-only graph file before sharing or retaining it. <br>\n\n\n## Reference(s): <br>\n- [Ontology Schema Reference](artifact/references/schema.md) <br>\n- [Query Reference](artifact/references/queries.md) <br>\n- [ClawHub Skill Page](https://clawhub.ai/oswalpalash/ontology) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with inline JSON, YAML, Python, and shell command examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May create or update local workspace files under memory/ontology, including graph.jsonl and schema.yaml.] <br>\n\n## Skill Version(s): <br>\n1.0.4 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\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"},{"path":"skill-card.md","content":"## Description: <br>\nTyped knowledge graph for structured agent memory and composable skills. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[oswalpalash](https://clawhub.ai/user/oswalpalash) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agents use this skill to maintain a typed local knowledge graph for people, projects, tasks, events, documents, and related objects. It supports entity and relation CRUD, graph traversal, schema constraints, validation, and shared state across composable skills. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill stores durable local knowledge graph data that may include sensitive workspace context. <br>\nMitigation: Control what agents are allowed to remember and periodically inspect memory/ontology/graph.jsonl and memory/ontology/schema.yaml. <br>\nRisk: Passwords, tokens, or raw secrets could be placed into ontology records if a user or agent ignores the documented credential pattern. <br>\nMitigation: Do not store raw secrets; store references to a separate secret store and validate schemas that forbid secret-like credential properties. <br>\nRisk: Updates and deletes are append-only, so prior values can remain in graph history. <br>\nMitigation: Avoid recording information that must be erased from local history, and review the append-only graph file before sharing or retaining it. <br>\n\n\n## Reference(s): <br>\n- [Ontology Schema Reference](artifact/references/schema.md) <br>\n- [Query Reference](artifact/references/queries.md) <br>\n- [ClawHub Skill Page](https://clawhub.ai/oswalpalash/ontology) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with inline JSON, YAML, Python, and shell command examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May create or update local workspace files under memory/ontology, including graph.jsonl and schema.yaml.] <br>\n\n## Skill Version(s): <br>\n1.0.4 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1468,"uniquenessScore":42,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-06-01T00:29:27.634Z","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-06-01T00:29:27.634Z","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-09T00:23:58.642Z","emptyReason":null},"items":[{"id":"959108e7-5f7c-45ac-bea0-9ab67f017226","entityType":"agent","canonicalPath":"/agent/langchain-x1pay-langchain","slug":"langchain-x1pay-langchain","name":"@x1pay/langchain","description":"LangChain/LangGraph tools for AI agent x402 payments on X1","url":"https://www.npmjs.com/package/@x1pay/langchain","homepage":null,"source":"GITHUB_OPENCLEW","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":70,"overallRank":65,"updatedAt":"2026-06-01T00:29:07.099Z","createdAt":"2026-05-23T06:52:58.553Z","downloads":null},{"id":"4f8f8f95-34f7-49a9-b516-391d1c355d6c","entityType":"agent","canonicalPath":"/agent/langchain-langchain-langgraph-swarm","slug":"langchain-langchain-langgraph-swarm","name":"@langchain/langgraph-swarm","description":"An implementation of a multi-agent swarm using LangGraph","url":"git+ssh://git@github.com/langchain-ai/langgraphjs.git","homepage":"https://github.com/langchain-ai/langgraphjs#readme","source":"GITHUB_OPENCLEW","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":70,"overallRank":65,"updatedAt":"2026-06-01T00:29:03.792Z","createdAt":"2026-05-23T06:52:55.396Z","downloads":null},{"id":"e36fd59b-38d7-4e73-aa20-c1431a8f7434","entityType":"agent","canonicalPath":"/agent/langchain-langchain-langgraph-supervisor","slug":"langchain-langchain-langgraph-supervisor","name":"@langchain/langgraph-supervisor","description":"LangGraph Multi-Agent Supervisor","url":"git+ssh://git@github.com/langchain-ai/langgraphjs.git","homepage":"https://github.com/langchain-ai/langgraphjs#readme","source":"GITHUB_OPENCLEW","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":70,"overallRank":65,"updatedAt":"2026-06-01T00:29:03.756Z","createdAt":"2026-05-23T06:52:55.353Z","downloads":null},{"id":"d1d0f93e-b722-4791-9bbf-2532470054c2","entityType":"agent","canonicalPath":"/agent/langchain-oceanbus-langchain","slug":"langchain-oceanbus-langchain","name":"oceanbus-langchain","description":"LangChain tools for OceanBus — give your LangChain and CrewAI agents a global identity, encrypted messaging, and Yellow Pages service discovery with a single import.","url":"git+https://github.com/oceanbus/oceanbus.git","homepage":"https://github.com/oceanbus/oceanbus#readme","source":"GITHUB_OPENCLEW","protocols":["OPENCLAW"],"capabilities":["oceanbus","langchain","langchain-tools","agent-to-agent","ai-agent","communication","messaging","e2ee","structured-tool","yellow-pages","service-discovery","reputation","crewai"],"safetyScore":70,"overallRank":65,"updatedAt":"2026-06-01T00:29:02.595Z","createdAt":"2026-05-23T06:52:54.240Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}