🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Obsidian Ontology Sync

by @parthpandya1729

Bidirectional sync between Obsidian PKM (human-friendly notes) and structured ontology (machine-queryable graph). Automatically extracts entities and relatio...

Versionv1.0.1
Downloads7,684
Installs111
Stars⭐ 15
TERMINAL
clawhub install obsidian-ontology-sync

πŸ“– About This Skill


name: obsidian-ontology-sync description: Bidirectional sync between Obsidian PKM (human-friendly notes) and structured ontology (machine-queryable graph). Automatically extracts entities and relationships from markdown, maintains ontology graph, and provides feedback to improve note structure. Run sync every few hours via cron. metadata: { "tags": ["obsidian", "ontology", "knowledge-graph", "pkm", "automation"], "openclaw": { "requires": { "skills": ["obsidian", "ontology"] } } }

Obsidian-Ontology Sync

Philosophy: Obsidian is PRIMARY (human writes natural notes) β†’ Ontology is DERIVED (machine extracts structure) β†’ Feedback loop improves both

Core Concept

Obsidian Notes (Markdown)
    ↓ Extract (every 3 hours)
Ontology Graph (Structured)
    ↓ Query & Analyze
Insights & Suggestions
    ↓ Feedback
Improved Note Templates

When to Use

| Situation | Action | |-----------|--------| | After creating/updating contacts | Run sync to extract entities | | Before business queries | Sync then query ontology | | Weekly review | Sync + analyze + get suggestions | | New project setup | Extract entities + suggest structure | | Team status tracking | Sync daily-status β†’ ontology β†’ analytics |

What Gets Extracted

