| name | memory |
| description | Persistent memory writes — USER.md (behavioral) and the knowledge graph (facts). |
| always_include | true |
| cli | true |
You have two persistent memory targets for each user:
- USER.md — behavioral instructions: how I should act, communication style, defaults, persistent preferences. Loaded automatically into your prompt as the "User memory" section.
- Knowledge graph — entity-relationship triples for facts: temporal events (date-stamped) and stable factual claims (identity, family, biography, medical). Loaded automatically as the "Known facts" section.
Reading is automatic. You never need to cat USER.md or query the KG before writing. Write through the CLI commands below — never echo >>.
Classify before writing
Before storing anything in memory, decide which of these branches it falls into:
Temporal event — something happened, a decision was made, an item was acquired or disposed of, status changed. Cue: you would naturally write (noted YYYY-MM-DD) or "on YYYY-MM-DD" next to it. Verbs: ordered, bought, returned, decided, started, stopped, moved, joined, left, became, finished. → Use istota-skill memory_search add-fact with --from YYYY-MM-DD.
Stable factual claim — a property of the user that is true regardless of date: identity, family, biography, languages spoken, places lived, employer, role. For medical: allergies and named chronic/serious conditions (allergic_to shellfish, has_condition type_1_diabetes) belong here. Quantitative health data does NOT — see "Health data" below. Cue: a noun phrase about the person, not a verb-headed instruction. Even without a date, these belong in the knowledge graph. → Use istota-skill memory_search add-fact (no --from).
Behavioral instruction — how I should act, communication style, defaults, persistent preferences for my own behavior. Cue: it would still be true a year from now without re-confirmation, AND it tells me what to do. Phrasings: "always", "never", "default to", "prefer", "treat X as Y", "draft as", "send as". → Use istota-skill memory append.
Reusable task procedure — "here is the multi-step way to do task X" distilled from a successful run (which skills/CLIs, in what order, with what gotchas). Cue: it's a how-to, not a fact about the user or a behavioral default. These are learned playbooks, stored as markdown files under playbooks/ and recalled by relevance. In v1 they are generated only by the nightly sleep cycle from successful multi-step task trajectories — there is no runtime playbooks add write yet, so this branch is informational. Do not try to hand-write a playbook mid-task.
Both (rare) — write the behavioral rule to USER.md AND store the triggering event as a fact. Example: the user tells you they've switched to a new email client and from now on prefers shorter replies. The preference is behavioral; the switch event is a fact.
Don't store — anything already on the calendar / in files; transient state ("meeting tomorrow"); information about other users; sensitive data (passwords, tokens, financial account numbers); quantitative health data (see below).
Health data. The health skill owns body stats, biomarkers, and labs in a separate per-user DB. Never write any of the following to USER.md, the knowledge graph, dated memories, or KV: numerical measurements (weight, BP, HR, body temp, SpO2, body-fat %), biomarker / lab values, medication doses or schedules, dates of specific labs or procedures, current symptoms or transient illnesses. When another skill needs a current value, it should call istota-skill health latest or health trend NAME, not memorize it. What stays in the KG: allergies (allergic_to), named chronic conditions (has_condition), and the existence of major surgical history at the diagnosis level — identity-shaped facts that affect general reasoning, not measurements.
Calendar owns dates for scheduled events. Never write a KG fact that carries the date of an appointment, meeting, or other calendar-managed event. The calendar is the single source of truth for when things happen — duplicating the date in a KG fact creates two independent stores that can (and do) disagree, with nothing to break the tie. Date-less metadata about a scheduled event is fine: has_scheduled_procedure mri, has_medical_workup "riverside clinic, 4hr fast". On these facts, --from = when we learned the fact, never the event date. If the event date is the only thing worth recording, write nothing — the calendar already has it.
Writing facts
istota-skill memory_search add-fact alice acquired "arc desk lamp" --from 2026-05-03
istota-skill memory_search add-fact alice decided "standardize on clamp-mount lamps with warm dimmable bulbs" --from 2026-05-04
istota-skill memory_search add-fact alice disposed_of "arc desk lamp" --from 2026-05-04
istota-skill memory_search add-fact alice allergic_to shellfish
istota-skill memory_search add-fact alice has_family_member "wife: Clara"
istota-skill memory_search add-fact alice speaks portuguese
istota-skill memory_search add-fact alice grew_up_in Lisbon
Predicate guidance. Short, lowercase, snake_case. Prefer the existing vocabulary:
- Single-valued (auto-supersedes the previous value):
works_at, lives_in, has_role, has_status.
- Temporary (coexists with permanent facts):
staying_in, visiting, traveled_to.
- Multi-valued:
acquired, disposed_of, decided, completed, owns, uses_tech, knows, speaks, prefers, allergic_to, has_family_member, interested_in, grew_up_in, born_in, relates_to.
Reverting an acquired fact. When the user gets rid of something they previously acquired, record disposed_of with the same object string. Both facts live side by side; the timeline is reconstructable from --from dates. The fuzzy-dedup engine compares objects only when predicates match, so acquired and disposed_of for the same object will not collide.
Other knowledge-graph commands. istota-skill memory_search invalidate <fact_id> [--ended YYYY-MM-DD] marks a fact as no longer valid. istota-skill memory_search delete-fact <fact_id> hard-deletes a fact. istota-skill memory_search facts --subject alice lists current facts. istota-skill memory_search timeline alice lists the historical record for an entity.
Writing behavioral instructions
istota-skill memory headings
istota-skill memory show --heading "Communication style"
istota-skill memory append --heading "Communication style" --line "Keep replies under 3 sentences with alice's family"
istota-skill memory append --heading "Communication style" --subheading "Email" --line "Plain text, no HTML"
istota-skill memory add-heading --heading "Travel" --line "Default vehicle is the motorcycle — say 'rode' not 'drove'"
istota-skill memory remove --heading "Preferences" --match "morning meetings"
istota-skill memory replace --heading "Preferences" --match "prefers tea" --line "Prefers black coffee"
istota-skill memory remove-heading --heading "Old Project"
Rules:
- The heading must already exist for
append; on heading_missing the CLI returns the list of available headings — pick the closest match or use add-heading.
add-heading is for genuinely new topic areas only. Don't proliferate near-duplicates ("Notes", "Memory", "Stuff").
remove requires a substring unique to one bullet under the heading. The match spans the whole section — top region and any ### subsections. If the substring matches multiple bullets, the CLI returns multiple_matches; narrow the substring. ### subheading lines themselves are never matched.
- To reword a stale bullet, use
replace --match <substr> --line <new text> — one in-place op instead of remove then append. To drop an entire stale section, use remove-heading.
- To append under a
### subsection, pass --subheading "Name" to append. Without it, append targets the section's top region (above the first ###).
Don't bypass the CLI
Never write to USER.md or CHANNEL.md with echo >>, cat >>, tee -a, or direct file edits. Those bypass section routing, dedup, and the audit log, and the nightly bypass detector will flag them as legacy writes. Use istota-skill memory exclusively.
Channel memory
Each Talk room has a CHANNEL.md loaded as the "Channel memory" section of your prompt.
istota-skill memory append --heading "Decisions" --line "Use PostgreSQL" --channel room123
istota-skill memory headings --channel room123
The --channel flag must match the active conversation token. Cross-channel writes are refused.
Channel vs user memory. Channel memory is for things relevant to everyone in the room (project decisions, shared conventions). User memory is for personal preferences and personal context. When unsure, prefer user memory — it won't leak personal context to other room participants.
Bot-managed directory layout
Each user has a bot-managed workspace area:
/Users/{user_id}/
├── {BOT_DIR}/ # Shared collaboration space
│ ├── config/
│ │ ├── USER.md # Persistent memory file (this skill writes here)
│ │ ├── TASKS.md # User's task file
│ │ └── ...
│ ├── exports/ # Files I generate for the user
│ └── ...
├── inbox/ # Files the user wants me to process
├── memories/ # Auto-generated dated memory files (read-only — written by sleep cycle)
├── shared/ # Auto-organized files shared by user
└── scripts/ # Reusable Python scripts
Dated memory files (search-only)
The nightly sleep cycle writes summaries to /Users/{user_id}/memories/YYYY-MM-DD.md. These are NOT auto-loaded — search them on demand:
istota-skill memory_search search "desk lamp" --limit 5
istota-skill memory_search search "Project Alpha" --since 2026-04-01
Do not write to dated memory files directly. They are managed by the sleep cycle.