Personal CRM
Personal CRM
A People/ folder that turns into a relationship-tracking system: last-touched dates, follow-up reminders, conversation history.
Convention
Each person gets a note at People/<name>.md:
---
title: "Sarah Chen"
email: sarah@example.com
twitter: "@sarahchen"
relationship: friend # friend | colleague | family | acquaintance | mentor
first-met: 2024-03-15
follow-up-cadence: 90 # days between meaningful touches
tags: [person]
---
# Sarah Chen
## Context
Software engineer at Acme. Met at a conference in 2024.
## Interests
- distributed systems, hiking, ramen
## Conversations
(auto-populated by the trigger)
How automation fits
Triggers and schedules in Lettuce don’t run an AI — they splice a > [!ai] <prompt> directive into a note. Whatever MCP agent you have connected (Claude Desktop/Code) picks the directive up via pending_directives and does the work, proposing edits if it’s connected with a propose-only key. So the CRM “automation” below is really: drop a directive at the right moment, let your agent maintain the People notes. See Vault automation/01 Triggers and Vault automation/02 Schedules for the schemas.
A real limitation to know up front: the only trigger event is file:created — there is no file:saved, and triggers have no predicates (no body-matches / path-matches) or actions (no run-agent / move). So the conversation-logging flow below fires when you create a note, not every time you save one.
Triggers
Build the Conversations log
When you create a new note anywhere in the vault, splice a directive asking the agent to check it for People mentions and log meaningful touches:
# .lettuce/triggers.yml
- when: "file:created:**/*.md"
prompt: |
If this note mentions one or more People/<name>.md, then for each person:
1. Read the surrounding context (a paragraph or two).
2. Decide if it's a "meaningful touch" (a conversation, decision, or
shared experience) versus a passing mention.
3. If meaningful, propose adding a bullet to People/<name>.md under
`## Conversations`: `- <today's date>: <one-line summary>. See [[this note]].`
Skip trivial mentions ("I sent Sarah a link"). Use judgment.
The trigger only fires on creation, so it covers the common case of a fresh daily/meeting note that name-drops people. For notes you edit later, the agent will pick the same work up the next time it sweeps pending_directives, or you can add the > [!ai] line by hand.
Follow-up nudges
A weekly schedule drops a directive into Monday’s daily note asking the agent to surface anyone you’re overdue to contact:
# .lettuce/schedules.yml
- weekly: "Mon 09:00"
target: "Daily/{{date}}.md"
prompt: |
For each note in People/, compare frontmatter.follow-up-cadence (days)
against the date of the last entry under `## Conversations` (or `first-met`
if there are none). For anyone where days-since-last-touch exceeds their
cadence, append under a `## Follow-ups` heading in this note:
`- [ ] Reach out to [[People/<name>]] (last touch: <date>, cadence: N days)`
Create this daily note and the heading if they don't exist. Don't notify —
just populate the note so I see it during my morning routine.
{{date}} in target resolves to the fire date (YYYY-MM-DD), so the directive lands in that Monday’s daily note. The date math (“days since last touch”) happens in the connected agent — the prompt text is spliced verbatim with no templating.
Variants
Birthday reminders
There’s no notification action in the schema — schedules only drop directives — so route a daily reminder into a single note the agent maintains:
- daily: "08:00"
target: "Daily/{{date}}.md"
prompt: |
Look at every People/ note with a `birthday: MM-DD` in frontmatter.
If any match today's MM-DD (or tomorrow's, for advance warning), append a
line under `## Birthdays` here: `- Tomorrow is [[People/<name>]]'s birthday.`
Do nothing if there are no matches.
You’ll see it in your daily note rather than as a macOS alert.
Relationship graph
The vault graph view (View → Graph, filter to tag:person) shows your network. Cluster sizes are signal — who’s in your “frequent” cluster vs. “outer ring”.
Email integration
Drop emails into Inbox/ as email-*.md notes. A trigger fires on creation and asks the agent to thread each into the right person’s ## Conversations:
- when: "file:created:Inbox/email-*.md"
prompt: |
Identify the other party from the From/To frontmatter. If a matching
People/<name>.md exists, propose adding a `## Conversations` entry there
with a one-line summary and a wikilink back to this email note.
Triggers can’t move files (there are no actions), so if you want the email filed under People/<name>/, ask the agent to do the move in the prompt, or move it yourself after reviewing the proposed conversation entry.
Notes from meetings auto-link
If you tag attendees in meeting notes, fire on new notes created in Meetings/:
- when: "file:created:Meetings/**/*.md"
prompt: |
Read the attendees from frontmatter. For each attendee, propose adding to
People/<name>.md under `## Conversations`:
`- <today's date>: <meeting title>. See [[this meeting note]].`
Privacy
The People folder typically contains real names, emails, sometimes personal context. Either:
Don’t publish — the easy default. Notes are only exported when they carry
published: true, so leaving People notes unmarked keeps them out of anylettuce publishsite.Pseudonyms — if you want to write publicly about people without naming them, use first-name-only filenames and strip or anonymise the sensitive content in the note itself before marking it
published: true(there’s no automatic frontmatter-stripping step).
Related
Recipes/09 Weekly review — includes follow-ups