Skip to main content

autograph

Schema-as-code enforcement for any Obsidian vault. Zero hardcoded domains. Use when creating vault cards, checking vault health, running schema compliance, deduplicating entities, generating MOC indexes, running decay cycles, bootstrapping a vault, fixing wikilinks, finding orphans or backlinks, extracting entities from daily files, or touching/promoting cards. Do NOT use for content generation or non-vault file operations.

Source facts

Repository
smixs/iva
Last source activity
August 14, 2026 at 07:53
Detected SKILL.md language
English
Stars
173
Forks
33

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
7 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
autograph
description
Schema-as-code enforcement for any Obsidian vault. Zero hardcoded domains. Use when creating vault cards, checking vault health, running schema compliance, deduplicating entities, generating MOC indexes, running decay cycles, bootstrapping a vault, fixing wikilinks, finding orphans or backlinks, extracting entities from daily files, or touching/promoting cards. Do NOT use for content generation or non-vault file operations.
# autograph — typed vault engine One schema. One graph. Works on any vault. ## Overview No hardcoded domains, types, or paths. The agent discovers structure from data, builds a schema, then enforces it. All scripts share `common.py`. Zero external dependencies (stdlib only, API calls via urllib). ## Quick Reference: 6 Workflows | Workflow | When to use | Entry point | | ------------------- | ----------------------------------------------------- | ------------------------------------------------------- | | **BOOTSTRAP** | New vault / after import / first setup | `discover.py` → `enforce.py` → `graph.py health` | | **HEALTH** | Daily maintenance / on request | `graph.py health` → fix → moc → decay | | **CREATE / UPDATE** | New knowledge card, or new info about an existing one | `search.py` dedup → ADD/UPDATE/SUPERSEDE → link → touch | | **SEARCH & LINK** | Find info + strengthen connections | Hub → links → target; `graph.py orphans` → connect | | **ORCHESTRATE** | Automated multi-agent workflows (no API keys) | `orchestrate.py health\|bootstrap` | | **DAILY → CARDS** | Turn a day's raw notes into linked cards | `daily.py extract` → dedup-first process → link | --- ## Workflow 1: BOOTSTRAP (raw vault → structured graph) **When to use:** New vault, bulk import, first setup. Run once, then switch to HEALTH. **Full guide:** `references/bootstrap-workflow.md` ### Summary (10 phases) 1. **Discover:** `uv run scripts/autograph/discover.py <vault-dir> --verbose > /tmp/discovery.json` 2. **Generate schema:** Script baseline (`generate_schema.py`) + **agent swarm** (`swarm_prepare.py` → Wave 1 haiku → `swarm_reduce.py` → Wave 2 sonnet). **NEVER skip the swarm.** 3. **Review:** Human approves schema. Never auto-apply. 4. **Bootstrap + Enforce:** `engine.py init` + `enforce.py --apply` 5. **Link cleanup:** `link_cleanup.py --apply` (before enrichment) 6. **Tag enrich:** `enrich.py tags --apply` (via OpenRouter API) 7. **Deduplicate:** `dedup.py --apply` (before link enrichment) 8. **Link enrich:** `enrich.py swarm-links --apply` (**always swarm-links, never links**) 9. **MOC generation:** `moc.py generate` 10. **Verify:** `graph.py health` + `enforce.py` → target 90+/100 ### Critical Rules - **Always run Phase 2B (agent swarm).** Script alone cannot classify unstructured content. - **Always use `swarm-links`**, not `links` (0.3% vs 81.6% match rate). - **Always dry-run first** — run without `--apply` before applying. - **Dedup before link enrich** — prevents links to merged/trashed files. --- ## Workflow 2: HEALTH (daily graph maintenance) **When to use:** Daily upkeep, after edits, or when health score drops. This is the most common workflow. ### Decision Logic ``` 1. Run `graph.py health <vault-dir>` → check score 2. If health < 90 → investigate: a. broken_links > 0 → `graph.py fix <vault-dir> --apply` b. orphans > 5 → connect orphans to hub files (see Workflow 4) c. desc_coverage < 70% → add descriptions to files missing them 3. Run `moc.py generate <vault-dir>` → regenerate indexes 4. Run `engine.py decay <vault-dir>` → recalculate relevance + tiers 5. Run `graph.py health <vault-dir>` → confirm improvement ``` ### Thresholds & Action Triggers | Metric | Good | Action needed | | -------------------- | ---- | --------------------------------------- | | Health score | ≥90 | <90: investigate broken links, orphans | | Broken links | 0 | >0: `graph.py fix --apply` | | Orphan files | <5 | ≥5: connect to hubs (Workflow 4) | | Description coverage | ≥80% | <70%: add descriptions | | Stale cards (>90d) | <20% | >30%: `engine.py creative` to resurface | ### Commands ```bash uv run scripts/autograph/graph.py health <vault-dir> # health check uv run scripts/autograph/graph.py fix <vault-dir> --apply # fix broken links uv run scripts/autograph/moc.py generate <vault-dir> # regenerate MOCs uv run scripts/autograph/engine.py decay <vault-dir> # decay cycle (Ebbinghaus) uv run scripts/autograph/engine.py decay <vault-dir> --dry-run # preview decay changes uv run scripts/autograph/engine.py stats <vault-dir> # tier distribution uv run scripts/autograph/engine.py creative 5 <vault-dir> # resurface forgotten cards ``` --- ## Workflow 3: CREATE / UPDATE (dedup-first, then link) **When to use:** Recording any card, or new information about something the vault may already track. Always look up first, always link immediately — a near-duplicate is the most common mistake; an orphan card is wasted knowledge. ### Step 0: LOOKUP (mandatory — never skip) ```bash uv run scripts/autograph/search.py "<entity / key phrase>" --vault <vault-dir> --json # fallback: grep -ril "<name>" <vault-dir> ``` Pick the operation (full rules: `references/update-in-place.md`): - **ADD** — no existing card → create it (steps 1–5 below). - **NOOP** — already captured, unchanged → stop. - **UPDATE** — same subject, new enrichment → open the card, sharpen `description`, append a dated line under `## Log`, re-`touch`. - **SUPERSEDE** — new fact _contradicts_ the Compiled Truth → rewrite the Compiled Truth (frontmatter field + top of description), move the OLD value to append-only `## History` (`- 2026-06-01: company: TDI Group (held 2026-03→2026-06)`), set `updated:`. Writing through Iva's `write_card`? Pass the displaced fact as `history_entry` — the tool owns that section. Whole card obsolete → `status: superseded` + `superseded_by: [[new-card]]`. Only when the operation is **ADD**, continue: ### Steps (ADD path) 1. **Type:** Pick from schema `node_types` 2. **Path:** Reverse-lookup `domain_inference` to find target folder: ```python # domain_inference maps path→domain. To find folder for domain "crm": for path_prefix, domain in schema['domain_inference'].items(): if domain == 'crm': target_folder = path_prefix # e.g. "work/crm/" break ``` 3. **Frontmatter:** Write description (search snippet, not title repeat), tags (2-5, lowercase, kebab-case), status from type's enum 4. **LINKING PROTOCOL (mandatory):** a. Add `## Related` section with `[[hub]]` file of the domain - Hub = `_index.md` or `MEMORY.md` of that domain b. Find 2-3 sibling cards of same type+domain → add `[[links]]` - `uv run scripts/autograph/graph.py backlinks <vault> <hub>` → find siblings - Or: read vault-graph.json → filter nodes by type+domain c. Run `uv run scripts/autograph/engine.py touch <new-file>` 5. **Verify checklist:** - [ ] Hub linked? - [ ] 2+ related cards found? - [ ] description ≠ title repeat? - [ ] tags: 2-5, lowercase, kebab-case? - [ ] status ∈ schema enum? Templates: `references/card-templates.md` --- ## Workflow 4: SEARCH & LINK (find + strengthen connections) **When to use:** Looking up information in the vault, or strengthening weak areas of the graph. ### Navigation (Hub → Links → Target) 1. **Determine domain** from the topic (work, personal, research, etc. — whatever your schema defines) 2. **Start at hub:** `_index.md` or `MEMORY.md` of that domain 3. **Follow links** — max 2 hops from hub to target 4. **Fallback:** `uv run scripts/autograph/graph.py backlinks <vault> <target>` for reverse links ### Orphan Rescue ```bash uv run scripts/autograph/graph.py orphans <vault-dir> # find orphans # For each orphan: connect to nearest hub or sibling card ``` ### Link Strengthening ```bash # Files with <2 links → enrich OPENROUTER_API_KEY=sk-... uv run scripts/autograph/enrich.py swarm-links <vault-dir> --apply uv run scripts/autograph/graph.py health <vault-dir> # verify improvement ``` --- ## Workflow 5: ORCHESTRATE (automated multi-agent workflows) **When to use:** Instead of running scripts manually. No API keys — the Claude Code agent does all judgment directly. ### Phase 0: Script sequencing ```bash python3 scripts/autograph/orchestrate.py health <vault-dir> # automated health workflow python3 scripts/autograph/orchestrate.py bootstrap <vault-dir> # full bootstrap (one command) ``` `health` runs: graph check > fix broken links > link cleanup > MOC > decay > verify. `bootstrap` runs: enforce > cleanup > tags > dedup > swarm-links > MOC > verify. ### Phases 1-3: Agent judgment (no API keys) The agent (you) does the judgment directly — read prepared data, decide, write results. ```bash # Phase 1: prep dedup clusters for YOUR review python3 scripts/autograph/orchestrate.py dedup-prepare <vault-dir> # -> writes .graph/dedup-review-input.json # -> YOU read clusters, mark approved=true, then: dedup.py --apply-manifest # Phase 2: prep domain catalogs for YOUR link suggestions python3 scripts/autograph/orchestrate.py link-prepare <vault-dir> # -> writes .graph/link-review-input.json # -> YOU read catalogs, suggest links per domain, write batch results # Phase 3: prep graph data for YOUR semantic analysis python3 scripts/autograph/orchestrate.py graph-prepare <vault-dir> # -> writes .graph/graph-analysis-input.json # -> YOU analyze contradictions, missing links, stale hubs, write findings ``` For Phases 1-3: run the prep command, read the output JSON, do the analysis yourself (you ARE the LLM), write results back. Use Agent tool for parallel domain work in Phase 2. --- ## Workflow 6: DAILY → CARDS (day's notes → linked cards) **When to use:** Turning a `daily/YYYY-MM-DD.md` note file into durable cards. Judgment-first — the scripts extract candidates; you classify, dedup, and link. **Full guide:** `references/daily-processor.md` ### Summary (4 phases + idempotency) 1. **CAPTURE:** `daily.py extract <daily-dir> <vault-dir> [date]` (candidates → `.graph/`) + `supersede.py <vault>` (conflict scan). Read schema `node_types`, list noteworthy items + the day's topics. 2. **PROCESS:** per item, run the Workflow 3 Step 0 decision (ADD / UPDATE / SUPERSEDE / NOOP — `references/update-in-place.md`); resolve every `.graph/supersede-candidates.json` entry. 3. **LINK:** apply the Workflow 3 linking protocol (hub + 2 siblings + touch) to each card. 4. **SUMMARIZE (schema-gated):** only if the schema defines a summary type, write a daily-summary card with topics + a MOC down to today's cards and the raw file. No hardcoded DAG. **Idempotency:** append `<!-- autograph-processed: YYYY-MM-DDTHH:MM cards=N -->` to the end of the daily file; on re-run, skip content above the last marker. Never edit existing lines. --- ## Decay Engine (Ebbinghaus) The decay system models memory with three key mechanisms: ### 1. Access count (spacing effect) Each `touch` increments `access_count` in frontmatter. More retrievals = slower forgetting: ``` strength = 1 + ln(access_count) effective_rate = base_rate / strength relevance = max(floor, 1.0 - effective_rate * days_since_access) ``` Example: a card touched 5 times has `strength = 1 + ln(5) ≈ 2.6`, decaying ~2.6x slower than a card touched once. ### 2. Domain-specific rates Different content types decay at different rates. Configure in schema `decay.domain_rates`: | Type | Rate | Half-life (~) | Rationale | | --------- | ----- | ------------- | -------------------------------------- | | contact | 0.005 | 100 days | People don't become irrelevant quickly | | crm | 0.008 | 62 days | Deals have medium lifecycle | | learning | 0.010 | 50 days | Knowledge fades moderately | | project | 0.012 | 42 days | Projects have defined timelines | | daily | 0.020 | 25 days | Daily notes lose relevance fast | | (default) | 0.015 | 33 days | Fallback for unlisted types | ### 3. Graduated recall Touch promotes one tier at a time, not a direct jump to active: ``` archive → cold → warm → active ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub