Private provenance-backed social graph. Maintains queryable records of people, relationships, preferences, and shared experiences for recall, gifting, hostin...
---
name: ocas-weave
source: https://github.com/indigokarasu/weave
install: openclaw skill install https://github.com/indigokarasu/weave
description: Use when storing or retrieving facts about people, recording relationships, preparing for meetings, finding gift ideas, discovering connections between people, or syncing contacts. Maintains a private provenance-backed social graph (LadybugDB). Trigger phrases: 'who do I know in', 'what does X like', 'add this person', 'relationship with', 'gift ideas for', 'sync contacts', 'prepare for meeting with', 'update weave'. Do not use for OSINT investigations (use Scout) or general web research (use Sift).
metadata: {"openclaw":{"emoji":"πΈοΈ"}}
---
# Weave
Weave maintains a private, provenance-backed social graph of people, relationships, preferences, and shared experiences β queryable for meeting prep, gift ideas, hosting, introductions, city connections, and serendipity discovery. Every stored fact carries source type, reference, timestamp, and confidence score; the graph never silently merges two person records and never writes back to external systems without explicit per-sync approval. All queries use Cypher β no SQL. The database initializes automatically on first use.
## When to use
- Store or update information about a person, relationship, or preference
- Look up who someone is, how they relate to others, or what they like
- Prepare for a meeting, dinner, or introduction
- Find who you know in a given city
- Generate gift ideas grounded in known preferences
- Discover serendipity connections between people
- Sync contacts from Google Contacts or Clay
## When not to use
- Web research without a social graph need β use Sift
- OSINT investigations on people β use Scout
- CRM or sales pipeline automation
- Personality profiling without evidence
## Responsibility boundary
Weave owns the private social graph: people, relationships, preferences, and shared experiences.
Weave does not own: general world knowledge (Elephas/Chronicle), OSINT research (Scout), web research (Sift), task management (Triage).
Weave is a standalone database. It does not write to Chronicle and has no runtime dependency on Chronicle. If a person in Weave also exists in Chronicle, Chronicle may store a `weave:person_id` reference on its Entity node. That is Chronicle's concern, not Weave's.
## Storage layout
```
~/openclaw/db/ocas-weave/
weave.lbug β LadybugDB database (auto-created on first use)
config.json β connector and sync configuration
staging/ β temporary import/export files
~/openclaw/journals/ocas-weave/
YYYY-MM-DD/
{run_id}.json β one journal per run
```
Default config.json:
```json
{
"skill_id": "ocas-weave",
"skill_version": "2.3.0",
"config_version": "1",
"created_at": "",
"updated_at": "",
"writeback": {
"google_contacts": false,
"clay": false
},
"last_sync": {
"google_contacts": null,
"clay": null
},
"retention": {
"days": 0
}
}
```
## Database rules
LadybugDB is an embedded single-file database. One `READ_WRITE` process at a time. If another process holds the lock, operations fail immediately with a lock error β do not retry silently, surface the error.
Multiple `READ_ONLY` connections are safe simultaneously. `COPY FROM` is for bulk import (>100 rows). `MERGE` is for sporadic single-record upserts. Never loop `MERGE` over bulk data.
## Auto-initialization
Every command that opens the database runs `_ensure_init()` first. No manual init command is needed on first use.
Read `references/init_pattern.md` for the `_open_db` implementation pattern. Full DDL is in `references/schemas.md`.
## Commands
**weave.upsert.person** -- Add or update a person. Auto-inits DB on first call. MERGE on `id`. Read back after write; report failure if no row returned β never claim success unconfirmed.
**weave.upsert.relationship** -- Add or update a `Knows` edge. Confirm both Person nodes exist first. Halt and report which is missing.
**weave.upsert.preference** -- Store a provenance-backed preference. Each preference is a distinct `CREATE` (not merged). Link to Person via `HasPreference` edge.
**weave.import.csv** -- Bulk import contacts via `COPY FROM`. Read `references/import_export.md`. Pre-process CSV to staging dir first. Check `CALL show_warnings() RETURN *` after. Report: N imported, N skipped (with reasons), N failed.
**weave.query** -- Query the graph. Read `references/query_patterns.md`. Modes: `lookup`, `connection`, `serendipity`, `city`, `summarize`, `gift`. Return only stored facts with provenance. Never speculate.
**weave.attach** -- Query an external skill database read-only. Read `references/cross_db.md`.
**weave.export** -- Export data to staging dir via `COPY TO`. Read `references/import_export.md`.
**weave.sync.google-contacts** -- Bidirectional sync with Google Contacts. Read `references/connectors.md`. Inbound before outbound. Outbound requires `writeback.google_contacts: true` AND explicit per-sync approval.
**weave.sync.clay** -- Bidirectional sync with Clay. Read `references/connectors.md`. Clay is enrichment source β Weave provenance wins conflicts. Outbound requires `writeback.clay: true` AND explicit approval.
**weave.project.vcard** -- Generate vCard 4.0 draft. Read `references/vcard_projection.md`. Omit fields with confidence below 0.7. Label DRAFT. Requires explicit approval before writeback.
**weave.writeback.contacts** -- Push records to Google Contacts or Clay. Disabled by default. Requires config enablement AND per-action user approval.
**weave.init** -- Diagnostic and repair command. Checks schema, creates missing tables, verifies indexes. Use when troubleshooting, not as a prerequisite β the database initializes automatically on first use.
**weave.status** -- Report graph health and config state.
```cypher
CALL show_tables() RETURN *;
MATCH (p:Person) RETURN count(p) AS people;
MATCH ()-[r:Knows]->() RETURN count(r) AS relationships;
MATCH (pref:Preference) RETURN count(pref) AS preferences;
CALL show_warnings() RETURN *;
```
**weave.journal** -- Write journal for the current run. Read `references/journal.md`. Called at end of every run. Journals are immutable after write.
**weave.update** -- Pull latest skill package from GitHub source. Preserves journals and data.
## Run completion
After every Weave command that reads or writes data:
1. Persist any new or updated records to the database
2. Log material decisions to `decisions.jsonl`
3. Write journal via `weave.journal` β Observation Journal for queries/upserts/imports, Action Journal for syncs/writebacks
## Provenance
Every written fact requires: `source_type` (direct / inferred / imported / user-stated), `source_ref`, `record_time` (ISO 8601), `confidence` (0.0β1.0). Use `event_time` when the real-world occurrence has a distinct time. Never write facts without provenance.
## Constraints
- Never use SQL.
- Never report a write as successful before read-back confirms it.
- Never parse or modify `.lbug`, `.wal`, `.shadow`, or `.tmp` files directly.
- Never write to Chronicle or any other skill's database.
- Never silently collapse two Person records into one.
- Use ontology standard relationship types in `Knows.rel_type`.
- Store useful, durable, socially actionable facts only.
- No outbound sync without explicit per-sync user approval.
- Surface lock errors immediately.
- Write a journal at the end of every run. Runs missing journals are invalid.
## OKRs
Universal OKRs from spec-ocas-journal.md apply. Weave-specific:
```yaml
skill_okrs:
- name: person_record_completeness
metric: fraction of Person nodes with name + (email or phone) + record_time
direction: maximize
target: 0.80
evaluation_window: 30_runs
- name: sync_success_rate
metric: fraction of sync runs with zero failed records
direction: maximize
target: 0.90
evaluation_window: 30_runs
- name: import_skip_rate
metric: fraction of imported rows skipped due to missing required fields
direction: minimize
target: 0.05
evaluation_window: 30_runs
- name: query_provenance_coverage
metric: fraction of returned facts carrying source_ref and record_time
direction: maximize
target: 1.0
evaluation_window: 30_runs
```
## Optional skill cooperation
- Elephas β read Chronicle read-only for entity enrichment (optional, degrades gracefully if absent)
- Scout β receive OSINT findings about people as upsert candidates
- Dispatch β provide social graph context for communication drafting
## Journal outputs
- Observation Journal β query runs, upsert runs, import runs
- Action Journal β sync runs, writeback runs
## Initialization
On first invocation of any Weave command, `_open_db()` handles auto-initialization:
1. Create `~/openclaw/db/ocas-weave/` and subdirectories (`staging/`)
2. Write default `config.json` with ConfigBase fields if absent
3. Create `~/openclaw/journals/ocas-weave/`
4. Open database (auto-creates `weave.lbug` and runs DDL if tables absent)
5. Register cron job `weave:update` if not already present (check `openclaw cron list` first)
6. Log initialization as a DecisionRecord
## Background tasks
| Job name | Mechanism | Schedule | Command |
|---|---|---|---|
| `weave:update` | cron | `0 0 * * *` (midnight daily) | `weave.update` |
```
openclaw cron add --name weave:update --schedule "0 0 * * *" --command "weave.update" --sessionTarget isolated --lightContext true --timezone America/Los_Angeles
```
## Self-update
`weave.update` pulls the latest package from the `source:` URL in this file's frontmatter. Runs silently β no output unless the version changed or an error occurred.
1. Read `source:` from frontmatter β extract `{owner}/{repo}` from URL
2. Read local version from `skill.json`
3. Fetch remote version: `gh api "repos/{owner}/{repo}/contents/skill.json" --jq '.content' | base64 -d | python3 -c "import sys,json;print(json.load(sys.stdin)['version'])"`
4. If remote version equals local version β stop silently
5. Download and install:
```bash
TMPDIR=$(mktemp -d)
gh api "repos/{owner}/{repo}/tarball/main" > "$TMPDIR/archive.tar.gz"
mkdir "$TMPDIR/extracted"
tar xzf "$TMPDIR/archive.tar.gz" -C "$TMPDIR/extracted" --strip-components=1
cp -R "$TMPDIR/extracted/"* ./
rm -rf "$TMPDIR"
```
6. On failure β retry once. If second attempt fails, report the error and stop.
7. Output exactly: `I updated Weave from version {old} to {new}`
## Visibility
public
## Support file map
| File | When to read |
|---|---|
| `references/schemas.md` | Before any DDL, upsert, or import; before weave.init |
| `references/init_pattern.md` | When implementing _open_db or troubleshooting initialization |
| `references/query_patterns.md` | Before any weave.query call |
| `references/import_export.md` | Before any COPY FROM or COPY TO operation |
| `references/cross_db.md` | Before any weave.attach call or Chronicle enrichment query |
| `references/connectors.md` | Before any sync with Google Contacts or Clay |
| `references/vcard_projection.md` | Before weave.project.vcard |
| `references/journal.md` | Before weave.journal; at end of every run |
don't have the plugin yet? install it then click "run inline in claude" again.