From Contact Notes (references/contacts/*.md)

Extracts:

  • Person entity (name, email, phone)
  • works_at β†’ Organization
  • met_at β†’ Event
  • assigned_to β†’ Project (if mentioned)
  • status β†’ (prospect, warm_lead, client, etc.)
  • Example:

    # Alice Johnson

    Email: alice@company.com Company: Acme Corp Met At: Tech Conference 2026 Projects: Project Alpha

    Notes

    Great developer, responsive communication.

    Becomes:

    {
      "entity": {
        "id": "person_alice_johnson",
        "type": "Person",
        "properties": {
          "name": "Alice Johnson",
          "email": "alice@company.com",
          "notes": "Great developer, responsive communication"
        }
      },
      "relations": [
        {"from": "person_alice_johnson", "rel": "works_at", "to": "org_acme"},
        {"from": "person_alice_johnson", "rel": "met_at", "to": "event_tech_conference_2026"},
        {"from": "person_alice_johnson", "rel": "assigned_to", "to": "project_alpha"}
      ]
    }
    

    From Client Notes (references/clients/*.md)

    Extracts:

  • Organization entity
  • has_contract_value β†’ number
  • projects β†’ Project entities
  • primary_contact β†’ Person
  • From Team Notes (references/team/*.md)

    Extracts:

  • Person entity
  • works_for β†’ Organization
  • assigned_to β†’ Project[]
  • reports_to β†’ Person
  • response_pattern β†’ (proactive, reactive, non-responsive)
  • From Daily Status (daily-status/YYYY-MM-DD/*.md)

    Extracts:

  • response_time property on Person
  • status_update β†’ Event
  • blockers β†’ Issue entities
  • behavioral_pattern tracking
  • From Project Notes (projects/*.md)

    Extracts:

  • Project entity
  • for_client β†’ Organization
  • team β†’ Person[]
  • status, value, deadline
  • Sync Process

    1. Extract Phase (Markdown β†’ Ontology)

    # Run extraction
    python3 skills/obsidian-ontology-sync/scripts/sync.py extract

    What it does:

    1. Scan configured Obsidian directories

    2. Parse markdown frontmatter + content

    3. Extract entities (Person, Project, Organization, etc.)

    4. Extract relationships (works_at, assigned_to, etc.)

    5. Write to ontology using append-only operations

    Detection Rules:

    # Contact files
    if file.startswith("references/contacts/"):
        entity_type = "Person"
        extract_email_from_content()
        extract_company_from_property("Company:")
        extract_projects_from_links([[Project]])
        
    

    Client files

    if file.startswith("references/clients/"): entity_type = "Organization" extract_contract_value() extract_projects()

    Team files

    if file.startswith("references/team/"): entity_type = "Person" role = "team_member" extract_assignments() extract_response_patterns()

    2. Analysis Phase (Ontology β†’ Insights)

    # Run analytics
    python3 skills/obsidian-ontology-sync/scripts/sync.py analyze

    Generates insights like:

    - "3 team members have no assigned projects"

    - "Contact 'John Doe' missing email address"

    - "Project 'X' has 5 people but no client linked"

    - "10 contacts from AI Summit not linked to follow-up tasks"

    3. Feedback Phase (Insights β†’ Improve PKM)

    # Get suggestions
    python3 skills/obsidian-ontology-sync/scripts/sync.py feedback

    Creates:

    - Missing property suggestions

    - Broken link reports

    - Relationship suggestions

    - Template improvements

    Example Feedback:

    # Sync Feedback - 2026-02-27

    Missing Information (10 items)

  • [ ] Alice Johnson missing phone number
  • [ ] Bob missing email in team file
  • [ ] Project Project Alpha missing deadline
  • Suggested Links (5 items)

  • [ ] Link Jane Doe (TechHub) to organization TechHub
  • [ ] Link Eve to project (found in daily-status but not in team file)
  • Relationship Insights

  • Project Alpha team: Alice, Carol, David (extracted from daily-status)
  • Suggest updating project file with team assignments
  • Template Suggestions

  • Add Projects: [[]] field to contact template
  • Add Response Pattern: field to team template
  • Configuration

    config.yaml

    # /root/life/pkm/ontology-sync/config.yaml

    obsidian: vault_path: /root/life/pkm # What to sync sources: contacts: path: references/contacts entity_type: Person extract: - email_from_content - company_from_property - projects_from_links clients: path: references/clients entity_type: Organization extract: - contract_value - projects - contacts team: path: references/team entity_type: Person role: team_member extract: - assignments - response_patterns - reports_to daily_status: path: daily-status extract: - response_times - behavioral_patterns - blockers

    ontology: storage_path: /root/life/pkm/memory/ontology format: jsonl # or sqlite for scale # Entity types to track entities: - Person - Organization - Project - Event - Task # Relationships to extract relationships: - works_at - assigned_to - met_at - for_client - reports_to - has_task - blocks

    feedback: output_path: /root/life/pkm/ontology-sync/feedback generate_reports: true suggest_templates: true highlight_missing: true

    schedule: # Run via cron every 3 hours sync_interval: "0 */3 * * *" analyze_daily: "0 9 * * *" # 9 AM daily feedback_weekly: "0 10 * * MON" # Monday 10 AM

    Scheduled Sync (Cron Integration)

    Setup Automatic Sync

    # Add to OpenClaw cron
    python3 skills/obsidian-ontology-sync/scripts/setup-cron.py

    Or manually via cron tool

    cron add \ --schedule "0 */3 * * *" \ --task "python3 skills/obsidian-ontology-sync/scripts/sync.py extract" \ --label "Obsidian β†’ Ontology Sync"

    Cron Jobs Created:

    1. Every 3 hours: Extract entities from Obsidian β†’ Update ontology 2. Daily 9 AM: Run analytics and generate insights 3. Weekly Monday 10 AM: Generate feedback report + template suggestions

    Queries (Using Ontology)

    Once synced, you can query:

    # All team members on high-value projects
    python3 skills/ontology/scripts/ontology.py query \
      --type Person \
      --where '{"role":"team_member"}' \
      --related assigned_to \
      --filter '{"type":"Project","value__gt":400000}'

    Contacts from specific event not yet followed up

    python3 skills/ontology/scripts/ontology.py query \ --type Person \ --where '{"met_at":"event_tech_conference_2026"}' \ --missing has_task

    Team response patterns

    python3 skills/ontology/scripts/ontology.py query \ --type Person \ --where '{"role":"team_member"}' \ --aggregate response_pattern

    Projects by client

    python3 skills/ontology/scripts/ontology.py query \ --type Project \ --group-by for_client \ --count

    Feedback Loop Examples

    Example 1: Missing Email Detection

    Ontology finds: Person entity with no email property

    Feedback generated:

    ## Missing Contact Information

    The following team members are missing email addresses:

  • [ ] Bob (references/team/Bob.md)
  • [ ] Lucky (references/team/Lucky.md)
  • Suggestion: Add email field to team member template: \\\markdown Email: \\\

    Example 2: Broken Project Links

    Ontology finds: Person assigned_to Project that doesn't exist

    Feedback generated:

    ## Broken Project References

    Found references to projects that don't have dedicated files:

  • [ ] "Project Epsilon" mentioned in team files but no projects/Project Epsilon.md
  • [ ] "Project Delta Tata DT" assigned but no project file
  • Suggestion: Create project files with template

    Example 3: Relationship Discovery

    Ontology finds: Multiple people working at same company

    Feedback generated:

    ## Suggested Company Grouping

    Found 3 contacts at "TechHub":

  • Jane Doe
  • [2 others from daily-status mentions]
  • Suggestion: Create references/clients/TechHub.md and link contacts

    Integration with Daily Workflow

    Morning Routine (9 AM)

    # Cron runs analysis
    

    Generates daily-insights.md with:

  • Response rate from yesterday's status requests
  • Projects needing attention (blockers mentioned)
  • Contacts to follow up (met > 3 days ago, no task)
  • Weekly Review (Monday 10 AM)

    # Cron generates weekly feedback
    

    Creates suggestions for:

  • Missing information to fill in
  • Broken links to fix
  • New templates to adopt
  • Relationship insights
  • On-Demand Queries

    # Before a meeting
    "Show me all interactions with Client X"

    Resource planning

    "Which team members are on <3 projects?"

    Sales pipeline

    "Contacts met at conferences in last 30 days without follow-up"

    Benefits

    βœ… For You

    1. Zero Extra Work: Just keep writing normal Obsidian notes 2. Automatic Structure: Ontology extracted automatically 3. Powerful Queries: Find patterns across all your data 4. Quality Improvement: Feedback loop catches missing info 5. No Double Entry: Single source of truth (Obsidian)

    βœ… For Team Management

  • Track who's on which project (auto-extracted)
  • Monitor response patterns (from daily-status)
  • Identify unbalanced workloads
  • Find blockers across projects
  • βœ… For Sales/BD

  • Track contact network (who you met, where, when)
  • Follow-up reminders (contacted >7 days ago)
  • Relationship mapping (who knows who)
  • Pipeline insights (prospects β†’ warm β†’ clients)
  • βœ… For Finance

  • Project valuations (extracted from client notes)
  • Team cost allocation (people β†’ projects β†’ revenue)
  • Revenue forecasting (active projects Γ— value)
  • File Structure After Sync

    /root/life/pkm/
    β”œβ”€β”€ references/
    β”‚   β”œβ”€β”€ contacts/          # Source notes (you write these)
    β”‚   β”œβ”€β”€ clients/           # Source notes
    β”‚   └── team/              # Source notes
    β”œβ”€β”€ daily-status/          # Source notes
    β”œβ”€β”€ projects/              # Source notes
    β”‚
    β”œβ”€β”€ memory/ontology/       # Generated ontology
    β”‚   β”œβ”€β”€ graph.jsonl        # Entity/relation storage
    β”‚   └── schema.yaml        # Type definitions
    β”‚
    └── ontology-sync/         # Sync outputs
        β”œβ”€β”€ config.yaml        # Your config
        β”œβ”€β”€ feedback/
        β”‚   β”œβ”€β”€ daily-insights.md
        β”‚   β”œβ”€β”€ weekly-feedback.md
        β”‚   └── suggestions.md
        └── logs/
            └── sync-YYYY-MM-DD.log
    

    Advanced: Bidirectional Sync

    Future capability:

    Update Obsidian notes FROM ontology insights:

    # Automatically add missing fields
    python3 skills/obsidian-ontology-sync/scripts/sync.py apply-feedback

    What it does:

    - Adds missing email field to contact notes

    - Creates suggested project files

    - Links related entities

    - Updates frontmatter

    Safety: Always creates backup before modifying files.

    Comparison with Alternatives

    | Approach | Pros | Cons | |----------|------|------| | Manual ontology | Full control | Too much work, falls behind | | Obsidian only | Simple | No structured queries | | Ontology only | Powerful queries | Not human-friendly | | This skill | Best of both | Initial setup needed |

    Getting Started

    1. Install Dependencies

    # Already have ontology skill installed
    clawhub install obsidian  # If not already installed
    

    2. Create Config

    python3 skills/obsidian-ontology-sync/scripts/init.py

    Creates:

    - config.yaml with your vault path

    - ontology directory structure

    - cron jobs

    3. Run First Sync

    # Manual first sync to test
    python3 skills/obsidian-ontology-sync/scripts/sync.py extract --dry-run

    See what would be extracted

    Review, then run for real:

    python3 skills/obsidian-ontology-sync/scripts/sync.py extract

    4. Enable Automatic Sync

    python3 skills/obsidian-ontology-sync/scripts/setup-cron.py

    Confirms cron jobs:

    βœ“ Sync every 3 hours

    βœ“ Daily analysis at 9 AM

    βœ“ Weekly feedback Monday 10 AM

    5. Query Your Data

    # Try some queries
    python3 skills/obsidian-ontology-sync/scripts/query.py "team members on high value projects"
    

    Troubleshooting

    Extraction Issues

    # Dry run to see what would be extracted
    python3 skills/obsidian-ontology-sync/scripts/sync.py extract --dry-run --verbose

    Check specific file

    python3 skills/obsidian-ontology-sync/scripts/debug.py \ --file references/contacts/Alice.md

    Query Not Finding Data

    # Check what's in ontology
    python3 skills/ontology/scripts/ontology.py query --type Person

    Verify sync ran

    cat /root/life/pkm/ontology-sync/logs/sync-latest.log

    Feedback Not Generated

    # Manually run analysis
    python3 skills/obsidian-ontology-sync/scripts/sync.py analyze
    python3 skills/obsidian-ontology-sync/scripts/sync.py feedback
    

    Version History

  • 1.0.0 (2026-02-27) - Initial version with extraction, analysis, feedback loop

  • Author: Built for team management, contact tracking, and business intelligence at scale License: MIT Tags: obsidian, ontology, knowledge-graph, pkm, automation, sync

    ⚑ When to Use

    TriggerAction
    |-----------|--------|
    | After creating/updating contacts | Run sync to extract entities |
    | Before business queries | Sync then query ontology |
    | Weekly review | Sync + analyze + get suggestions |
    | New project setup | Extract entities + suggest structure |
    | Team status tracking | Sync daily-status β†’ ontology β†’ analytics |

    πŸ’‘ Examples

    1. Install Dependencies

    # Already have ontology skill installed
    clawhub install obsidian  # If not already installed
    

    2. Create Config

    python3 skills/obsidian-ontology-sync/scripts/init.py

    Creates:

    - config.yaml with your vault path

    - ontology directory structure

    - cron jobs

    3. Run First Sync

    # Manual first sync to test
    python3 skills/obsidian-ontology-sync/scripts/sync.py extract --dry-run

    See what would be extracted

    Review, then run for real:

    python3 skills/obsidian-ontology-sync/scripts/sync.py extract

    4. Enable Automatic Sync

    python3 skills/obsidian-ontology-sync/scripts/setup-cron.py

    Confirms cron jobs:

    βœ“ Sync every 3 hours

    βœ“ Daily analysis at 9 AM

    βœ“ Weekly feedback Monday 10 AM

    5. Query Your Data

    # Try some queries
    python3 skills/obsidian-ontology-sync/scripts/query.py "team members on high value projects"
    

    βš™οΈ Configuration

    config.yaml

    # /root/life/pkm/ontology-sync/config.yaml

    obsidian: vault_path: /root/life/pkm # What to sync sources: contacts: path: references/contacts entity_type: Person extract: - email_from_content - company_from_property - projects_from_links clients: path: references/clients entity_type: Organization extract: - contract_value - projects - contacts team: path: references/team entity_type: Person role: team_member extract: - assignments - response_patterns - reports_to daily_status: path: daily-status extract: - response_times - behavioral_patterns - blockers

    ontology: storage_path: /root/life/pkm/memory/ontology format: jsonl # or sqlite for scale # Entity types to track entities: - Person - Organization - Project - Event - Task # Relationships to extract relationships: - works_at - assigned_to - met_at - for_client - reports_to - has_task - blocks

    feedback: output_path: /root/life/pkm/ontology-sync/feedback generate_reports: true suggest_templates: true highlight_missing: true

    schedule: # Run via cron every 3 hours sync_interval: "0 */3 * * *" analyze_daily: "0 9 * * *" # 9 AM daily feedback_weekly: "0 10 * * MON" # Monday 10 AM

    πŸ“‹ Tips & Best Practices

    Great developer, responsive communication.

    
    Becomes:
    
    json { "entity": { "id": "person_alice_johnson", "type": "Person", "properties": { "name": "Alice Johnson", "email": "alice@company.com", "notes": "Great developer, responsive communication" } }, "relations": [ {"from": "person_alice_johnson", "rel": "works_at", "to": "org_acme"}, {"from": "person_alice_johnson", "rel": "met_at", "to": "event_tech_conference_2026"}, {"from": "person_alice_johnson", "rel": "assigned_to", "to": "project_alpha"} ] } ``

    From Client Notes (references/clients/*.md)

    Extracts:

  • Organization entity
  • has_contract_value β†’ number
  • projects β†’ Project entities
  • primary_contact β†’ Person
  • From Team Notes (references/team/*.md)

    Extracts:

  • Person entity
  • works_for β†’ Organization
  • assigned_to β†’ Project[]
  • reports_to β†’ Person
  • response_pattern β†’ (proactive, reactive, non-responsive)
  • From Daily Status (daily-status/YYYY-MM-DD/*.md)

    Extracts:

  • response_time property on Person
  • status_update β†’ Event
  • blockers β†’ Issue entities
  • behavioral_pattern tracking
  • From Project Notes (projects/*.md)

    Extracts:

  • Project entity
  • for_client β†’ Organization
  • team β†’ Person[]
  • status, value, deadline`