A typed memory layer for always-on agents. One schema, one graph, any Obsidian vault.
🇬🇧 English · 🇷🇺 Русский
An always-on agent writes notes into your Obsidian vault every day — voice transcripts, meetings, ideas, contacts. A month later you have 800 files, broken wiki-links, duplicates, and no one remembers whether status: ongoing is the same as status: active. autograph is the layer that keeps all of that in order automatically.
You describe the taxonomy once in schema.json: what card types exist (note, contact, project, CRM deal), which folder holds which domain, how fast each kind of knowledge decays, which statuses are allowed. From there the engine takes over — it places new files, repairs links, forgets cards you haven't touched for months, merges duplicates, computes a health score. One schema.json is read by Claude Code, OpenClaw, Hermes, Codex — any agent writing to your vault.
📋 Table of contents
Claude Code — marketplace or direct
/plugin marketplace add smixs/autograph
/plugin install autograph@autograph
Direct install without registering the marketplace:
/plugin install github:smixs/autograph
Update / uninstall:
/plugin marketplace update autograph
/plugin uninstall autograph
OpenClaw — via .claude-plugin/plugin.json bundle autodetect
git clone https://github.com/smixs/autograph.git ~/dev/autograph
openclaw plugins install ~/dev/autograph
openclaw gateway restartThe skill lands in ~/.openclaw/skills/autograph/ and /autograph:research becomes available globally. For one workspace only, clone into <workspace>/.agents/skills/autograph/.
Hermes (NousResearch) — github source
hermes skills install github:smixs/autograph/skills/autographThe skill lands in ~/.hermes/skills/autograph/. Hermes doesn't support Claude Code slash-commands — commands/research.md is ignored, but the whole workflow lives in the skill, so just invoke the skill by name in chat.
Moving from OpenClaw to Hermes? hermes claw migrate imports autograph to ~/.hermes/skills/openclaw-imports/.
Codex — via symlink
git clone https://github.com/smixs/autograph.git ~/dev/autograph
ln -s ~/dev/autograph/.claude-plugin ~/dev/autograph/.codex-pluginPoint Codex at ~/dev/autograph in your agents config.
# 1. Point at a vault — empty, chaotic, or already populated
/autograph:research /path/to/vault
# 2. Daily health check
uv run skills/autograph/scripts/graph.py health /path/to/vault
# 3. Decay pass: recompute relevance + tier for every card
uv run skills/autograph/scripts/engine.py decay /path/to/vault
# 4. Regenerate Map-of-Content indexes
uv run skills/autograph/scripts/moc.py generate /path/to/vaultThe 10-phase bootstrap (discover → generate → swarm → enforce → cleanup → tag → dedup → link → MOC → verify) is in skills/autograph/references/bootstrap-workflow.md.
| Scenario | Commands | Why |
|---|---|---|
| Audit someone else's vault | discover.py → graph.py health → graph.py fix --apply |
Understand state before changing anything |
| Bootstrap empty or chaotic vault | /autograph:research <vault> |
Interactive Q&A + explorer agent swarm → schema draft → approval |
| Create a card with guaranteed links | Workflow 3 in SKILL.md: type → path → frontmatter → ## Related (hub + 2 siblings) → engine.py touch |
Orphan cards are dead knowledge — the skill won't close the task until links are in place |
| Import from CRM / external source | engine.py init → enforce.py --apply → enrich.py tags --apply → enrich.py swarm-links --apply |
Exports from HubSpot / Notion / OneNote / Apple Notes become indistinguishable from hand-written cards |
| Spaced repetition of forgotten knowledge | engine.py creative 5 <vault> + cron |
The 5 oldest cards surface back in warm tier for review |
Decay + health at night. Dedup + MOC on Sundays.
OpenClaw cron
openclaw cron add --name "autograph-daily" \
--cron "0 3 * * *" --tz "Europe/Amsterdam" \
--session isolated --tools exec,read \
--message "uv run ~/.openclaw/skills/autograph/scripts/engine.py decay /path/to/vault && uv run ~/.openclaw/skills/autograph/scripts/graph.py health /path/to/vault"
openclaw cron add --name "autograph-weekly" \
--cron "0 4 * * 0" --tz "Europe/Amsterdam" \
--session isolated --tools exec,read \
--message "uv run ~/.openclaw/skills/autograph/scripts/dedup.py /path/to/vault --apply && uv run ~/.openclaw/skills/autograph/scripts/moc.py generate /path/to/vault"Hermes cron
hermes cron create "0 3 * * *" "autograph decay + health on /path/to/vault" --skill autograph
hermes cron create "0 4 * * 0" "autograph dedup + MOC on /path/to/vault" --skill autographJob output: ~/.hermes/cron/output/{job_id}/{ts}.md.
System cron
0 3 * * * cd /path/to/vault && uv run ~/dev/autograph/skills/autograph/scripts/engine.py decay . >/tmp/autograph-decay.log 2>&1
5 3 * * * cd /path/to/vault && uv run ~/dev/autograph/skills/autograph/scripts/graph.py health . >/tmp/autograph-health.log 2>&1
0 4 * * 0 cd /path/to/vault && uv run ~/dev/autograph/skills/autograph/scripts/moc.py generate . >/tmp/autograph-moc.log 2>&1Targets: health ≥ 90, broken_links = 0, description coverage ≥ 80%, stale (>90d) < 20%.
Ebbinghaus-style memory with three mechanisms, all configurable in schema.decay:
1. Access count (spacing effect)
Each touch increments access_count. More retrievals slow forgetting:
strength = 1 + ln(access_count)
effective_rate = base_rate / strength
relevance = max(floor, 1.0 − effective_rate × days_since_access)
A card touched 5 times decays ~2.6× slower than one touched once.
2. Domain-specific rates
| Type | Rate | Half-life | Rationale |
|---|---|---|---|
contact |
0.005 | ~100 days | People don't go stale 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 deadlines |
daily |
0.020 | ~25 days | Daily notes lose relevance fast |
| default | 0.015 | ~33 days | Fallback for everything else |
3. Graduated recall
A touch promotes one tier at a time: archive → cold → warm → active. last_accessed is set to the midpoint of the interval — so without a re-touch the card naturally drifts back down.
autograph/
├── .claude-plugin/
│ ├── plugin.json # Manifest (Claude Code, OpenClaw)
│ └── marketplace.json # Marketplace entry
├── commands/research.md # /autograph:research slash command
├── skills/autograph/
│ ├── SKILL.md # Skill instructions for the model
│ ├── schema.example.json # Generic starting template
│ ├── references/ # Bootstrap workflow, card templates, schema docs
│ ├── scripts/ # 14 engine scripts (stdlib only)
│ ├── tests/ # 220 self-contained tests
│ └── evals/evals.json # Skill-creator eval cases
└── LICENSE
Engine scripts — 14 total
| Script | Purpose |
|---|---|
common.py |
FM parser, walk, domain inference, decay formula |
discover.py |
Phase 1: scan vault, enum candidates |
generate_schema.py |
Phase 2A: discovery → draft schema |
swarm_prepare.py |
Phase 2B: bin-pack vault into agent batches |
swarm_reduce.py |
Phase 2B: consolidate + validate schema |
research.py |
/research helper: gate + manifests + reduce |
enforce.py |
Phase 4: validate + auto-fix against schema |
link_cleanup.py |
Phase 5: remove phantom wikilinks |
enrich.py |
Phase 6/8: tags + catalog-based swarm-links via LLM |
dedup.py |
Phase 7: safe merge + .trash/ |
graph.py |
Health score, repair, backlinks, orphans |
moc.py |
Map-of-Content generation |
engine.py |
Decay, touch, creative recall, stats, init |
daily.py |
Entity extraction from daily/memory files |
Requirements: Python 3.11+, uv, Obsidian-style vault (folder of .md with YAML frontmatter). Optional: OPENROUTER_API_KEY for enrich.py. No pip install needed — stdlib only.
Tests:
cd skills/autograph && uv run tests/test_autograph.pyGrew out of smixs/agent-second-brain — a Telegram-first "second brain" bot that classified voice transcripts into an Obsidian vault with a 9pm daily report. The decay engine, vault-health scoring, and graph tools turned out to be the part every agent needed, not just that one bot. autograph extracts them into a shared memory layer for any runtime.
Made with care in Tashkent · MIT License · Issues