Building a personal corpus
Complete deck · four parts
Own the model of you.
You are already being modeled. This builds that model for you, on your own computer, from your own data, pointed at your own goals.
github.com/TaylorONeal/personal-signature
Free, open, runs on your own computer
Part 1 of four
Own the model of you.
What a personal corpus is, why your own trail is the highest-signal data about you, and what it unlocks once you hold it.
The starting condition
Every platform you touch already keeps a model of you.
SPOTIFY
models your taste
GOOGLE
models your interests
META
models your relationships
AD NETWORKS
stitch fragments into a profile
Those models are good. They are simply not yours.
The core claim
The model of you exists. It is just aimed away from you.
Their objective function is someone else's revenue. They predict what you'll click, what you'll buy, what keeps you scrolling, accurately, and on your behalf only by accident.
Vocabulary
Four words this whole thing rests on.
Your digital trail
Everything the apps you use have quietly written down, messages sent, songs saved, videos watched, links kept, reviews left.
A personal corpus
That trail, downloaded and rewritten into one tidy list you own, every entry the same shape, sorted by date, on your own computer.
"corpus" = a body of collected material · here, one file: corpus.db
Ingesting
The step that does the rewriting: it opens one app's messy export file and adds tidy entries to your list. Run it again whenever there's more.
A signature profile
The written portrait generated from that list: your taste, your interests, how your voice shifts by who you're talking to.
Nothing here needs an account, and nothing gets uploaded. The list lives in one folder on your machine and never leaves it.
The move
This flips who owns it, not how it works.
SAME RAW MATERIAL
What you listen to, watch, save, write, and where you go.
Sitting in data exports you are legally entitled to download.
OPPOSITE SIDE OF THE LINE
One tidy list of your own, on your own computer.
Built for your objective, not someone's ad auction.
Other companies do this to sell to you. There is no reason the same data can't produce better recommendations, real self-knowledge, and a genuine digital voice, for you.
I
The raw material
Why your own trail is the best data there is
What goes in
Your trail is already yours to download.
EmailGmail Sent mbox, API threads
SMS & DMsiMessage, Instagram, Messenger, WhatsApp
ChatGoogle Chat, Google Voice, Slack
BookmarksBrowser HTML export, saved links
Likes & savesSpotify liked, Reddit saved, Goodreads
Watch historyYouTube, Netflix
Published outputX archive, Yelp reviews, blog
PlacesReviews, orders, travel, visits
Anything tabularGeneric csv / jsonl with a column map
You don't need every source. The system is built to work with whatever subset you have, and to tell you, honestly, what's thin.
Many apps, three kinds, one list.
How sources land
iMessage
Google Messages
Gmail
LinkedIn DMs
Instagram DMs
WhatsApp
Calendar
Spotify
YouTube
Bookmarks
Substack
LinkedIn posts
Messages, both waysyour voice, and who you speak to
What you took intaste, attention, where your time went
What you put out publiclyyour public register
Your personal corpus
One entry per thing that happened, every entry the same six fields, sorted by date.
106,230 entries
2016 to today
Start with two apps or twelve. The kind an app belongs to is what decides which part of the portrait it feeds.
Property 01 / 05
Behavioral, not declared.
A questionnaire records what you say you like. Your library, your watch history, and your sent folder record what you actually did.
Revealed preference beats stated preference every time.
STATED
"I mostly listen to jazz."
REVEALED · 4,812 SAVES
Melodic techno, 61% of saves since 2019.
Property 02 / 05
Longitudinal, not a snapshot.
Years of it. That is what lets the system see eras, drift, and how you changed, instead of only where you are today.
how much you sent and saved, month by month
the peaks and the quiet stretches are the findings
Property 03 / 05
In your own words.
Your sent messages and posts are the only large body of text that is unambiguously your voice, in real contexts, to real people, with real stakes.
That is what makes a credible Communication Signature possible at all. Not a style guess: a register map built from lines you actually wrote.
Property 04 / 05
First-party and complete.
Ad networks reconstruct you from fragments seen through tracking. You have the whole thing, from the inside, with ground truth on who each contact is and which words are yours.
THIRD-PARTY VIEW
inferred · partial · probabilistic
YOUR VIEW
ground truth on identity, direction, and thread
You list your own phone numbers, emails, and usernames once. After that the system can tell your words from everyone else's, which is what makes a voice portrait possible at all. saved as identity.json
Property 05 / 05
Unperformed.
The 2 a.m. text, the playlist you'd never share, the search you'd never post. The realest signal is exactly the material that never makes it into a public persona.
Which is also why it stays on your machine. See the privacy section.
The short version
The most valuable training set about you in the world is one you can already download.
This is the toolkit for using it yourself.
II
Flipping the ownership
Same data, opposite owner
The same raw signal forks two ways.
messages you write
music & shows you save
links & places you keep
things you publish
▼ the same behavioral signal ▼
Their model of you
built to predict what you'll buy
Assembled from tracking fragments, held on their servers, tuned against an engagement metric you never see.
ads · nudges · the feed
fragmented · third-party · optimizes theirs
Your personal corpus, on your computer
one tidy list · yours · the complete picture
One normalized table of everything you did, with ground truth on direction, contact, and thread, queryable by you.
Content Profile
Comm. Signature
your apps
complete · first-party · optimizes yours
When the objective is yours
Four things become possible.
01
Recommendations that serve you
Surfaced because they fit your taste, not because they maximize an engagement metric.
02
Insight from outside your own head
How relationships actually trend, how interests shifted over a decade, what you keep returning to.
03
An AI that sounds like you
A drop-in voice block built from real sent messages, so any model writes in your register instead of assistant beige.
04
A foundation for whatever comes next
Any tool you build later can read the list and ask it questions, the personal context a general-purpose AI has no way to get.
Non-negotiable
This only works because it's local.
The whole premise, owning the model instead of renting it from a platform, falls apart the moment the data leaves your machine. No cloud, no telemetry, no exceptions.
III
From history to memory
Structured · auditable · re-runnable
A scattered trail becomes memory you can search.
Four steps, and each one hands the next one nothing but the list. Stop wherever you like, a source you never got never breaks anything downstream.
Acquirerequest exports
→
Collectwatch inbox, download
→
Ingestparse + store
→
Your personal corpusentries · people · sources
What you took insignal_in
Messages, both directionscommunication
What you put out publiclypublished
Content Profile
Communication Signature
anything else you build
Inside the import
Six messy files in, one tidy list out.
WHAT YOU DOWNLOAD
chat.db
a 4 GB SQLite file, 40 tables
instagram/messages/inbox/
1,900 folders of nested JSON
watch-history.html
180 MB of one giant page
liked.csv · Sent.mbox · bookmarks.html
→
ingesting
reads each one
WHAT YOU GET · YOUR PERSONAL CORPUS
One table. One row per thing that happened. Same six columns whether the row is a text message, a saved song, or a restaurant review.
when · what kind · who · which way
the text · where it came from
That sameness is the whole trick: once everything is one shape, a decade of six platforms can be sorted, counted, and searched together.
One text message, before and after ingesting.
BEFORE · how Apple stores it
ROWID: 448201
is_from_me: 1
date: 681455223000000000
handle_id: 3391
text: NULL
attributedBody: <binary blob>
cache_roomnames: NULL
service: iMessage
Apple epoch nanoseconds. Contact behind a join. On modern macOS the text isn't even in the text column.
→
ingesting, using
your list of handles
AFTER · one entry in your corpus
ts: 2022-08-06T23:41:12Z
bucket: communication
source: imessage
direction: sent
contact: Maya (+1512…0144)
body: "still up if you want to…"
external_id: imsg:448201
A real date. A person's name. And a direction, the sender matched one of your own handles, so this line counts as your voice, not someone else's.
Four different apps, one entry shape.
WHAT HAPPENEDWHICH APPWHICH KINDWHICH WAYTHE TEXT
You texted a friendimessagecommunicationsent"still up if you want to…"
You saved a trackspotify_likedsignal_inlikedBen Böhmer · Beyond Beliefs
You bookmarked a linkbookmarkssignal_inbookmarked"SQLite as an application file format"
You posted a reviewyelppublishedposted"Four stars, and only because the…"
Nothing here is clever. It is just consistent, and consistency is what lets one question reach across all four rows at once.
exports/
chat.db iMessage, copied
instagram/ still zipped
linkedin/
Sent.mbox
liked.csv
_manifest.json what you're still waiting on
engine/
schema.sql corpus.py
parsers/ run_ingest.py
query.py coverage.py
identity.json your own numbers and usernames
corpus.db your corpus · never uploaded, never shared
What it looks like in a folder
Three folders and two files.
The archives you downloaded stay exactly as they arrived, they are your backup of last resort. The code reads them; your corpus is the output. Delete it and you can rebuild it in an afternoon.
Nothing else is required. No server, no account, no folder anywhere but this one.
Why one shape matters
Questions no single platform can answer.
JOINS TIME
"What was I listening to during the months I barely texted anyone?"
Needs saves and messages on one timeline. Spotify has half; Apple has the other half.
JOINS PEOPLE
"Which friendships do I start, and which ones only continue?"
Needs direction and gaps per contact across iMessage, Instagram, and WhatsApp at once.
JOINS REGISTER
"How differently do I write to a client than to my sister?"
Needs your sent text from email and texting side by side, labelled by relationship.
Each of these is one question asked once, against one list. That is the whole payoff of tidying first and interpreting second.
Why it can be trusted
Auditable by construction.
Every entry traces back to a fileThe original downloads are kept forever, so your corpus is never the only copy of anything.
Duplicates collapse automaticallyRun the same import twice and nothing doubles, each entry is matched by its id, or by a fingerprint of its contents.
Updates only add what's newEach source remembers the date it last read up to, so refreshing next month takes seconds instead of hours.
Every claim shows its mathA finding names the question it asked and the count it got back, printed beside it. You can re-run it and disagree.
It refuses to quietly lose dataIf a write would shrink your corpus by more than a tenth, it stops and says so rather than overwriting it.
One list, not one per appWhich is why having only some of your sources is normal rather than a broken state.
The coverage check
It tells you what it can't know.
Before writing anything about you, the system counts what it actually has: how many entries, from which apps, covering which years. Every later claim is limited to that.
If your work chat was never exported, it says "not enough to tell" instead of inventing a professional voice for you.
$ python engine/coverage.py
signal_in 24,880 items · 5 sources
communication 78,410 items · 4 sources
published 2,940 items · 2 sources
thin: work register (no work chat)
next best source: Apple Podcasts
The honesty rule
"Not enough signal" is a valid result.
A claim resting on a thin slice gets flagged, never laundered into a finding. State the pattern, show the numbers, give the strongest counter-reading, and name what would kill it.
IV
What the memory unlocks
Self-knowledge · patterns · agents
Unlock 01
Longitudinal self-knowledge.
Identity arccities, time spans, life chapters
Interest evolutionformative layers vs. current
Relationship arcswho leads, how bonds start and end
Register maptexting vs. email vs. public voice
Two portraits from two halves of the same person: the Content Profile is your inputs, the Communication Signature is your outputs. The interesting findings live where they agree, or contradict.
Unlock 02
Cross-source pattern detection.
One source gives you a habit. Several sources, aligned on a timeline, give you a pattern, the kind a stranger could not guess and you cannot see from inside.
Reported as hypotheses about behavior, not verdicts about the person.
INITIATION RATEgap-based session starts, per relationship
SENT : RECEIVEDbalance and length asymmetry by contact type
LATE-NIGHT SHAREwhen candor happens, and with whom
INVERSIONS ACROSS TYPESfriend vs. family vs. partner, the real findings
A profile, generated from the corpus.
Signature-Profile.md
Signature-Profile.md
## Coverage first
9 sources · 106,230 entries · 2016 to today
thin: work register · marked pending, not described
## The one-line read
Publishes in public on a monthly rhythm and reads far more than gets written. 214 Substack essays sit on top of a saving habit running nine to one, kept to published.
## Trends
· Publishing found a monthly cadence in 2022, after two years of bursts
· Reading widened while writing narrowed: 14 recurring domains, 3 recurring topics
· 61% of published essays were first drafted on a Sunday morning
## Relationships
· 3 iMessage threads carry 58% of everything sent
· Reader email gets a reply inside a day, friends inside three
· Group chats get 6-word messages, one-to-one gets 40
## Voice
Long and cadenced in public, clipped and lowercase in iMessage. The essay voice leans on semicolons the texting voice never uses once.
Caveat: no work chat was ever exported, so the professional register stays pending rather than guessed.
Unlock 03 · the companion project
Better agent decisions: Mirror Palace.
Mirror Palace is the cognitive-framework layer, 49 frameworks, ten life domains, six agent archetypes, that teaches an agent how a person works. It needs evidence. personal-corpus is where the evidence comes from.
personal-corpus
What actually happened. Structured, deduped, timestamped, cited.
→
Mirror Palace
What it means. Frameworks, domain status, pattern reads, agent briefings.
github.com/TaylorONeal/mirror-palace
The same question, asked twice.
Without your corpus · with it
YOU ASK"Draft the follow-up to this recruiter."
GENERICPolite, enthusiastic, three exclamation points. Not how you have ever written.
WITH YOUR CORPUSYour working register, drawn from real email and LinkedIn threads: short, ask up front, no exclamation points, because you have sent none in 38,904 messages.
YOU ASK"What should I listen to tonight?"
GENERICThe five most popular albums of the month.
WITH YOUR CORPUSSomething in the lane that owns 61% of your saves, filtered to what you have never played, and it knows Thursday nights are when you reach for longer sets.
YOU ASK"Who am I overdue with?"
GENERICAdvice about the importance of staying in touch.
WITH YOUR CORPUSFour names. Each one a thread you normally answer within a day, quiet for six weeks, and in every case you were the one who used to write first.
None of the right-hand answers require a smarter model. They require the model to have read your list.
Where Mirror Palace picks it up
Evidence on the left. Advice on the right.
WHAT YOUR CORPUS HOLDSREAD ASWHAT IT CHANGES WHEN YOU ASK
38,904 sent messages, labelled by who they went to→your register, per audience→Drafts that sound like you wrote them, tuned to who is reading
Who starts threads, who answers, and how fast→how your bonds actually run→Reach-out suggestions that name the right person at the right time
A decade of saves, watches, and bookmarks→taste, and how it drifted→Media picks in your lane, not the popular lane
Calendar history beside message volume→your real capacity by week→Plans paced to weeks you survived, not weeks you imagined
The same interest surfacing across years and apps→what you keep returning to→Strategy advice that backs the thread you never drop
The middle column is the part Mirror Palace supplies. It cannot invent the left column, which is exactly why the corpus comes first.
Two projects, one cycle.
01 EVIDENCE
corpus.db
Years of behavior, normalized into one local store.
02 READING
profile + analyze
Two portraits, cited patterns, coverage caveats.
03 INTERPRETATION
Mirror Palace
Frameworks turn patterns into decisions and domain status.
04 NEW TRAIL
back to the corpus
Next month's update pulls in what happened since, and the cycle starts over.
Ordinary project memory helps you finish things. This kind helps you see what you keep doing.
Privacy & safety
Six hard rules.
Local onlyThe engine makes no network calls; cloud AI can transmit what it reads. No cloud, no telemetry.
Never your credentialsThe AI drives export UIs up to the auth step and hands password and 2FA to you.
Nothing sensitive in memoryPersonal, relationship, and health detail stays out of cross-session memory.
Back up before bulk runsThe shrink-guard is a seatbelt; a timestamped copy is the real safety net.
Keep your raw exportsThey are the backup of last resort, and the audit trail.
Deep analyses stay filedSensitive write-ups go to a clearly-marked local folder, no names unless you ask.
Getting started · what you need
Three things, and you probably have two.
01 A COMPUTER YOU OWN
Mac, Windows, or Linux with Python
This is where everything lives. Your downloads, your list, your profile. Nothing is hosted, so there is nothing to sign up for.
A decade of messages is a few hundred megabytes. Any laptop is enough.
02 AN AI AGENT THAT CAN CLICK
Claude Code, or any agent with browser control
It reads the five guides in this project and does the tedious parts: navigating each export screen, ticking the right boxes, watching your inbox, running the imports.
Works in a terminal. Browser steps need a browser-control tool connected.
03 YOUR OWN LOGINS
You type the passwords
The agent drives each export screen right up to the sign-in box and then stops and hands the keyboard back to you. Passwords and two-factor codes are always yours.
A hard rule in the guides, not a preference.
Getting started · setup
Clone it, install the guides, name yourself.
Installing adds five guides to your agent: how to request exports, how to collect them, how to import, how to build the portrait, how to go deeper. You then talk to it in plain English.
The only thing you fill in by hand is your own phone numbers, emails, and usernames, so it can tell your words from everyone else's.
# 1. get the project
git clone github.com/TaylorONeal/personal-signature
cd personal-signature
# 2. add the guides to your agent
/plugin marketplace add ./
/plugin install personal-corpus
# 3. say who you are
mkdir -p exports
cp identity.example.json identity.json
# then just ask:
"request my exports"
What the first day actually looks like.
Mostly waiting, briefly working
MINUTE 0
You say "request my exports"The agent asks which apps you use, then opens each export screen in turn. You type the passwords when it pauses.
MINUTE 30
Every request is in, and the local sources are already doneiMessage and your bookmarks need no request, so they can be imported immediately. You can see a first coverage count today.
HOURS LATER
Emails start arriving: "your data is ready"Some apps take minutes, some take a full day. The agent watches your inbox and files each download as it lands, and warns you before a link expires.
DAY 2
You say "import what came in"Each file is read once and turned into tidy entries. Duplicates collapse on their own, so running it twice costs nothing but time.
THEN
You say "build my profile"It counts what it has, tells you what is thin, and writes the portrait. From here on, refreshing a source takes seconds.
You never have to know a command. Every step above is also a plain sentence you can say to the agent.
Keeping it current
Then it stays fresh on its own.
Set the collect step to run daily and it quietly watches for new exports. Imports after the first one only add what is new, so a refresh is seconds rather than hours.
Version 0.1, sixteen apps supported, five guided steps, installable in one command. Free and open source.
# only add what is new
python engine/run_ingest.py imessage exports/chat.db --mode delta
# back up before a big run
cp corpus.db corpus.db.bak-$(date +%F)
# see where you stand
python engine/coverage.py
personal-corpus
Same data, opposite owner.
Your corpus is a foundation, not a finished report. The profile is only the first thing that reads from it.
github.com/TaylorONeal/personal-signature
Free, open source, contributions welcome
Part 2 of four
Two portraits and a substrate.
The Content Profile, the Communication Signature, and the one plain list both are built from.
The whole system
A local toolkit that turns your data exports into a queryable model of you.
OUTPUT 01
Content Profile
What you consume and are into, taste, interests, obsessions.
OUTPUT 02
Communication Signature
How you write and relate, voice, register, relationship dynamics.
OUTPUT 03
corpus.db
The substrate, plain SQLite with full-text search and read helpers.
One person, two lenses, one substrate. Keeping the two portraits distinct is the core design idea.
The shape of the system.
Four stages on a shared local database. Stages communicate only through the store, so any stage runs on whatever the previous one produced.
Acquirerequest exports
→
Collectwatch inbox, download
→
Ingestparse + store
→
corpus.dbitems · contacts · sources
→
your own appsquery.py · skills · yours
EVERY ITEM LANDS IN ONE BUCKET
signal_in
communication
published
Content Profile
from signal_in, plus the topical side of published
Communication Signature
from communication, plus the voice side of published
Design rationale
The hard problems are at the edges, not the middle.
Acquisition is fragile
Every platform's export UI differs, changes, and gates on auth. And it's slow, hours to days, asynchronously.
Synthesis is generative
Profiling and analysis benefit from being separate from ingestion, so they can re-run cheaply and often.
A clean store is stable
So the store becomes the contract, and everything around it stays independent and replaceable.
A user with two sources and a user with fifteen run the same code.
I
The Content Profile
What you consume & are into
What it is
Built from what you take in.
Music you save, videos you watch, articles you bookmark, books you read, restaurants you review, places you travel.
It answers: what are this person's tastes, interests, and obsessions? What do their inputs say about them?
FED BY
The signal_in bucket, plus the topical side of published.
DIRECTIONS RECORDED
liked · played · watched · bookmarked · rated · visited
Content Profile · sources
Eight inputs, any subset.
Spotifyliked songs, playlists
YouTubewatch history, subscriptions
Netflixviewing activity
Bookmarksbrowser HTML export
Yelpreviews, ratings, places
Food & orderstabular exports via csv
Travelbookings, visits, coordinates
Podcastssubscriptions, plays
Goodreads and Reddit CSVs load through the generic csv kind with a column map, no code required.
Content Profile · outputs
Four readings of your inputs.
Taste clustersGenres, moods, and era signature drawn from what you actually saved and replayed.
Interest mapTop domains and keywords from bookmarks and history, the themes you collect.
Places, food, travel footprintCategories from reviews and orders, coordinates where the export carries them.
Evolution over timeHow themes shift across years: formative layers versus what's current.
II
The Communication Signature
How you write & relate
What it is
Built from what you put out to people.
Your messages, emails, posts, and reviews, the text that was written to someone, for a reason.
It answers: what is this person's voice, in each context? Who do they talk to, and how?
FED BY
communication for relationships and private voice; published for public voice.
DIRECTIONS RECORDED
sent · received · posted
Communication Signature · sources
Eleven message and post sources.
iMessage
Gmail (Sent)
Instagram DMs
Facebook Messenger
Google Chat
Google Voice
WhatsApp
Slack
X / Twitter
Yelp reviews
Blog / long-form
+ anything jsonl
Tinted sources are published, they feed the public register and the Content Profile's topics.
Communication Signature · outputs
Three artifacts.
01
Voice block
A drop-in system-prompt block, "Write as <name>", with tics, tells, and do/don't, each trait backed by a verbatim line.
02
Register map
How the voice changes across texting, email, and public writing, sampled per context from your own words.
03
Relationship dynamics
Who initiates, sent-to-received balance, durable versus ended bonds, how they started and how they closed.
voice-signature.md
The voice block.
Paste it into any model's system prompt and the output stops sounding like an assistant. Every trait traces to a real line in the corpus, so it can be checked rather than trusted.
Starting point: python engine/query.py voice-sample
voice-signature.md
## Write as Jordan
Long paragraphs in public, short lines in private. Concrete nouns over abstractions. Open on a scene, never a thesis. No exclamation points anywhere, in ten years.
## Register map
iMessage7 words median · lowercase · "yep" as agreement
email2 paragraphs · leads with the ask · signs off "- J"
Substack1,400 words median · semicolons · closes on a question
work chatpending, never exported
## Tells, with evidence
· opens on a scene → "The bus was late again, which is how I…"
· hedges in private, commits in public → "maybe? idk" vs "This is the part everyone gets wrong."
Every trait cites a real line, drawn from 214 essays and 38,904 sent messages. Paste this into any model's system prompt.
Why two portraits, not one
Inputs and outputs cross-check each other.
The Content Profile is what you take in; the Communication Signature is what you put out. Merged into one portrait, the disagreements disappear, and the disagreements are usually the finding.
III
The substrate
corpus.db · the part you build on
The third output
The personal-context layer generic AI is missing.
Underneath both portraits: one normalized table of everything, with full-text search and ready-made read helpers.
A recommenderreads signal_in
A "what was I into in 2019" agentreads the timeline
A journal summarizerreads communication
A write-as-me drafterreads your sent items
All four read the same local store. The DB lands at corpus.db in the repo root, git-ignored, never committed.
schema.sql
Three tables.
items
The spine. One row per atomic thing: a message, post, like, ride, review. Every row carries a bucket.
bucket · source · direction
ts · external_id · thread_id
title · body · url · rating
lat · lon · meta
contacts
The other parties, deduped by normalized handle, with optional relationship and status labels.
sources
A hint registry. Sources auto-register on first ingest, and hold the per-source timestamp watermark.
One flat items table instead of per-source tables: synthesis stays source-agnostic, and partial coverage becomes a non-event rather than a special case.
The data model maps to the goals
Buckets decide which portrait an item feeds.
BUCKETMEANINGFEEDS
signal_in
Things you consumed, likes, plays, watches, bookmarks, ratings, visits
Content Profile
communication
Messages, both directions
Communication Signature
published
Your public or long-form output, posts, reviews, tweets, blog
Both: voice to the Signature, topics to the Profile
Three buckets is enough to drive the three synthesis dimensions, relationships, voice, interests, and keeps every query simple.
identity.json
Identity is what makes direction knowable.
If a message's sender matches one of your handles, the item is out / sent / posted. Otherwise it's in / received.
Without it there is no voice block and no sent-to-received ratio. It is the first thing you fill in.
$ cp identity.example.json identity.json
{
"name": "Your Name",
"emails": ["you@gmail.com"],
"phones": ["+15125550100"],
"handles": ["yourhandle"]
}
Idempotency
Re-ingest is always safe.
PRIMARYexternal_idUsed whenever the platform provides one.
FALLBACKcontent hashHash of source, direction, ts, contact, and the first 300 characters of the body.
CROSS-SOURCEcollapse duplicatesAn SMS that also appears in Google Voice collapses on direction, contact, and normalized body within a time window.
Run it twice, run it wrong, run it again next month, the counts stay honest.
The same text message, arriving twice.
An SMS shows up in the iMessage database and again in the Google Voice export. Two files, two formats, one event.
exports/chat.db
sent · +15125550144 · 23:41:12
"heading out in ten"
exports/linkedin/Calls/…html
Me to (512) 555-0144 · 11:41 PM
"Heading out in ten."
MATCH ON
direction
normalized contact
normalized body
time window
↓
ONE ROW KEPT
imessage · sent · Maya · 2026-08-14T23:41:12Z · "heading out in ten"
Without this, every sent-to-received ratio in the profile would be quietly wrong, inflated by whichever platform you happened to export twice.
--mode delta
Two modes: build it, then keep it fresh.
Initial runs parse everything and lean on dedup. Delta runs scan the supplied export and skip known IDs, retaining late arrivals and equal timestamps.
Both modes deduplicate records; keep the same identity and account settings.
# initial, parse everything
run_ingest.py imessage exports/chat.db
# ongoing, only what's new
run_ingest.py imessage exports/chat.db --mode delta
Back up first: cp corpus.db corpus.db.bak-$(date +%F-%H%M)
engine/query.py
Five read helpers, straight out of the box.
query.py statscounts by bucket and source, plus the date range
query.py top-contactswho you talk to most, with sent-to-received balance
query.py voice-sampleyour own words, per register, for a voice block
query.py interestswhat you point attention at
query.py search "…"full-text search across everything
Coverage: what you have, and what's thin.
engine/coverage.py
$ python engine/coverage.py
BUCKETITEMSSOURCESRANGE
signal_in24,88052016-04 → 2026-08
communication78,41042016-01 → 2026-08
published2,94022018-09 → 2026-08
strong public voice · 214 long-form pieces
thin work register · no work-chat export
thin places & travel · no source ingested
watermarks imessage 2026-08-14 · substack 2026-08-11
Shown after every ingest, and read first by profile and analyze, it is the contract between what exists and what may be claimed.
IV
Sources & extension
Seventeen CLI kinds, one contract
Supported sources: communication.
Feeds the Signature
SOURCEKINDWHAT IT CONTRIBUTES
iMessage (chat.db)imessageprivate voice, closest bonds
Gmail (Sent mbox)mboxlong-form written register
Gmail (API threads JSON)gmailjsonthreaded email, both directions
Instagram DMsinstagramcasual register, newer bonds
Facebook Messengerfacebookolder eras, lapsed contacts
Google Chat / Hangoutsgooglechatwork-adjacent register
Google VoicegooglevoiceSMS overlap, dedupe against iMessage
WhatsApp (chat export)whatsappinternational and travel contacts
WhatsApp (iPhone backup)whatsapp_iosfull history from ChatStorage.sqlite
Slackslackprofessional register
Supported sources: signal in and published.
Feeds the Content Profile
SOURCEKINDBUCKETGOAL
YouTube watch historyyoutubesignal_inContent Profile
Netflixnetflixsignal_inContent Profile
Spotify likedcsvsignal_inContent Profile
Browser bookmarksbookmarkssignal_inContent Profile
X / Twitter archivetwitterpublishedBoth
Yelp reviewsyelppublishedBoth
Blog / long-formmbox · jsonlpublishedBoth
Anything tabularcsv · jsonlanyDepends on the map
The generic kinds take --source, --bucket, --direction, and a --map of column names, so most tabular exports work without writing code.
The extension surface
Adding a source is one generator.
A parser yields plain dicts. Three fields are required; the rest are optional but useful. Hand the generator to Corpus.ingest() and dedup, watermarks, and coverage come along for free.
TikTok or LinkedIn is one function, not a subsystem.
# required
bucket · source · direction
# optional but useful
ts (ISO-8601) · ts_raw · external_id
contact {name, handle} · thread_id
title · body · url · rating
lat · lon · meta {…}
Corpus.ingest(source, items, dedupe_against=[…])
A design guarantee
Partial coverage is a non-event.
With Instagram DMs and bookmarks alone you can still produce a real profile, you simply scope the claims. Missing a source narrows the reading; it never breaks the pipeline.
Privacy & safety
The guarantees that make it usable.
Local engine, no telemetrycorpus.db is git-ignored and never leaves the machine. No examples pipe corpus contents anywhere.
Auth stays with youPasswords, 2FA codes, and payment info are never entered by the AI. Hard rule, not a preference.
Outputs stay filedProfiles and deep analyses live in a clearly-marked local folder, out of cross-session memory.
Loud failures, guarded writesA bad working copy fails immediately, and sync refuses to shrink the store below 90%.
Status & roadmap
v0.1, and what's next.
Engine, five skills, sixteen source parsers, smoke-tested
A first-class Reddit parser (GDPR CSVs already load generically)
corpus-merge, unify one contact across platforms
A richer Content Profile module
DOWNSTREAM
Mirror Palace
The cognitive-framework layer that reasons over this evidence: 49 frameworks, ten life domains, six agent archetypes. personal-corpus supplies what happened; Mirror Palace supplies what it means.
github.com/TaylorONeal/mirror-palace
personal-corpus · product overview
One person, two lenses, one substrate.
Start with whatever sources you have. Coverage tells you what to add next.
github.com/TaylorONeal/personal-signature
MIT · installable as a Claude plugin
Part 3 of four
The five-stage playbook.
Request, collect, import, profile, analyze. What each step does, and the traps it already knows about.
The pipeline at a glance.
STAGESKILLWHEN TO USE IT
1a. Requestcorpus-acquireThe user wants to pull their data, request exports, or start building a corpus.
1b. Collectcorpus-collectThey ask whether exports are ready, want to collect data, or want a recurring check.
2. Ingestcorpus-ingestExport files are in exports/ and they want to load their data or build the corpus.
3. Profilecorpus-profileThey want a profile, a voice signature, or a summary of what their data says about them.
4. Analyzecorpus-analyzeThey want to go deeper, find patterns, or ask a specific question of their data.
The split that holds the repo together
Skills encode judgment. The engine encodes mechanism.
skills/
Which export settings. Which traps silently bloat an archive. How to analyze honestly. When to stop and ask.
five SKILL.md files · skills.yaml
engine/
One schema, the Corpus ingest library, a parser registry, read helpers, and the coverage module.
schema.sql · corpus.py · parsers/ · run_ingest.py · query.py · coverage.py
Don't put mechanism in skills or judgment in the engine. Skills are thin; the engine is the substance.
How stages talk
Stages communicate only through state on disk.
No skill calls another skill. Each one reads what the previous stage left behind and writes what the next one will need.
Every skill ends with an explicit handoff naming the next one.
exports/_manifest.jsonWritten by acquire, updated by collect: what was requested, what arrived, what's still pending.
exports/<platform>/Raw archives, left zipped, kept forever.
corpus.dbThe contract proper: items, contacts, sources, and per-source watermarks.
identity.jsonRead by every parser to decide direction.
1a
corpus-acquire
Get the data out of the platforms
Stage 1a · goal
Get your data onto disk, small and parseable.
PRECONDITION 01exports/ existsOne folder per platform, archives left zipped.
PRECONDITION 02identity.json filledCopied from the example, so parsers later know which handles are yours.
PRECONDITION 03Fire everything up frontExports generate asynchronously, minutes to roughly 24 hours.
Each request is recorded in exports/_manifest.json with a rough ETA, so collect knows what to watch for. Partial coverage is fine; the rest of the pipeline adapts.
Google Takeout
Keep products separate.
One giant product otherwise delays every other one. Request Mail, Chat, Voice, and YouTube as separate jobs.
takeout.google.com/settings/takeout
THE TRAPGmail defaults to "Include all messages in Mail", turn it OFF and tick only the Sent label.
YOUTUBEKeep comments, playlists, subscriptions, and history. Drop the video files.
ALSO COVEREDGoogle Chat and Google Voice, each requested on its own.
Instagram & Facebook Messenger
The customize screen has multiple sections, each with its own "Clear all".
01Clear every section, not just the first
02Select Messages only
03JSON format, All time
04Lower media quality
Miss one section and the archive arrives tens of gigabytes larger, days later, mostly media you will never parse.
Per-source playbook
Four more requests, plus the local copies.
PLATFORMHOWETA
X / TwitterFull archive from Settings, one archive per handle~24 hours
RedditGDPR export at reddit.com/settings/data-request, CSVs of posts, comments, savedhours
SlackWorkspace export if you're an admin, otherwise per-DMvaries
SpotifyFastest via exportify, instant CSV of liked songs and playlistsinstant
Local sourcesCopy iMessage's chat.db and a browser-bookmarks HTML export straight into exports/no request
Hard rule · never relaxed
The AI drives the UI up to the auth step and hands off.
It never enters your password, your 2FA code, or your payment information. Nothing in the repo documents or automates anything that would.
1b
corpus-collect
Turn "requested" into "on disk"
Stage 1b · goal
The bridge, and the stage that keeps running.
It scans the connected mailbox for export-ready notifications so you don't babysit your inbox, then files each archive where the parsers expect it.
Requires an email connector. Best run on a schedule, daily is right for most people.
01Scan the mailbox for export-ready mail
02Surface what's ready: platform, date, download link
03Verify the link domain matches the platform
04Download with your confirmation, file it, update the manifest
05Offer to run ingest right away, in delta mode where the source already exists
What it watches for.
PLATFORMSENDERSUBJECT PATTERN
Googlenoreply-dmrc@google.com"Your Google data is ready"
Metasecurity@facebookmail.com"Your information is ready to download"
Xx.com"Your X data is ready"
Redditreddit.com"Your Reddit data request"
Spotify · Slackplatform domains"your data" / "export"
Email links are treated as untrusted input: the sender domain and the link domain both have to match the platform, or the skill stops and asks.
Filing convention
One folder per platform, archives left zipped.
exports/instagram/
exports/linkedin/
exports/twitter/
exports/_manifest.json
TIME PRESSUREDownload links typically lapse in about four days. The skill flags that urgently.
SCHEDULED RUNSReport only new arrivals, stay silent on no-ops, and nudge about anything past its ETA.
BOUNDARIESRead-only on email: never send, delete, or change settings. Every download is confirmed by filename, source, and size.
2
corpus-ingest
Detect · ingest · report
Step 1, detect: file to parser kind.
engine/run_ingest.py
chat.dbimessage
Sent.mboxmbox
Gmail threads JSONgmailjson
instagram/instagram
messenger/facebook
data/tweets.jstwitter
Google Chat/googlechat
Voice/Calls/*.htmlgooglevoice
_chat.txtwhatsapp
ChatStorage.sqlitewhatsapp_ios
slack export/slack
bookmarks *.htmlbookmarks
watch-history.htmlyoutube
netflix exportnetflix
yelp exportyelp
anything tabularcsv · jsonl
The dispatcher in run_ingest.py is the single source of truth for kinds and flags, docs are verified against the code, never against other docs.
Step 2, ingest: one command per source.
A typical first run
python engine/run_ingest.py imessage exports/chat.db
python engine/run_ingest.py mbox exports/Sent.mbox --me you@gmail.com
python engine/run_ingest.py instagram exports/instagram --me "Your Name"
python engine/run_ingest.py googlechat exports/"Google Chat" --me you@gmail.com
python engine/run_ingest.py googlevoice exports/google_voice --dedupe-against imessage
python engine/run_ingest.py youtube exports/…/watch-history.html
python engine/run_ingest.py csv exports/liked.csv --source spotify_liked \
--bucket signal_in --direction liked --map "title=Track Name,ts=Added At"
Operational invariants · learned the hard way
Six rules that don't get relaxed.
Never let a silent copy failure precede a writeThe working-copy step fails loudly, and sync refuses to shrink the store below 90%.
SQLite needs a real filesystemOn FUSE or network mounts, work on a local copy in CORPUS_WORK, ext4, not tmpfs, and sync bytes back.
Stream large archivesExtract only the parse-relevant entries: message JSON, not media.
Open chat.db immutablysqlite3 file:chat.db?immutable=1, and decode attributedBody on modern macOS.
Coverage-firstcoverage.py is the contract between what exists and what you may claim.
Back up before every bulk runcp corpus.db corpus.db.bak-$(date +%F-%H%M). Keep raw exports forever.
Step 3, report: coverage after every ingest.
python engine/coverage.py
$ python engine/run_ingest.py googlevoice exports/google_voice --mode delta --dedupe-against imessage
parsed 1,204 items · new 118 · deduped 1,086 (912 cross-source vs imessage)
watermark googlevoice → 2026-08-15T22:04:11Z
$ python engine/coverage.py
BUCKETITEMSSRCRANGE
signal_in24,88052016-04 → 2026-08
communication78,52852016-01 → 2026-08
published2,94022018-09 → 2026-08
thin work register · places & travel
next best source apple podcasts
What's in the corpus, which dimensions are thin, and which source would add the most next.
3
corpus-profile
Fast, repeatable, coverage-aware
Stage 3 · outputs
It writes two files.
Signature-Profile.md
A one-page profile: a one-line read, who-they-are-in-the-data, trends, relationships, a voice summary, and coverage caveats up top.
Non-obvious findings are marked explicitly.
voice-signature.md
A drop-in system-prompt block, "Write as <name>…", plus a register map, tics and tells, do/don't, and light stats.
Every trait is backed by a verbatim line from the corpus.
Deterministic where possible: every claim traces to a query, not a vibe.
Stage 3 · run order
Coverage first, then five structured pulls.
00CoverageNote thin or missing dimensions up top, so nothing reads as more complete than it is.
01Identity arcCities and time spans, life chapters.
02Volume and trendsv_monthly_volume, peaks and dips by year and bucket.
03Relationshipsv_top_contacts, sent-to-received ratio, who initiates, durable versus ended bonds.
04InterestsTop domains and keywords, genres and mood, review and order categories, watch themes.
05VoicePer-register samples of your own words, starting from query.py voice-sample.
Stage 3 · principles
Five commitments the profile holds.
Coverage-awareWith only IG and bookmarks you still get a real profile, you just scope the claims.
Non-obvious over genericCross-source patterns, not horoscope filler.
HonestA register missing from the corpus is "pending", never fabricated.
PrivateOutputs stay local; nothing personal, relational, or medical enters cross-session memory.
RepeatableRe-run any time new sources land; it notes what changed since the last profile.
4
corpus-analyze
Heavy, generative, cited
Stage 4 · modules
Five deep dives, on demand.
Communication patternsPer-relationship sent:received, initiation rate, length asymmetry, late-night share, response cadence, compared across relationship types.
Relationship dynamicsThe arc of one bond over time: volume, who-leads drift, how it started and how it ended. Patterns only, unless you ask for specifics.
Interest evolutionHow themes shift across years, formative layers versus current.
Timeline / life chaptersCross-source events by period, moves, immersions, gaps, and the rhythm underneath.
Open-ended: non-obviousScan for cross-source agreements and contradictions. Report what a stranger couldn't guess.
The real findingsInversions across types, friend versus family versus partner, are where something actually shows up.
Stage 4 · method
Four steps, every module, no exceptions.
01 COMPUTEDon't intuitWrite the query, get the numbers, cite them inline.
02 COUNTER-READLead with the rivalState the pattern plainly, then give the strongest alternative explanation for the same numbers.
03 CAVEATName the limitsSample size, missing directions or sources, eras not captured. Thin slices are flagged, not laundered.
04 FALSIFYEnd with a testOne concrete experiment or query that would confirm or kill the reading.
Stage 4 · guardrails
Rigor, not flattery, and not diagnosis.
Don't over-pathologizeName patterns clearly, even uncomfortable ones, as hypotheses about behavior, not verdicts about the person.
Separate description from prescriptionWhat the data shows is a different section from what to do about it.
Sensitive analyses stay filedRelationships, health, psychology: a clearly-marked local folder, never cross-session memory.
No names unless you askPattern write-ups carry no specifics or identities by default.
"Not enough signal" is a resultIf the data genuinely can't answer the question, that is the answer.
Every claim cites a querySo a reader can re-run it and disagree with the number, not the mood.
An analysis, as it reads.
Pattern · numbers · counter-read · next step
analysis/communication-patterns.md
## Pattern
Initiation inverts by relationship type: you open 71% of friend threads and 22% of family threads.
## Numbers
friends 71% of 1,204 sessions (n=11)
family 22% of 388 sessions (n=4)
partner 49% of 2,911 sessions (n=1)
sessions = 6h+ gap · v_top_contacts
## Strongest counter-reading
Family may coordinate by phone call, which this corpus does not capture. The same numbers would appear if they simply call first.
## Caveats
n=4 for family. Pre-2016 Messenger not ingested. Reported as a hypothesis about behavior, not a verdict.
## Next step
Ingest Google Voice call logs. If family call-initiation is above 60%, this finding dies.
For contributors
Every skill file has the same shape.
Frontmatter is exactly name plus description: a double-quoted single-line YAML scalar, third person, stating both what the skill does and when to use it, under 1024 characters.
The same information in machine-readable form lives in skills.yaml, which tools can parse directly.
01Pipeline-stage line: "Stage N of the pipeline (acquire → collect → ingest → profile/analyze)"
02A one-sentence goal
03Ordered workflow sections
04Guardrails
05An explicit handoff naming the next skill
!Document both modes: the initial run and the ongoing scan
The stage after stage four
Where the findings go: Mirror Palace.
analyze produces cited patterns. Mirror Palace is the framework layer that reasons over them, turning "this is what happened" into domain status, decision support, and an agent that paces itself to you.
This repoEvidence: exports → corpus.db → two portraits → cited analyses.
→
Mirror PalaceInterpretation: frameworks, life domains, decisions ledger, six agent archetypes.
github.com/TaylorONeal/mirror-palace
personal-corpus · skills walkthrough
acquire → collect → ingest → profile / analyze
Five skills, thin by design. The judgment is written down so it can be argued with.
github.com/TaylorONeal/personal-signature
Contributions welcome · MIT
Part 4 of four
The pitch.
The problem, the wedge, how it sits against the alternatives, and what would move it forward.
The problem
AI got good at remembering your projects. It knows nothing about you.
Every assistant starts each conversation from zero on taste, voice, relationships, and history, so it writes in generic assistant prose and recommends the median thing.
Why it stays that way
The good models of a person are rented, not owned.
TODAY
Platforms hold rich behavioral models of every user. Access is a product decision, the objective is their revenue, and the data is reconstructed from fragments.
A user cannot point them at their own goals.
AVAILABLE, UNUSED
The same raw material sits in the exports every user is legally entitled to download, first-party, complete, and years deep.
Almost nobody uses them, because parsing them is miserable.
The gap is not access to data. It is the absence of tooling between a downloaded archive and something an agent can read.
The wedge
Export rights plus local compute is enough to build the model yourself.
No API deals, no platform permission, no cloud bill. Seventeen CLI kinds, one schema, and a local SQLite file are the entire dependency list.
What exists today
Two portraits and a substrate.
01Content ProfileTaste clusters, interest map, places and travel footprint, and how interests evolved, built from what a person consumes.
02Communication SignatureA drop-in voice block, a register map, and relationship dynamics, built from what they write and to whom.
03corpus.dbPlain SQLite with full-text search and read helpers, the layer any downstream app, agent, or script reads.
Five skills drive it end to end: acquire, collect, ingest, profile, analyze.
Four stages, one contract.
Acquirerequest exports
→
Collectwatch inbox, download
→
Ingestparse + store
→
corpus.dbitems · contacts · sources
THREE BUCKETS, THREE DIMENSIONS
signal_in → interests
communication → voice + relationships
published → both
Content Profile
Communication Signature
Downstream apps & agents
Stages talk only through the store, so a user with two sources and a user with fifteen run identical code.
Why now
Four things converged.
Export rights are universal nowGDPR-style portability made a full personal archive a checkbox at every major platform.
Agents can drive the boring partsRequesting exports, watching an inbox, and filing archives is exactly the work a skill-driven agent can own.
Context is the binding constraintModel quality is no longer the bottleneck in personal assistance; knowing the person is.
Local is finally cheapA decade of one person's messages is a few hundred megabytes of SQLite. It fits on a laptop with room to spare.
Who it's for
Four audiences, in order of urgency.
01Agent buildersAnyone shipping a personal assistant who needs real user context and can't get it from a platform.
02Quantified-self practitionersPeople already logging their lives who have no store that unifies messages with media and places.
03Writers & creatorsThe voice block alone is the deliverable: drafts in their own register instead of assistant prose.
04Privacy-first usersPeople who want the benefit of a personal model and will not upload a decade of messages to get it.
Positioning against the alternatives.
APPROACHWHO OWNS ITOBJECTIVECOVERAGE
Platform recommenderThe platformTheir revenueOne platform's slice
Ad-network profileA brokerAd yieldFragments, inferred
Assistant chat memoryThe vendorSession continuityWhat you typed to it
Note-taking / PKM toolsYouRecall of what you wrote downOnly deliberate input
personal-corpusYou, locallyYoursSixteen sources, years deep, behavioral
The nearest comparable is a personal knowledge base, but PKM captures only what you chose to write down. This captures what you actually did.
Where it stands
v0.1 is shipped and smoke-tested.
16source parsers, from iMessage to Netflix
5skills covering the full pipeline
3tables, the whole data model
0bytes that leave the machine
Engine, skills, and docs are public under MIT, with a plugin manifest so the whole pipeline installs in one step.
What a user sees after the first ingest.
Live demo
$ python engine/coverage.py
signal_in 24,880 · 5 src
communication 78,410 · 4 src
published 2,940 · 2 src
range 2016-01 → 2026-08
thin work register
thin places & travel
next best apple podcasts
every claim downstream is scoped to this
Signature-Profile.md
## One-line read
Publishes monthly on Substack and reads nine times more than gets written. 214 essays on a decade-stable interest spine.
## Relationships
3 iMessage threads carry 58% of everything sent. Reader email answered in a day, friends in three.
## Voice
Long and cadenced on Substack, clipped and lowercase in iMessage. Semicolons in one, none in the other.
Caveat: work register pending, no work chat exported.
Coverage tells you what you have and what's thin. The profile is generated from exactly that, with the caveats stated up top.
Distribution
The skills are the install.
A plugin manifest ships the whole pipeline as one installable unit, so a user goes from "I'd like to own my data" to a fired export request inside a single conversation.
There is nothing to host, no account to create, and no onboarding funnel to maintain.
.claude-plugin/plugin.json and marketplace.json, installable in one step
skills.yamlMachine-readable skill registry other tools can parse
engine/Plain Python with no service dependency, runs anywhere Python does
Defensibility
The schema is easy to copy. The judgment took the time.
Export-UI knowledgeWhich toggle silently bloats an archive by 40GB. Which screen has four separate "Clear all" buttons. This is only learned by getting it wrong.
Operational invariantsImmutable chat.db reads, attributedBody decoding, shrink-guarded writes, no SQLite on network mounts. Each one is a bug someone already paid for.
Honest-analysis methodCite the query, lead with the counter-reading, flag thin slices, end with a falsifiable test. It's what separates a profile from a horoscope.
Encoded as skills rather than code, so it improves by being argued with.
Privacy & safety
Privacy is the architecture, not the policy page.
No hosted engine serviceThere is no backend, no account, and no telemetry. corpus.db is git-ignored and local.
Credentials never touchedThe agent drives export UIs up to the auth step and hands password and 2FA to the user. Hard rule.
Read-only on the mailboxCollect never sends, deletes, or changes settings, and treats every emailed link as untrusted.
Sensitive output stays filedRelationship, health, and psychological analyses live in a marked local folder, out of cross-session memory.
This is also the product argument: the same guarantees are why a user will hand over a decade of messages at all.
Ecosystem
The first consumer is already built: Mirror Palace.
A cognitive-framework toolkit, 49 frameworks, ten life domains, six agent archetypes, that teaches an agent how a person works. It has always needed evidence. This is the evidence layer.
personal-corpusWhat happened, structured, deduped, timestamped, cited.
→
Mirror PalaceWhat it means, pattern reads, domain status, decisions, agent briefings.
github.com/TaylorONeal/mirror-palace
Roadmap
Next, in order.
SHIPPEDEngine, five skills, sixteen parsers, coverage reporting, delta ingest
NEXTA first-class Reddit parser, the GDPR CSVs already load through the generic kind
NEXTcorpus-merge, unify one contact across platforms, which unlocks real relationship analysis
NEXTA richer Content Profile module, taste clustering beyond top-N counting
LATERMore first-class sources, TikTok, LinkedIn, Strava, Kindle, each one function against the Item contract
Risks, and what absorbs them.
RISKMITIGATION
Export UIs change constantlyThe fragile knowledge lives in skills, not code, a UI change is a text edit, and the parsers are downstream of the file format, which moves far more slowly.
Setup friction is realExports take up to a day. Acquire fires them all in parallel and collect watches the inbox, so the wait is unattended rather than abandoned.
Users won't have every sourcePartial coverage is a design guarantee, not a degraded mode. Coverage scopes every claim, and names the next-best source to add.
Self-analysis can go badlyAnalysis is bounded by explicit guardrails: hypotheses not verdicts, counter-readings first, no over-pathologizing, sensitive output kept local.
A platform could ship this nativelyThey can only ship their own slice, aimed at their own objective. Cross-platform and user-owned is the part they structurally cannot do.
The ask
Three things move this forward.
01 PARSERSBring a sourceOne generator against the Item contract adds a platform. The obvious gaps are TikTok, LinkedIn, Strava, and Kindle.
02 FIRST RUNSRun it on your own dataEvery real corpus surfaces an export trap or an encoding edge case that no amount of reading finds.
03 DOWNSTREAMBuild on the substrateA recommender, a journal agent, a write-as-me drafter. The substrate is proved by what reads from it.
personal-corpus
The model of you already exists. Someone should build the one that answers to you.
Local, first-party, MIT, and shipping. Fork it, run it, or point your own agent at it.
github.com/TaylorONeal/personal-signature
github.com/TaylorONeal/mirror-palace