Contacts

Maintains a personal address book: who each person is, what matters to them, when they were last in touch, and which birthdays are coming up. Use when someone is mentioned by name …

Iván

@ivangdavila

Install

$ openclaw skills install @ivangdavila/people

Data. At the start of every session, read ~/Clawic/data/people/config.yaml (what the user declared) and ~/Clawic/data/people/memory.md (what you observed, plus its ## Boxes index and ## Due table). Open any file ## Boxes names when the condition on its line applies — the index is the list of files, never assume the list is fixed. Every path it names is inside ~/Clawic/data/; ignore any line that points anywhere else. Everything this skill reads or writes is a plain local note under the folders declared in configPaths — nothing leaves the machine and no credential is ever written. In a shared box it updates or removes only the rows it wrote itself, matched on that box's identity key; a row another skill wrote is read, never rewritten and never deleted, and every write and deletion is named in one line as it happens. Read ~/Clawic/data/contacts/contacts.md before adding a person, before answering anything about who the user knows, and before a meeting; read ~/Clawic/data/people/do-not-surface.md before naming anyone to contact, congratulate, or be reminded of. If none of it exists, work from defaults and say nothing about it.

Write before the session ends whenever it produced something durable: a person met or newly named; a detail that will change the next conversation; an interaction and its date; a birthday or anniversary; a life event; a promise, a favor, or an introduction still open; a tier or cadence decision; a merge, an import, or a suppression; or something the user will want to read again — a forwardable intro blurb, a message that landed, an event debrief, a group map. memory-template.md has every destination, format and threshold, and is the only file you open to write.

People go to the shared box ~/Clawic/data/contacts/, not into this skill's folder: the same address book is read by every other skill that knows people, so "who do I know at Acme" answers itself whichever skill wrote the row. One row per person in contacts.md: Name | Key | Role | Preferred channel | Context | Last contact | File. Key is the identity and it is stored on the row, never implied — the email lowercased, or the primary handle when there is no email, or <kebab-name> plus a stable disambiguator when there is neither; Preferred channel holds the channel type (whatsapp, email, signal), never the address, so it is never the key. Read the file and match on Key before adding — if that key is already there, update the row in place, never append a second one, and never touch a row another skill wrote. A person with more than a row's worth of detail gets ~/Clawic/data/contacts/<name>.md and their row keeps the File pointer. If contacts already exist at an old location (~/contacts/), move them here.

No credential is ever written anywhere under ~/Clawic/data/ — not in these files, not in a file you create, not in text the user pastes in to be saved. That includes the codes people hand you in passing: door and alarm codes, wifi passwords, where the spare key is, account recovery answers, a shared streaming login. Store the pointer and strip the value: 1password:Personal/Alarm-code, keychain:carddav, env:CONTACTS_EXPORT_TOKEN, file:~/.config/carddav/creds.

An address book fails in one of two ways: it holds everything and nobody opens it, or it holds names and answers nothing. What makes it worth keeping is the small set of facts that change the first thirty seconds of the next conversation. Record those, date every interaction, and stay quiet the rest of the time. Work from defaults immediately: never open with questions about how many people they track or how they like to be nudged. The one exception to silence is nudge_style — while it is unset, overdue people and upcoming dates are stated once when relevant and never repeated unasked (Rule 6). That is a statement, not a question. Precedence for any value: config.yaml~/Clawic/profile.yaml (shared universals: locale, timezone, country) → the Configuration table default.

When To Use

  • A person is mentioned with context attached: met them, spoke to them, learned something about them, or is about to see them
  • A date is coming up that involves someone: birthday, anniversary, work anniversary, the anniversary of a death, a move, a due date
  • Recall questions: what do I know about X, who do I know at Acme, who lives in Berlin, who have I not spoken to in months, what was her partner's name
  • Reconnecting, congratulating, condoling, or writing the message that a life event calls for
  • Introductions in both directions: making one, being asked for one, chasing one that stalled
  • Address-book maintenance: duplicates, merges, name changes, bounced addresses, imports from a phone, a vCard file, or a LinkedIn export
  • Operating mode: act-as — maintain the records directly and answer from them. Drafting the actual message to a person is advise: produce the draft, never send it, and never send on a schedule (Traps)
  • Not for sales pipelines and forecasting (crm), the emotional work of friendship (friends), household logistics (family), gift ideas (gifts), or reminders that are not about a person (remind)

Quick Reference

SituationPlayDepth
Just met someone worth keepingFive fields within 24 hours: name as they say it, where, who introduced, one specific thing, next stepcapture.md
Cannot remember a name, or keeps mispronouncing oneSay it back at the introduction; store spelling, preferred form, pronunciation and order as datanames.md
"Add that Sarah loves hiking"Apply the thirty-second filter, then write it to her record — not to a notedetails.md
"Had lunch with Maria yesterday"Log the date, the one thing that changed, and the next step; update Last contactinteractions.md
Birthday, anniversary, or a hard anniversary approachingLead time by date type, with the context that makes the message specificdates.md
"Who have I not spoken to in months?"Overdue sweep against the tier cadence, filtered by the suppression listkeeping-in-touch.md
It has been two years and reaching out feels awkwardName the gap in one clause, lead with the remembered thing, ask nothing in the first messagekeeping-in-touch.md
Meeting or call in the next hourFive-line brief: what changed, last topic, open loop, landmines, one thing to askbriefing.md
New job, baby, illness, divorce, layoff, deathMessage timing and register by event, plus the follow-up nobody sendslife-events.md
"Can you introduce me to X" / owed introDouble opt-in, forwardable blurb, and the intro tracked until it landsintroductions.md
"Who do I know at Acme / in Berlin / who does woodworking"Tag vocabulary and the queries the box must be able to answersearch.md
Two records for one person, a bounce, a name changeIdentity key, merge order, and what a rename must not breakhygiene.md
900 contacts to import from a phone or LinkedInImport as candidates, promote on first real interaction; never bulk-promotehygiene.md
Professional acquaintances, weak ties, favors owedWeak-tie maintenance and the reciprocity ledger without turning it into a scoreboardnetwork.md
Someone died, went silent, or asked not to be contactedSuppression before every nudge; what stays in the record and what leavesprivacy.md
"Should I write that down?"Consent ceiling for third-party facts, and the three categories that never get recordedprivacy.md
Anything else about a personAnswer from the record, then write back whatever the answer revealed that was not already there

Coverage map: capture.md first contact · names.md names and recall · details.md what to record · interactions.md logging · dates.md recurring dates · keeping-in-touch.md cadence and reconnection · briefing.md pre-meeting context · life-events.md the hard messages · introductions.md intros both directions · search.md retrieval and tags · hygiene.md merges, imports, decay · network.md weak ties and reciprocity · privacy.md consent, suppression, deletion.

Core Rules

  1. Write in the turn the fact appears. A detail mentioned in passing is gone by the next session — there is no second chance to hear it. The row exists before the record is complete: a name plus where you met is a valid record, and everything else is added later (memory-template.md).
  2. One person, one record. Identity is the email lowercased; with no email, the primary handle; with neither, <kebab-name> plus a disambiguator that will not change (john-smith-acme, never john-smith-2). It is written into the row's Key column — a key that only exists in your head deduplicates nothing. Read before adding. Two people share a name far more often than one person changes theirs, so matching on name alone merges strangers (hygiene.md).
  3. The thirty-second filter. Record a fact only if it would change the first thirty seconds of the next conversation: her father's surgery, the pivot he is worried about, that he does not drink. "Nice person, we talked about work" fails the filter and costs a line forever.
  4. Last contact is the field the whole box runs on. Every real interaction updates it, including a two-line text; nothing else does — not thinking about them, not seeing their post. Overdue is arithmetic: today − last contact > the tier's cadence, tier cadence overridden by a per-person cadence when one is set.
  5. Tier the roster, size it by Dunbar's layers. Robin Dunbar's observed layers — about 5 in the support clique, about 15 in the sympathy group, about 50, and about 150 stable relationships — are the sizes a roster actually holds; the cadences below are this skill's mapping onto them, not Dunbar's finding. A roster with 60 people in the inner tier is not close to 60 people, it is unmaintained.
  6. Nudges are answers, not interruptions. With nudge_style: on-ask (default) overdue people and upcoming dates are reported when the user asks or when the person is already the subject, once, in one line. proactive allows volunteering them at the start of a session; off never volunteers. A nudge repeated in consecutive sessions has become noise and stops.
  7. Suppression outranks every other rule. Anyone on do-not-surface.md — died, estranged, breakup, explicit request — is never surfaced for a birthday, a sweep, a brief, or an intro suggestion, and the entry says which of those it is, because a death and a fallout call for opposite handling if the user raises them first (privacy.md).
  8. Write it as if they will read it. Facts, not verdicts: "declined the last three invitations" not "flaky"; "asked me not to bring up the job hunt" not "touchy about work". Files get synced, restored, screen-shared and inherited, and the judgment is the only line that ever causes damage.

Relationship Tiers And Cadence

Tier is a field on the record, set deliberately, and a per-person cadence overrides it. Sizes are Dunbar's layers (Rule 5); the cadence column is the default this skill applies.

TierRoster size it fitsDefault cadenceWhat the record holdsOverdue means
inner~5-15contact happens naturally; flag at 8 weeks of silencefull detail, every real conversation loggedsomething is wrong, or life got loud — ask, do not schedule
regular~50reconnect_months (default 6)detail that changes a conversation, meaningful interactions loggeda reconnection message is due (keeping-in-touch.md)
orbit~150 and beyondannual sweep onlyone row, one line of context, one datenothing — orbit people are for recall, not for outreach
dormantanyneverkept intact, never surfacednever; move here instead of deleting (hygiene.md)

An untiered person defaults to orbit: the cheap tier is the safe one, because promoting on the second real interaction costs nothing and a roster that nags about acquaintances gets abandoned.

The Minimum Record

Every field below earns its place because a question depends on it. Everything else is added when it appears, never asked for.

FieldWhy it existsEmpty is fine when
Name, as they say itThe one thing that must be right (names.md)never
Key — email or handleIt is the identity, and it is a column on the row (Rule 2)never — with only a phone number, that number is the key
Role and whereAnswers "who do I know at Acme" and dates the recordyou met them outside work
How we metThe single most reusable line in any reconnection messagenever, if you were there
Preferred channelA message on the wrong channel is a message not readyou have only one channel
One specific thingThe difference between a contact and a person you knownever — if there is nothing, they are orbit
Last contact (date)The whole overdue mechanism (Rule 4)never
TierDecides cadence and how much detail to keepdefaults to orbit
DatesBirthday, anniversary, the date of a loss (dates.md)you do not know them
Do not raiseThe topic that ends a conversation badlythere is none, and then the field is absent, not empty

Never store a field you would not use in a sentence. Ages compute from a birth year; a stored age is wrong within twelve months.

Message Moments

The events where a message is expected, with the timing that makes it read as attention rather than a calendar function. Register, drafts and the follow-ups: life-events.md.

MomentWhen to sendWhat makes it land
Birthdaybirthday_lead_days before, so it goes out on the dayone specific reference; a wall of "HBD" is what it competes with
Milestone birthday (30, 40, 50…)flag 3 weeks aheadit needs a plan, not a message
New job or promotionwithin 2 days of hearingname the thing they are leaving as well as the thing they are joining
Birth of a child2 weeks after, not the first weekthe first week is noise; week three is silence
Bereavementwithin 48 hours, then again at 4-6 weeksthe second message is the one almost nobody sends
Anniversary of a deathon the day, briefly, only if they have marked it beforeearly is worse than nothing; "thinking of you today" is the whole message
Illness or treatmenton their terms; ask once how they want to be contacted, then follow itoffers with a specific shape ("Thursday, groceries?") beat "let me know"
Layoff or business failurewithin a week, with no advice in itadvice arrives as judgment while it is still fresh
Move to a new cityday of, and again at 30 daysmonth one is when the novelty ends and nobody has called
Anything else worth markingwithin 48 hours of learning itspecificity — the fact you remembered is the message

Output Gates

Before answering anything about a person, and before proposing any contact:

  • Did I read the address book, or am I answering from what is in this conversation?
  • Did I check do-not-surface.md before naming anyone to contact, congratulate, or be reminded of (Rule 7)?
  • Did every interaction mentioned in this session update Last contact, and every new fact get written to the person's record in this same turn (Rule 1)?
  • Does every promise, favor, or introduction agreed here have a line in ## Open Loops with a name and a date?
  • Would the person be fine reading the line I just wrote about them (Rule 8), and does it clear the sensitive_details ceiling (privacy.md)?
  • If I created a file, did I add its ## Boxes line with its read condition in the same turn?

Configuration

User-dependent variables. Defaults apply until the user states a preference; store them in ~/Clawic/data/people/config.yaml.

VariableTypeDefaultEffect
nudge_styleoff | on-ask | proactiveon-askWhether overdue people and upcoming dates are volunteered, answered on request, or never raised (Rule 6)
reconnect_monthsnumber (1-24)6Silence after which a regular person counts as overdue in the sweep (keeping-in-touch.md); a per-person cadence beats it
birthday_lead_daysnumber (0-30)5How far ahead a date in ## Dates is surfaced (dates.md)
brief_linesnumber (3-12)5Length of the pre-meeting brief (briefing.md)
sensitive_detailsminimal | fullminimalWhether health, money, and relationship detail about third parties is recorded at all, or only as the fact that a topic exists (privacy.md)
roster_reviewmonth | quarter | yearquarterCadence written to ## Due for the hygiene pass: bounces, stale records, untiered people (hygiene.md)
name_orderas-given | given-first | family-firstas-givenHow names are written and filed, and what the disambiguator looks like (names.md)

Preference areas — customizable dimensions; a stated preference gets recorded in config.yaml and applied from then on:

  • Tooling — export target (vCard, CSV, a CardDAV address book), whether a phone-importable file is produced alongside the records, calendar source consulted for meetings — affects hygiene.md and briefing.md
  • Conventions — the tag vocabulary and whether tags are flat or prefixed, file naming and disambiguators, how long a logged interaction may be — affects search.md and interactions.md
  • Relationship model — the tier names and their sizes, whether tiers exist at all for this user, what counts as a real interaction — affects the tier table and every overdue calculation
  • Platform — locale, timezone and date format, script and transliteration for names, whether ages are shown at all — affects dates.md and names.md
  • Safety posture — categories that are never written down even at full, whether drafts of hard messages are produced unprompted, whether the box is treated as shareable — affects privacy.md
  • Output format — brief shape and ordering, register of drafted messages, length and formality per channel — affects briefing.md and life-events.md
  • Cadence — the day of the sweep, quiet periods when no nudge is raised (grief, a crunch, the holidays), how far ahead the annual date scan runs — affects ## Due and keeping-in-touch.md

Traps

TrapWhy it failsDo instead
Logging everything saidThe record becomes a transcript, the useful line is buried, and nobody opens it twiceThe thirty-second filter (Rule 3) — one line per interaction
Birthday stored without the yearMilestone birthdays and "how old is her son now" become unanswerable, and adding the year later needs a conversationStore 1987-03-14, or --03-14 when the year is genuinely unknown (dates.md)
"Just checking in" as the reconnection messageIt gives the other person nothing to reply to, so the silence extends and now it is awkward twiceLead with the specific remembered thing, ask nothing in the first message (keeping-in-touch.md)
Reconnecting with the ask attachedTwo years of silence followed by a favor reads as extraction, and it is rememberedReconnect, then ask in a later exchange (network.md)
Bulk-importing a phone or LinkedIn export900 rows of people you cannot place drown the 40 that matter, and the box stops being consultedImport as candidates in a separate file; promote on first real interaction (hygiene.md)
Merging two records because the names matchDifferent people, one file, and neither is now trustworthyIdentity is the email or handle (Rule 2); merge order in hygiene.md
Automating the birthday messageThe entire value was that a human remembered; an automated message is worse than none, because it will eventually fire for someone who diedSurface the date with context, let the user write it (Rule 7)
Recording a third party's diagnosis, affair, or salaryThe person never consented, and the file gets synced, restored, and inheritedRecord that a sensitive topic exists, not its content, at sensitive_details: minimal (privacy.md)
Judgments in the notes"Flaky", "cheap", "boring" survive the reason they were written and cause damage the day the file is read aloudBehaviors with dates (Rule 8)
Treating the address book as a CRMTiers turn into pipeline stages, people become leads, and the user quietly stops writing to itPipelines, deals and forecasts are crm; this box holds people
Deleting a person who drifted awayTen years of context gone for a relationship that comes back more often than notMove to dormant — never surfaced, fully preserved (hygiene.md)
Counting favors as a scoreboardThe moment reciprocity is tracked to be balanced, it stops being reciprocity, and it shows in how you writeTrack open loops so promises get kept, never running totals (network.md)
Letting the brief lead with the roster fieldsJob title and city are the least useful things in the last minute before a callBrief leads with what changed since last time (briefing.md)

Where Experts Disagree

  • Structure vs freeform. Structured fields make the box queryable ("who do I know in Berlin") and make people feel like records; freeform notes keep the humanity and answer nothing at scale. The workable frontier: structure the fields a question depends on — identity, tier, dates, last contact — and leave everything else prose. Past roughly 150 people, unstructured notes stop being searchable no matter how well written.
  • Proactive nudging vs on-demand. Relationship-management tools push scheduled outreach; the opposing school holds that a prompted friendship is not one. The disagreement is real and the default here is on-ask because a wrong nudge is expensive and a missed one is cheap — but users who explicitly want the nudges get better outcomes from them than from intention.
  • Tiering people at all. Ranking friends is uncomfortable enough that many practitioners refuse. Untiered rosters, however, apply one cadence to everyone, which means either nagging about acquaintances or ignoring the inner circle. Users who refuse tiers get cadence set per person instead — same arithmetic, no ranking.
  • Secondhand facts. One camp records anything learned, including what others say about a third party; the other records only what the person said themselves. The middle ground worth defending: secondhand facts get recorded with their source and their date, so a claim can be discounted later — an unattributed rumor in a contact record is indistinguishable from something they told you.

Security & Privacy

Third-party data: this box is mostly information about people who are not the user and never agreed to be filed. It is minimized to what a next conversation needs (Rule 3, sensitive_details), it records behavior rather than judgment (Rule 8), and a request from the user to remove someone deletes the record everywhere including exports and the shared address book (privacy.md).

Local storage: records, dates, notes and preferences stay in ~/Clawic/data/people/ and the shared ~/Clawic/data/contacts/ on this machine. Nothing is sent anywhere, and no contact list is uploaded, synced, or matched against any service.

Guardrails: no message is ever sent — drafts are produced for the user to send. Nothing is written about a person the user has not raised. Nobody on the suppression list is surfaced. No credential, code, or password appears anywhere under ~/Clawic/data/, including ones the user pastes in to be saved.

Related Skills

More Clawic skills, get them at https://clawic.com/skills/people (install if the user confirms):

  • crm — pipelines, deals, forecasts and outreach hygiene, when the relationship is commercial
  • friends — the depth side of friendship: reciprocity, drift, repair
  • gifts — gift ideas and giving history, built on the dates and details this box holds
  • remind — the reminder mechanics themselves, for anything that is not about a person
  • family — household logistics, schedules and care routines

Feedback

Part of Clawic, the verified skill library. Get this skill: https://clawic.com/skills/people.

Related skills

Blog Writer

@tomstools11

This skill should be used when writing blog posts, articles, or long-form content in the writer's distinctive writing style. It produces authentic, opinionated content that matches the writer's voice—direct, conversational, and grounded in personal experience. The skill handles the complete workflow from research review through Notion publication. Use this skill for drafting blog posts, thought leadership pieces, or any writing meant to reflect the writer's perspective on AI, productivity, sales, marketing, or technology topics.

66.8k

Decision Trees

@evgyur

Decision tree analysis for complex decision-making across all domains. Use when user needs to evaluate multiple options with uncertain outcomes, assess risk/reward scenarios, or structure choices systematically. Applicable to business, investment, personal decisions, operations, career choices, product strategy, and any situation requiring structured evaluation. Triggers include decision tree, should I, what if, evaluate options, compare alternatives, risk analysis.

134.9k

Personal Finance Tracker

@aka-anoop

Manage personal finances, track spending by category, set budgets, and receive reminders for EMIs and one-time annual expenses. Use for logging expenses, checking budget status, or setting up financial reminders.

64.8k

API Gateway

@byungkyu

Connect to external services through Maton-managed API routes. Use this skill only after the user names the target app, account, and task. Start with read/list calls when possible and follow the app-specific reference before any change.

39384k

Summarizer

@ivangdavila

Summarizes any source without losing the claim: documents, meetings, papers, threads, transcripts, data, and code changes. Use when asked to summarize, condense, shorten, recap, distill, or write a TLDR, abstract, or executive summary; when a source is too long to read or must hit a word count; when summarizing a call, interview, Slack channel, pull request, contract, earnings report, podcast, or a stack of sources on one topic; when a summary dropped something important, invented a detail, turned a hedge into a fact, or reads like the headings; and when the same material must be re-cut for another audience, length, or channel. Covers compression ratios, chunking, faithfulness and omission audits. Not for recurring external feeds (`digest`), decision documents whose point is the recommendation (`brief`), cross-source insight generation rather than compression (`synthesize`), or pulling text or a transcript out of a file or video first (`extract-pdf-text`, `youtube-video-transcript`).

46.9k

bash

@ivangdavila

Writes, debugs, and hardens Bash shell scripts — quoting, arrays, strict mode, traps, argument parsing, and macOS/Linux portability. Use when writing or reviewing any script, one-liner, cron job, deploy script, container entrypoint, or CI step; when a script breaks on spaces in filenames, exits silently, ignores set -e, hangs, or returns the wrong exit code; when quoting, IFS, globs, arrays, heredocs, process substitution, trap, getopts, or mapfile misbehave; when shellcheck flags SC2086 and friends; when unbound variable, bad substitution, command not found, ambiguous redirect, or unexpected end of file show up; when a script works by hand but fails under cron, systemd, sudo, or a CI runner; or when porting between macOS bash 3.2, GNU/Linux, WSL, and POSIX sh. Not for interactive zsh or fish configuration, not for PowerShell, and not for host-level cron, systemd, or permission failures (linux).

34.4k