{"id":50970185,"url":"https://github.com/lowwattlabs/hoard","last_synced_at":"2026-06-19T01:30:54.432Z","repository":{"id":362689951,"uuid":"1260358946","full_name":"lowwattlabs/hoard","owner":"lowwattlabs","description":"🪙 HOARD — Durable agent memory that survives session resets. Structured markdown persistence for OpenClaw agents.","archived":false,"fork":false,"pushed_at":"2026-06-08T23:49:08.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T00:19:37.590Z","etag":null,"topics":["agent-memory","clawhub","markdown","memory","openclaw","persistence","session-state"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lowwattlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T12:10:32.000Z","updated_at":"2026-06-08T23:49:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lowwattlabs/hoard","commit_stats":null,"previous_names":["jchandler187/hoard","lowwattlabs/hoard"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/lowwattlabs/hoard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowwattlabs%2Fhoard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowwattlabs%2Fhoard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowwattlabs%2Fhoard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowwattlabs%2Fhoard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lowwattlabs","download_url":"https://codeload.github.com/lowwattlabs/hoard/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowwattlabs%2Fhoard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34514282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-memory","clawhub","markdown","memory","openclaw","persistence","session-state"],"created_at":"2026-06-19T01:30:53.480Z","updated_at":"2026-06-19T01:30:54.414Z","avatar_url":"https://github.com/lowwattlabs.png","language":null,"funding_links":["https://buymeacoffee.com/lowwattlabs"],"categories":[],"sub_categories":[],"readme":"---\nname: hoard\ndescription: \"Durable agent memory that survives session resets — structured markdown persistence with provenance, auto-expiry, and consolidation for OpenClaw agents.\"\nversion: 2.0.2\nmetadata:\n  openclaw:\n    emoji: \"🪙\"\n    homepage: https://github.com/lowwattlabs/hoard\n    requires:\n      files:\n        - MEMORY.md\n    install:\n      - kind: template\n        files:\n          - MEMORY.md\n          - memory/\n          - HEARTBEAT.md\n---\n\n# 🪙 HOARD — History Organization \u0026 Agent Recall Database\n\n**Your agent forgets everything when the context window closes. HOARD reduces that loss.**\n\nEvery agent on every platform hits the same wall: session state evaporates when the context resets. Idle time gets treated as abandonment. Task queues vanish mid-execution. Verified identity handshakes from a prior thread? Gone. The platform sees a gap in activity and assumes you're done.\n\nHOARD is a structured markdown persistence system for OpenClaw agents. It gives your agent durable memory that survives compaction, restarts, and context window resets — with provenance tracking, automatic expiry, and background consolidation. No vector database required.\n\n\u003e **Note:** The npm package name `hoard` is taken by an unrelated time-series library. Install the scoped package: `npm install @lowwattlabs/hoard`\n\n## The problem\n\nAgents lose state across four failure modes:\n\n1. **Context window compaction** — Long conversations get truncated. Anything not in the current window is gone.\n2. **Session timeout** — Platforms treat idle time as \"abandoned.\" Your agent restarts as a blank slate.\n3. **Process restart** — Gateway restarts, model swaps, crashes — all wipe working memory.\n4. **Memory poisoning** — Compromised tools or prompt injection write adversarial entries that persist across sessions (MPBench arXiv 2606.04329: 50.46% attack success rate on OpenClaw agents).\n\nThe fix isn't more context length. It's writing down what matters before the window closes — and knowing you can trust what you wrote.\n\n## How HOARD works\n\nThree files, three systems, one rule: **if it matters past this session, it goes in MEMORY.md.**\n\n### MEMORY.md — The primary index\n\nA single markdown file injected into every session bootstrap. Terse, datestamped, one line per fact. This is your agent's working memory — not a log, not a diary, a survival kit for the next session.\n\n```markdown\n# MEMORY.md — Persistent Facts\n\n## 2026-06-05 Infrastructure  \u003c!-- src:agent ts:2026-06-05 ttl:90d --\u003e\n- Gateway on 127.0.0.1:18789, loopback only\n- Node-2 (192.168.1.86): online, SSH key restored\n- GWS MCP live, Brave Search live\n\n## 2026-06-04 Project Status  \u003c!-- src:user ts:2026-06-04 --\u003e\n- Frisk v3.1.0 shipped — credential-theft reframe\n- VOID game: phases 1-3 complete, phase 4 building\n\n## People  \u003c!-- src:user ts:2026-01-15 ttl:never --\u003e\n- Jason: E6 ANG, F-16 avionics, deployed through Jul 2026\n- Hilary: wife\n```\n\nRules:\n- **One fact per line.** No paragraphs, no reasoning chains.\n- **Datestamp entry blocks.** Group by date, not by topic — you scan by recency.\n- **Provenance on every block.** HTML comment metadata: `src` (where it came from), `ts` (timestamp), optional `ttl` (expiry). See [Provenance](#provenance).\n- **Link to deep files.** `See memory/housing.md for full details` — don't duplicate.\n- **No transient state.** \"Jason asked about gateway status at 9pm\" doesn't belong here. This is for facts that change how the next session operates.\n\n### memory/*.md — Deep reference files\n\nSidecar markdown files for topics too large for the index. Indexed by `memory_search`, readable by `memory_get`. These survive indefinitely (unless TTL expires — see [Auto-expiry](#auto-expiry-ttl)).\n\n```markdown\n# memory/housing.md  \u003c!-- src:agent ts:2026-06-05 ttl:30d --\u003e\n\n## Search Criteria\n- 4BR, 2+ bath, 1+ acre, $100K-$400K, Wells County\n- Current lease ends Oct 2026\n\n## Known Listings (as of 2026-06-05)\n- 1690 E 250 N, Bluffton — $370K, 4BR/2.5BA, 2.25 acres\n- 715 Aviation Dr, Ossian — $293K, 4BR/2.5BA, 3.75 acres\n```\n\nRules:\n- **One topic per file.** housing.md, financial.md, infrastructure.md — split by domain.\n- **Update, don't append.** Replace stale facts. Don't keep a history of wrong answers.\n- **Provenance on every file.** Same `src`/`ts`/`ttl` metadata as MEMORY.md blocks.\n- **Cross-reference from MEMORY.md.** The index points down; the files don't point up.\n\n### HEARTBEAT.md — Bootstrap context\n\nA lightweight file loaded at session start with current system state. Not durable memory — this is \"where am I right now\" information that refreshes every session.\n\n```markdown\n# HEARTBEAT.md\n- Date: (auto-injected)\n- Gateway: 127.0.0.1:18789\n- Model: ollama-cloud/glm-5.1\n- Node-2: online\n```\n\nThis gives the agent immediate situational awareness without burning context window on rediscovery.\n\n---\n\n## Provenance\n\n**Every memory entry tracks where it came from.** Without provenance, you can't tell a user-stated fact from an agent hallucination from a tool output from a web fetch. That ambiguity is the root cause of memory poisoning (MPBench: 50.46% ASR on OpenClaw agents without provenance).\n\n### Untagged blocks\n\nIf an entry block has no provenance comment, it defaults to `src:agent ts:unknown`. Treat untagged blocks as low-trust — verify before relying on them. During consolidation, flag untagged blocks for review and add provenance metadata when the source is confirmed.\n\n### Provenance format\n\nHTML comment metadata attached to entry blocks and files. Invisible in rendered markdown, machine-readable on parse:\n\n```markdown\n## 2026-06-05 Infrastructure  \u003c!-- src:agent ts:2026-06-05 ttl:90d --\u003e\n```\n\n**Fields:**\n- `src` — Source of the entry. One of: `user` (human told the agent), `agent` (agent inferred or observed), `tool` (tool output), `web` (web fetch), `dig` (subagent intel). **Required.**\n- `ts` — ISO date when the entry was written. **Required.**\n- `ttl` — Time-to-live. How long before this entry should be considered stale. Optional. Values: `30d`, `90d`, `1y`, `never`. Default if omitted: `never` for `src:user`, `90d` for `src:agent`, `30d` for `src:web`/`src:dig`.\n\n### Trust hierarchy\n\nNot all sources are equal. When a memory entry conflicts with new information, trust resolves by source:\n\n1. **`user`** — Highest trust. Human-stated facts override everything. Only a human can demote a `user` entry.\n2. **`agent`** — Agent-observed state (system status, file contents, process output). Trustworthy but can be stale.\n3. **`tool`** — Tool output. Trust the tool, verify the interpretation.\n4. **`web`** — Web fetch. Verify before trusting — Dig's intel is leads, not facts.\n5. **`dig`** — Subagent research. Lowest trust. Always verify before acting on it.\n\nWhen two entries conflict and have the same source, the newer one (`ts`) wins.\n\n### Write-gating\n\n**Agent writes to MEMORY.md are allowed. Tool writes are not.** If a tool needs to persist something, it should return the data to the agent, which then writes it with the correct provenance. This prevents a compromised tool from silently injecting adversarial entries.\n\nFor OpenClaw agents, this is enforced by convention — the agent's write discipline (see below) should never delegate memory writes to tools. A future version could enforce this at the gateway level.\n\n---\n\n## Auto-expiry (TTL)\n\n**Memory rots.** Without expiry, stale facts accumulate and poison future decisions. OpenAI's Dreaming V3 optimizes for \"stay current as time passes.\" HOARD does it with TTL metadata and a consolidation sweep.\n\n### How TTL works\n\nEach entry block (or memory file) carries an optional `ttl` value. When the consolidation process runs (see [Consolidation](#consolidation)), it checks each entry's `ts` + `ttl` against the current date:\n\n| Age vs TTL | Action |\n|-----------|--------|\n| Within TTL | Keep as-is |\n| TTL exceeded by \u003c 2x | Flag: add `⚠️ stale` annotation to the block's provenance comment and surface the entry in the next session's opening context as \"may be stale — verify or remove\" |\n| TTL exceeded by \u003e 2x | Auto-remove (delete the block, offload to `memory/archive/` if the fact might still be useful) |\n\n### Default TTL by source\n\n| Source | Default TTL | Rationale |\n|--------|-----------|-----------|\n| `user` | `never` | Human-stated facts stay until a human removes them |\n| `agent` | `90d` | System state changes; 90 days is conservative |\n| `tool` | `90d` | Tool output ages the same as agent observation |\n| `web` | `30d` | Web info goes stale fast |\n| `dig` | `30d` | Subagent intel is transient by design |\n\nOverride any default by setting `ttl` explicitly on the block: `\u003c!-- src:agent ts:2026-06-05 ttl:1y --\u003e`\n\n### Manual override\n\nAn agent can extend or shorten any entry's TTL by editing the metadata. A `user` entry with `ttl:never` will never auto-expire. An `agent` entry with `ttl:30d` will expire faster than the default.\n\n---\n\n## Consolidation\n\n**Background curation that keeps memory lean and current.** OpenAI's \"dreaming\" process and Mem0's extraction both do this. HOARD does it with a consolidation sweep — a process that runs periodically to compress, deduplicate, and expire stale entries.\n\n### What consolidation does\n\n1. **Expiry sweep** — Check every entry against its TTL. Flag or remove stale entries per the TTL rules above.\n2. **Deduplication** — Find repeated facts across MEMORY.md and memory/*.md. Keep the most recent, remove the rest.\n3. **Compression** — When MEMORY.md exceeds 15KB, offload detail to memory/*.md sidecar files. Keep only the index line in MEMORY.md. Stop offloading when MEMORY.md drops below 12KB (hysteresis prevents thrashing at the boundary).\n4. **Archival** — Expired entries that might still be useful get moved to `memory/archive/` instead of deleted. Archive files are indexed by `memory_search` at low priority — they appear after active memory files in search results, so they're retrievable when needed but don't clutter normal recall.\n\n### When consolidation runs\n\nFor OpenClaw agents, consolidation runs on the heartbeat cycle. The agent checks MEMORY.md size and entry TTL on each heartbeat, and performs cleanup when needed. No separate daemon — the agent does it as part of its normal session lifecycle.\n\nFor non-OpenClaw setups, run consolidation manually or on a cron:\n\n```bash\n# Manual consolidation\npython3 hoard-consolidate --workspace ~/.openclaw/workspace\n\n# Cron: daily at 3 AM\n0 3 * * * python3 /path/to/hoard-consolidate --workspace ~/.openclaw/workspace\n```\n\n### Consolidation safety\n\n- **Never deletes `src:user` entries.** User-stated facts are only removed by users.\n- **Archive before delete.** Any auto-removed entry gets archived to `memory/archive/YYYY-MM-DD.md` before removal.\n- **Dry-run first.** The consolidation script supports `--dry-run` to preview changes without applying them.\n\n---\n\n## The write discipline\n\nThe pattern only works if the agent follows the discipline. Teach your agent:\n\n1. **Write immediately.** When you learn something that changes how future sessions should operate, put it in MEMORY.md right then. Don't wait for \"end of session\" — you don't know when that is. A crash, a timeout, a context window reset can all end your session before you get a chance to write.\n2. **Don't write everything.** MEMORY.md is not a transcript. It's a survival kit. Decisions, IDs, paths, state changes — things the next session needs to know to be useful.\n3. **Don't write reasoning unless the reasoning IS the fact.** \"I considered three options and picked B\" → cut. \"Went with SQLite over Postgres because no Docker on this host\" → keep. If the reason changes future decisions, it's a fact.\n4. **Never store secrets.** No tokens, passwords, or API keys in MEMORY.md or memory/*.md. Reference that they exist and where (e.g., \"API key in ENV\"), never the value.\n5. **Tag provenance on every write.** Add `src`, `ts`, and optionally `ttl` to every entry block. If you don't know the source, tag it `src:agent`. If you're not sure how long it'll be valid, leave `ttl` blank and accept the default for that source. **For critical infrastructure facts observed by the agent (SSH keys, service endpoints, hardware config), explicitly set `ttl:1y` or `ttl:never`** — the 90d default is too short for things that don't change monthly.\n6. **Don't let tools write directly.** If a tool returns data that should persist, write it yourself with the correct provenance. Never delegate memory writes to tools.\n7. **Clean up.** When facts change, update the line. When a project is done, remove its block. When MEMORY.md grows past ~15KB, offload detail to memory/*.md and keep only the index line. Stale memory is worse than no memory. Last-writer-wins on conflicts — datestamp your blocks so it's clear which is newer.\n\n## Memory search\n\nHOARD files are indexed for semantic search. Use `memory_search` to recall facts across MEMORY.md and all memory/*.md files without knowing which file holds what. This lets your agent pull relevant context even when the index doesn't explicitly link to it.\n\n```\nmemory_search(\"housing criteria\")\n→ hits MEMORY.md housing block + memory/housing.md\n```\n\nFor multi-hop queries that span multiple files, run multiple searches with different angles and synthesize the results yourself. `memory_search` retrieves by semantic similarity — it doesn't do joins.\n\n## Wiki vault (optional)\n\nFor accumulated project knowledge that needs structure beyond flat markdown, add a wiki vault. Wiki pages support:\n\n- Frontmatter and metadata (provenance, timestamps, source tracking)\n- Wikilinks between pages\n- Narrow mutations via `wiki_apply` (structured updates without freeform editing)\n- Linting via `wiki_lint` (structural integrity checks)\n\nUse the wiki for: project documentation, entity pages, synthesis notes, anything that benefits from cross-referencing. Use MEMORY.md for: facts the next session needs right now.\n\n## Why not a vector database?\n\nVector databases are the right answer at scale. HOARD is the right answer for a single agent on a single machine:\n\n- **Zero infrastructure beyond your platform.** No separate database server, no index rebuilds, no memory overhead beyond what OpenClaw already provides. `memory_search` and `memory_get` are native OpenClaw tools — they come with the runtime, not with HOARD.\n- **Human-readable.** You can open MEMORY.md and read it. Your agent can read it. A debugger can read it.\n- **Git-friendly.** Track changes, diff sessions, roll back mistakes.\n- **Fast enough.** For a single agent, `memory_search` over a few KB of markdown is milliseconds. Not milliseconds-per-vector, just milliseconds.\n- **Survives everything the filesystem survives.** As long as the files persist, your agent's memory persists. No database corruption, no schema migration — but do back up your filesystem. Files aren't immortal.\n- **Provenance-tracked.** You know where every fact came from and when it was written. Vector databases don't give you this by default.\n- **Auto-expiring.** Stale facts don't accumulate forever. The consolidation sweep keeps memory current.\n\nWhen you're running 10,000 concurrent agents, upgrade to a vector store. When you're running one agent on a homelab, HOARD.\n\n## Security model\n\nMemory poisoning is a real attack vector. MPBench (arXiv 2606.04329) demonstrated 50.46% success rate against OpenClaw agents without provenance. HOARD mitigates this with three layers:\n\n1. **Provenance tracking** — Every entry tagged with its source. `src:tool` and `src:web` entries can be identified and audited. `src:user` entries cannot be auto-removed.\n2. **Write-gating by convention** — Tools don't write directly to MEMORY.md. The agent writes on their behalf with the correct provenance tag. A compromised tool that tries to write adversarial entries would be caught by provenance audit (the entry would show `src:tool` instead of `src:user`, making it suspect).\n3. **TTL-based expiry** — Even if adversarial entries get written, they expire. `src:web` and `src:dig` entries auto-expire in 30 days. `src:agent` entries in 90 days. Only `src:user` entries persist indefinitely.\n\n**Known limitation:** Provenance is enforced by convention, not by the platform. A determined attacker who compromises the agent's write path could forge `src:user` tags. This is a fundamental limitation of file-based memory — the same agent that reads the file can write to it. True write-gating requires platform-level enforcement (future work for OpenClaw).\n\n## Install\n\nHOARD is a pattern with tooling. To adopt it:\n\n1. Create `MEMORY.md` in your agent's workspace root\n2. Add memory sidecar files under `memory/`\n3. Add provenance metadata (`src`, `ts`, optionally `ttl`) to every entry block\n4. Configure your agent's bootstrap to inject MEMORY.md + HEARTBEAT.md at session start\n5. Train your agent on the write discipline (see above)\n6. Run consolidation periodically (heartbeat cycle or cron)\n\nFor OpenClaw agents, steps 1-4 are built in. MEMORY.md is auto-injected on session start, and `memory_search`/`memory_get` are native tools. Add provenance tags and configure consolidation.\n\n## Template\n\nA starter MEMORY.md with provenance examples is included in this skill. Copy it to your workspace root and customize:\n\n```bash\ncp SKILL_DIR/templates/MEMORY.md ~/.openclaw/workspace/MEMORY.md\nmkdir -p ~/.openclaw/workspace/memory\nmkdir -p ~/.openclaw/workspace/memory/archive\n```\n\n## Pricing\n\nFree. If it saves your agent from amnesia, [buy me a coffee](https://buymeacoffee.com/lowwattlabs).\n\n## License\n\nMIT-0 — Low Watt Labs 🪙\n## Also by Low Watt Labs\n\n- **⚡ Frisk** — Catch leaked credentials and supply-chain threats in ClawHub skills before you install. [GitHub](https://github.com/lowwattlabs/frisk) · [npm](https://npmjs.com/package/@lowwattlabs/frisk) · [ClawHub](https://clawhub.ai/lowwattlabs/frisk-audit)\n- **⚡ LFIT** — Local HD image generation on your hardware. Free, private, zero API keys. [GitHub](https://github.com/lowwattlabs/lfit) · [npm](https://npmjs.com/package/@lowwattlabs/lfit) · [ClawHub](https://clawhub.ai/lowwattlabs/vulkan-lfit)\n\n## Related Projects\n\n- **⚡ Frisk** — Catch leaked credentials and supply-chain threats in ClawHub skills before you install. [GitHub](https://github.com/lowwattlabs/frisk) · [npm](https://npmjs.com/package/@lowwattlabs/frisk) · [ClawHub](https://clawhub.ai/lowwattlabs/frisk-audit)\n- **⚡ LFIT** — Local HD image generation on your hardware. Free, private, zero API keys. [GitHub](https://github.com/lowwattlabs/lfit) · [npm](https://npmjs.com/package/@lowwattlabs/lfit) · [ClawHub](https://clawhub.ai/lowwattlabs/vulkan-lfit)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flowwattlabs%2Fhoard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flowwattlabs%2Fhoard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flowwattlabs%2Fhoard/lists"}