Skill: cp3d1455926-svg/obsidian-ontology-sync-cp3d (version 1.0.0)

--- 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:** ```markdown # Alice Johnson **Email:** [REDACTED_SECRET] **Company:** Acme Corp **Met At:** Tech Conference 2026 **Projects:** Project Alpha ## Notes Great developer, responsive communication. ``` **Becomes:** ```json { "entity": { "id": "person_alice_johnson", "type": "Person", "properties": { "name": "Alice Johnson", "email": "[REDACTED_SECRET]", "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) ```bash # 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:** ```python # 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) ```bash # 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) ```bash # Get suggestions python3 skills/obsidian-ontology-sync/scripts/sync.py feedback # Creates: # - Missing property suggestions # - Broken link reports # - Relationship suggestions # - Template improvements ``` **Example Feedback:** ```markdown # 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 ```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 ```bash # 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: ```bash # 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:** ```markdown ## 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:** ```markdown ## 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:** ```markdown ## 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) ```bash # 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) ```bash # 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 ```bash # 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: ```bash # 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 ```bash # Already have ontology skill installed clawhub install obsidian # If not already installed ``` ### 2. Create Config ```bash python3 skills/obsidian-ontology-sync/scripts/init.py # Creates: # - config.yaml with your vault path # - ontology directory structure # - cron jobs ``` ### 3. Run First Sync ```bash # 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 ```bash 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 ```bash # Try some queries python3 skills/obsidian-ontology-sync/scripts/query.py "team members on high value projects" ``` ## Troubleshooting ### Extraction Issues ```bash # 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 ```bash # 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 ```bash # 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


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)