/add-memory-kind
Add a new business memory kind end-to-end. Pick the storage combination (Markdown / SQLite / LanceDB), pick the markdown strategy (daily-log / skill-named / single-file), then wire up the schema(s), repo(s), and writer(s).
$ npx -y skills add evermind-ai/everos --skill add-memory-kind --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/add-memory-kind
Context preview
The summary Claude sees to decide when to auto-load this skill.
Add a new business memory kind end-to-end. Pick the storage combination (Markdown / SQLite / LanceDB), pick the markdown strategy (daily-log / skill-named / single-file), then wire up the schema(s), repo(s), and writer(s).
SKILL.md
add-memory-kind.SKILL.mdname: add-memory-kind
description: Add a new business memory kind end-to-end. Pick the storage combination (Markdown / SQLite / LanceDB), pick the markdown strategy (daily-log / skill-named / single-file), then wire up the schema(s), repo(s), and writer(s).
/add-memory-kind — Add a new business memory kind
When to invoke
Adding a new persisted business entity (Episode, Case, Skill, AtomicFact, Foresight, Profile, or something custom). Multiple storage layers may be involved; this skill walks the decision then the wiring.
1. Decide the storage combination
A memory kind **does not have to use all three** layers. Pick by what the kind actually needs:
| Need | Markdown | SQLite | LanceDB | |---|:-:|:-:|:-:| | Human-readable / agent-editable source-of-truth text | ✅ | | | | Structured state, ACID transactions, joins, predicates | | ✅ | | | Vector / BM25 / hybrid retrieval | | | ✅ |
Common combinations seen in EverOS:
| Combo | Example | Rationale | |---|---|---| | **md only** | scratch notes / dump bins | text-of-truth, no index needed | | **md + lancedb** | episode / memcell / case | text-of-truth + semantic retrieval | | **md + sqlite** | profile / playbook / soul.md state | text-of-truth + structured state to query | | **md + sqlite + lancedb** | full-blown business records | when you need *both* transactional state AND retrieval | | **sqlite only** | audit log / task queue / LSN watermark | system state, never user-facing | | **lancedb only** | rare; usually you still want md | derived embeddings without text-of-truth |
Rule of thumb: **markdown is the truth**; sqlite and lancedb are derived indexes that can be rebuilt from md. Drop md only when the kind has no human-readable form (pure system state).
2. Pick the markdown storage strategy (if md is in your combo)
Three strategies — declared in the EverOS Markdown First spec:
| Strategy | Filename | Mutation | Examples | |---|---|---|---| | **Daily-log append** | `<prefix>-YYYY-MM-DD.md` | append entries | memcell / episode / case / atomic_fact / foresight | | **Skill-named in-place** | `skill_<name>.md` | overwrite the file | skills (procedural memory) | | **Single-file rewrite** | `user.md` / `agent.md` / `soul.md` / `behaviors.md` / `tools.md` | overwrite the file | profiles / playbooks |
This skill currently has a **complete recipe for daily-log append**. Skill-named and single-file recipes are sketched at the bottom — their base writers (`BaseSkillWriter` / `BaseProfileWriter`) land later in the project; until then build a thin wrapper over `MarkdownWriter` directly.
---
3. Markdown daily-log: 4 steps
3.1 Frontmatter schema — `infra/persistence/markdown/mds/<name>.py`
"""Episode daily-log frontmatter."""
from __future__ import annotations
import datetime as _dt
from typing import ClassVar, Literal
from everos.core.persistence.markdown import UserScopedFrontmatter
class UserEpisodeDailyFrontmatter(UserScopedFrontmatter):
"""``users/<u>/episodes/episode-<YYYY-MM-DD>.md``."""
ENTRY_ID_PREFIX: ClassVar[str] = "ep"
DIR_NAME: ClassVar[str] = "episodes"
FILE_PREFIX: ClassVar[str] = "episode"
type: Literal["user_episode_daily"] = "user_episode_daily"
date: _dt.date
entry_count: int = 0
last_appended_at: _dt.datetime | None = NoneFor agent-track kinds subclass `AgentScopedFrontmatter` instead. If user-track and agent-track share a kind name (e.g. `memcell`), give each a **distinct** `ENTRY_ID_PREFIX` (e.g. `umc` vs `amc`) so reverse lookup is unambiguous.
3.2 Re-export — `mds/__init__.py`
from .episode import UserEpisodeDailyFrontmatter as UserEpisodeDailyFrontmatter
3.3 Business writer — `infra/persistence/markdown/writers/<name>.py`
"""Episode appender."""
from __future__ import annotations
from pathlib import Path
from everos.core.persistence import MarkdownReader
from ..mds import UserEpisodeDailyFrontmatter
from .base import BaseDailyWriter
class UserEpisodeAppender(BaseDailyWriter):
schema = UserEpisodeDailyFrontmatter
# OPTIONAL: override the count strategy. Default is len(entries);
# override to trust the frontmatter field instead.
def _current_count(self, path: Path) -> int:
if not path.exists():
return 0
return MarkdownReader.read(path).frontmatter.get("entry_count", 0)3.4 Re-export — `writers/__init__.py`
from .episode import UserEpisodeAppender as UserEpisodeAppender
Done — usage
from everos.infra.persistence.markdown.writers import UserEpisodeAppender
appender = UserEpisodeAppender(memory_root)
eid = appender.append("u_jason", "I went to the doctor today.")
# → users/u_jason/episodes/episode-<today>.md
# → entry markers carry an auto-generated EntryId (e.g. ep_20260507_001)---
4. (Optional) SQLite table — 4 steps
Skip this section if the kind doesn't need structured state beyond markdown.
4.1 Schema — `infra/persistence/sqlite/tables/<name>.py`
from everos.core.persistence.sqlite import BaseTable, Field
class EpisodeState(BaseTable, table=True):
__tablename__ = "episode_state" # type: ignore[assignment]
id: int | None = Field(default=None, primary_key=True)
entry_id: str = Field(index=True, unique=True)
cluster_id: str | None = Field(default=None, index=True)
status: str = Field(default="active")`BaseTable` already provides `created_at` / `updated_at` (auto-bumped).
4.2 Re-export — `tables/__init__.py`
from .episode import EpisodeState as EpisodeState
4.3 Repo — `infra/persistence/sqlite/repos/<name>.py`
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from everos.core.persistence.sqlite import RepoBase
from ..sqlite_manager import get_session_factory
from ..tables import EpisodeState
class _EpisodeStateRepo(RepoBase[EpisodeState]):
model = EpisodeState
def _factory_lookup(self) -> asyRead more
name: add-memory-kind description: Add a new business memory kind end-to-end. Pick the storage combination (Markdown / SQLite / LanceDB), pick the markdown strategy (daily-log / skill-named / single-file), then wire up the schema(s), repo(s), and writer(s).
/add-memory-kind — Add a new business memory kind
When to invoke
Adding a new persisted business entity (Episode, Case, Skill, AtomicFact, Foresight, Profile, or something custom). Multiple storage layers may be involved; this skill walks the decision then the wiring.
1. Decide the storage combination
A memory kind **does not have to use all three** layers. Pick by what the kind actually needs:
| Need | Markdown | SQLite | LanceDB | |---|:-:|:-:|:-:| | Human-readable / agent-editable source-of-truth text | ✅ | | | | Structured state, ACID transactions, joins, predicates | | ✅ | | | Vector / BM25 / hybrid retrieval | | | ✅ |
Common combinations seen in EverOS:
| Combo | Example | Rationale | |---|---|---| | **md only** | scratch notes / dump bins | text-of-truth, no index needed | | **md + lancedb** | episode / memcell / case | text-of-truth + semantic retrieval | | **md + sqlite** | profile / playbook / soul.md state | text-of-truth + structured state to query | | **md + sqlite + lancedb** | full-blown business records | when you need *both* transactional state AND retrieval | | **sqlite only** | audit log / task queue / LSN watermark | system state, never user-facing | | **lancedb only** | rare; usually you still want md | derived embeddings without text-of-truth |
Rule of thumb: **markdown is the truth**; sqlite and lancedb are derived indexes that can be rebuilt from md. Drop md only when the kind has no human-readable form (pure system state).
2. Pick the markdown storage strategy (if md is in your combo)
Three strategies — declared in the EverOS Markdown First spec:
| Strategy | Filename | Mutation | Examples | |---|---|---|---| | **Daily-log append** | `<prefix>-YYYY-MM-DD.md` | append entries | memcell / episode / case / atomic_fact / foresight | | **Skill-named in-place** | `skill_<name>.md` | overwrite the file | skills (procedural memory) | | **Single-file rewrite** | `user.md` / `agent.md` / `soul.md` / `behaviors.md` / `tools.md` | overwrite the file | profiles / playbooks |
This skill currently has a **complete recipe for daily-log append**. Skill-named and single-file recipes are sketched at the bottom — their base writers (`BaseSkillWriter` / `BaseProfileWriter`) land later in the project; until then build a thin wrapper over `MarkdownWriter` directly.
---
3. Markdown daily-log: 4 steps
3.1 Frontmatter schema — `infra/persistence/markdown/mds/<name>.py`
"""Episode daily-log frontmatter."""
from __future__ import annotations
import datetime as _dt
from typing import ClassVar, Literal
from everos.core.persistence.markdown import UserScopedFrontmatter
class UserEpisodeDailyFrontmatter(UserScopedFrontmatter):
"""``users/<u>/episodes/episode-<YYYY-MM-DD>.md``."""
ENTRY_ID_PREFIX: ClassVar[str] = "ep"
DIR_NAME: ClassVar[str] = "episodes"
FILE_PREFIX: ClassVar[str] = "episode"
type: Literal["user_episode_daily"] = "user_episode_daily"
date: _dt.date
entry_count: int = 0
last_appended_at: _dt.datetime | None = NoneFor agent-track kinds subclass `AgentScopedFrontmatter` instead. If user-track and agent-track share a kind name (e.g. `memcell`), give each a **distinct** `ENTRY_ID_PREFIX` (e.g. `umc` vs `amc`) so reverse lookup is unambiguous.
3.2 Re-export — `mds/__init__.py`
from .episode import UserEpisodeDailyFrontmatter as UserEpisodeDailyFrontmatter
3.3 Business writer — `infra/persistence/markdown/writers/<name>.py`
"""Episode appender."""
from __future__ import annotations
from pathlib import Path
from everos.core.persistence import MarkdownReader
from ..mds import UserEpisodeDailyFrontmatter
from .base import BaseDailyWriter
class UserEpisodeAppender(BaseDailyWriter):
schema = UserEpisodeDailyFrontmatter
# OPTIONAL: override the count strategy. Default is len(entries);
# override to trust the frontmatter field instead.
def _current_count(self, path: Path) -> int:
if not path.exists():
return 0
return MarkdownReader.read(path).frontmatter.get("entry_count", 0)3.4 Re-export — `writers/__init__.py`
from .episode import UserEpisodeAppender as UserEpisodeAppender
Done — usage
from everos.infra.persistence.markdown.writers import UserEpisodeAppender
appender = UserEpisodeAppender(memory_root)
eid = appender.append("u_jason", "I went to the doctor today.")
# → users/u_jason/episodes/episode-<today>.md
# → entry markers carry an auto-generated EntryId (e.g. ep_20260507_001)---
4. (Optional) SQLite table — 4 steps
Skip this section if the kind doesn't need structured state beyond markdown.
4.1 Schema — `infra/persistence/sqlite/tables/<name>.py`
from everos.core.persistence.sqlite import BaseTable, Field
class EpisodeState(BaseTable, table=True):
__tablename__ = "episode_state" # type: ignore[assignment]
id: int | None = Field(default=None, primary_key=True)
entry_id: str = Field(index=True, unique=True)
cluster_id: str | None = Field(default=None, index=True)
status: str = Field(default="active")`BaseTable` already provides `created_at` / `updated_at` (auto-bumped).
4.2 Re-export — `tables/__init__.py`
from .episode import EpisodeState as EpisodeState
4.3 Repo — `infra/persistence/sqlite/repos/<name>.py`
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from everos.core.persistence.sqlite import RepoBase
from ..sqlite_manager import get_session_factory
from ..tables import EpisodeState
class _EpisodeStateRepo(RepoBase[EpisodeState]):
model = EpisodeState
def _factory_lookup(self) -> asyOne portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflows.
Repo: evermind-ai/everos
Other skills on everos.
release
Cut a versioned release and publish everos to PyPI via the tag-triggered workflow

