FIELD NOTES · AUGUST 2026
How to make a personal AI system that knows you well
Three ways a general-purpose assistant failed me in daily use, the addressing rule I used to fix each one, and what the resulting system actually contains: 72 modules, nine domains, 3,080 files, and 33,788 bytes resident per turn.
01
Where it fell short
I did not start out wanting to build a system. I started out annoyed. Over about a year of using a general-purpose assistant every day — for work, money, health, immigration paperwork — the same three failures kept recurring, and none of them were failures of intelligence. Each one has a mechanism, and in each case the mechanism lives in the harness: the retrieval policy, the routing step, the write path. Those are things you control from outside the weights.
1.1 It remembers the wrong things
Two symptoms, which sound like opposites:
- It volunteered true, irrelevant history. Details from months earlier that had nothing to do with the question would surface mid-answer and drag the conversation toward them.
- It missed the one fact that governed the answer. The constraint that should have changed the recommendation never came up, and nothing indicated that it had been looked for and not found.
Both come from one property: similarity search returns k items and has no way to return zero. If the binding fact is not in the top k, it is silently missed. And because the k slots get filled regardless of whether anything relevant exists, true-but-unrelated material is shipped to fill them. One call, two failure types.
Three properties of an embedding store make this structural rather than a tuning problem:
- There is no primary key, so there is no UPDATE. Write “I live at A,” then later write “I moved to B,” and the store holds two rows, not one corrected row. At read time whichever sits closer to the query wins. Recency is not part of cosine distance unless you build it in yourself, and even then it is a heuristic competing with semantics rather than a fact replacing a stale one.
- Similarity is not bindingness. “This position is locked and cannot be sold” and “I like this stock” are near neighbours in embedding space. One is a hard constraint that invalidates an entire class of answers; the other is a preference. Nothing in the distance function distinguishes a rule from a mood.
- A corpus is not a state store. Retrieval was designed to find passages that discuss a topic. Personal assistance mostly needs the current value of a variable — where I live, what I owe, which document has been filed. That question has an exact answer, and answering it approximately is not a degraded success, it is a wrong answer delivered confidently.
Over-personalization is the accurate name for this. The problem is not that the assistant knows too little about me. It is that it applies what it knows with no test of whether that knowledge governs the question in front of it.
1.2 It answers like the median person
I would ask for help with a workplace situation and get emotional reassurance. Not wrong, exactly — just not the thing I asked for. The model was not missing knowledge about negotiation, organisational behaviour, or how to write a difficult message. It had all of that. There was simply no step anywhere that decided which body of knowledge applies here.
The mechanism is the training objective doing exactly what it should. For a given phrasing, generation lands near the mode of the conditional distribution. Most people who write “my manager did X and I feel Y” want to be comforted, so comfort is the modal continuation. That is the right answer for the population and the wrong answer for the person in front of it.
This matters because it separates cleanly from 1.1, and the two get conflated constantly:
- 1.1 is about facts. The system had the right information and failed to select it.
- 1.2 is about expertise. The system had the right knowledge and failed to select a discipline.
So no amount of additional context about me fixes 1.2. Loading a perfect profile still leaves the assistant answering from the middle of the distribution — now with better details. The fix has to be a selection step that runs before generation, plus something specific for it to select.
1.3 It never gets better
Corrections did not survive. I would explain a preference, catch a recurring mistake, or work out a better way to do something, and weeks later the same mistake would arrive again with the same confidence.
This is two failures stacked, and it is worth separating them because they need different fixes:
- Nothing triggered the reflection. There was no moment in the loop that asked “what should change as a result of this?” Reflection happened when I asked for it, which means it happened rarely and only about things I had already noticed.
- Reflections had nowhere to land. A lesson written into an undifferentiated memory pool is retrieved only if cosine distance happens to favour it later — which puts us back in 1.1. Writing is not learning. A system that produces reflections but cannot guarantee they are read has not learned anything; it has generated text about learning.
There is a third thing underneath both, which took me longest to see: the thing that needs to change is usually a procedure, not a fact. “Check the account balance before proposing a purchase” is not a memory. It is a step in a checklist. If no checklist exists, there is nothing to edit, and the only place the lesson can go is a note that hopes to be retrieved at the right moment.
All three failures above are addressable outside the model, and the rest of this article is how. What stays broken is judgment quality. If the model reasons badly about a negotiation, a better filing system gives you a well-filed bad answer, delivered faster and with citations. Addressing fixes retrieval, routing fixes selection, and write-back fixes accumulation. None of them fix reasoning.
02
Approach
Three fixes, one per failure. They are ordered by dependency: 2.2 is only possible because of 2.1, and 2.3 is only possible because of both.
2.1 Address space and assignment rules
The rule is one sentence: every durable fact has exactly one path, and the path is computed from the fact, not from the query.
Two invariants follow, and they are the whole of what I mean by maintainability:
- What is stored must exist and be unique. Not “probably saved somewhere” — one file, one location, checkable.
- You must always know where to look. Without this, the first invariant is unverifiable. You cannot confirm a fact is stored exactly once if you cannot enumerate where it would be.
One tree, walked twice
The file that defines the address space opens with two lines, which are the load-bearing sentences of the whole design:
Walk this tree before storing a file.
Walk the same tree when looking for one.
Compare the shapes. Similarity retrieval has two different
functions: writing is embed(text) → insert,
reading is embed(query) → top-k. They are not
inverses of each other, and nothing in the system forces them to
agree — which is precisely why a fact can be present and
unreachable. Here there is one function. Storage computes
f(fact); lookup computes f(fact)
again. If lookup fails, exactly two things can be true: the fact
was never stored, or the tree changed since it was. Both are
diagnosable in a way that “the embedding did not rank it
highly today” is not.
The uniqueness assertion
This block sits near the top of the tree file. Translated from the running system, which is written in Chinese:
ASSERT: every durable datum must have exactly one canonical owner.
Classification rules:
1. Classify by the SUBJECT of the information, not by which
workflow happens to use it.
2. User-specific facts and state never go into modules; modules
hold only reusable procedure and general knowledge.
3. The first matching branch of the decision tree is the only
destination. Storing a copy in two places is forbidden.
4. Any other location may hold only:
- a pointer naming the canonical path, or
- a derived projection, marked as rebuildable from the source.
5. Moving information requires updating every reference and
deleting the old copy.
Rule 1 is the one that does the work, and it is the one every naive version of this gets wrong. The instinct is to file by use: the travel workflow needs my passport scan, so put it in the travel module. Then the immigration workflow needs it, and now there are two passport scans, and six months later one of them is the old passport. Filing by subject — this is an identity document, regardless of who consumes it — yields one answer no matter how many workflows show up later.
Rule 3 is what makes the tree a function rather than a set of suggestions. First match wins, so branch order is semantic and deliberate, not cosmetic.
Walking the tree, and why the hops are in that order
The live tree has eight questions. What matters is not the list but why each one sits where it does:
- Is it a credential? Password, token, API key, membership number, login email. First, because it is the hardest boundary in the system: these leave the plaintext tree entirely and go to a separate credential store. Asking first means no later branch can accidentally capture a secret as a side effect of being a good match.
-
Does it belong to an existing project?
Second, because a project is the strongest ownership signal
available — it has a directory, a handoff document, and
a lifecycle. This branch carries its own guard, verbatim:
“It happened because of this project” is not the same as “it is a project file.” Only the project’s own artifacts and state belong here; cross-project personal state — travel, finance, health, identity — still goes to its own canonical owner.
Without that guard the tree degenerates into filing everything under whatever I happened to be doing at the time, which is filing by workflow with extra steps. - Is it long-lived personal information? Then it goes to the record, filed by domain. This is the branch that catches most things.
- Is it someone else’s document? Routed by relationship, not by file type. Another person’s CV is not “a CV”; it is an artifact of a specific relationship or project.
- Is it reusable reference material containing no personal facts? Then it belongs inside a module. This question is the enforcement point for rule 2 above, and it is what keeps modules portable.
- Is it a reusable procedure? Then it is a new module, not a note.
- Is it system configuration?
-
None of the above. Disposable material goes
to a downloads directory. Everything else stops:
if uncertain, you must ask. Do not decide alone. If the user is unavailable, do not store it — wait.
Miss semantics
That eighth branch is the one I would defend hardest, because it is the opposite of what retrieval does. The tree is deliberately partial. A miss is not resolved by descending the nearest plausible branch; it halts and escalates to a human.
Top-k always answers. A tree that is permitted to say “I do not know where this goes” is what stops the address space from quietly filling with misfiled facts. And the asymmetry is severe: a pause costs one question, while a misfiled fact is invisible — you discover it only when you go looking and it is not there, which is usually the moment you needed it.
One fact, two owners
The obvious objection: some facts genuinely belong to two subjects. An apartment floor plan is a housing fact and a furniture-shopping fact. Rule 4 handles it — one copy, several pointers. The tree assigns the single location; the cross-links make it a graph. Real entries from the anti-duplication table:
| Fact | Single location | How everything else refers to it |
|---|---|---|
| CV | record/career/ |
immigration project keeps a pointer file, not a copy |
| Degree certificates | record/education/ |
same pointer file |
| Furniture inventory | record/living/furniture/ |
the resale module stores listing status only, and points back |
| Trip itinerary, PNR, seats | record/travel/trips/<date>-<slug>/ |
calendar entry is a projection, not a second source |
| Card and account numbers | encrypted file under record/finance/ |
everywhere else holds a pointer; security codes are never written |
The database name for the failure this avoids is the update anomaly: when a fact is stored twice, an update that touches one copy leaves the other wrong, and nothing reports the disagreement. Normalization removes it by storing the fact once and referring to it by key. This is the same move with paths as keys.
One distinction took me a while to get right, and it is easy to collide: owners may be several; the copy must be one. Two workflows can both be responsible for keeping a fact current — that is fine and often correct. What cannot happen is two files.
What this costs
The failure mode does not disappear. It changes shape, and the honest comparison is:
- Retrieval fails confidently irrelevant. You get something true and unrelated, and there is no signal distinguishing that from a hit.
- A directory fails confidently stale. The file is exactly where the tree says it is, and its contents are three months old.
Stale is the better failure, but only for one reason: it is enumerable. I can list every file in a domain, sort by modified date, and see what has gone quiet. There is no equivalent listing for “what does my embedding index currently believe about where I live.” The cost is real, though — nothing in a file tree makes a fact update itself, and a system that assigns addresses perfectly will still hand you a confidently outdated answer if nobody wrote the new one down.
Procedure: assigning an address
- Name the subject of the fact, not the task that produced it. If the sentence you write starts with “this came up while I was…”, you are about to file by workflow.
- Walk the tree from question one. Take the first branch that matches. Stop there.
- If nothing matches, stop and ask. Do not invent a location on the spot — an invented location is one nobody will walk the tree to find later.
- If a second workflow needs the fact, add a pointer. Never a copy.
- If you moved anything, grep the old path, update every reference, then delete the original. Steps four and five of the assertion are one operation, not two.
- Record the new location in the tree file itself. The tree is the index; a location that is not in the index does not exist.
2.2 Domain modules
Addressing fixes facts. It does nothing about 1.2, because “which discipline applies here” is not a fact lookup. That needs a second structure: one subject, one module, and a fixed internal shape so that invoking a subject loads its whole apparatus rather than the fragments of it that happen to resemble the question.
Shape
Every one of the 72 modules is a directory with the same three parts:
-
SKILL.md— the router. Front matter carries a description and trigger phrases. The body is a decision tree over scenarios plus a short rule list. It routes; it does not teach. -
references/— the record for that subject. Procedures, checklists, distilled sources. Read only when the router names the file. -
assets/— executable procedure. Scripts and templates, where the subject has any.
The sameness is not tidiness. It is what lets the top-level instruction file route to a module without knowing anything about that module’s contents. The moment one module invents its own layout, routing has to special-case it, and the resident index stops being sufficient.
What is actually resident
Loading happens in stages:
- Every turn: the top-level instruction file (6,960 B) plus the 72 front-matter descriptions (26,828 B) — 33,788 B total.
- On match: the body of one router.
- On demand: the reference files that router names.
- Rarely: a book chapter, and only when a step cites one.
Measured on the negotiation module, for one rent negotiation:
SKILL.md 1,760 B router
references/framework.md 8,858 B four-phase tree, always read
references/rent.md 3,064 B scenario supplement
references/anti-patterns.md 2,282 B output gate
────────
loaded for this request 15,964 B
module on disk 6,849,002 B
share of the module in context 0.233 %
The three distilled books account for essentially all of the 6.85 MB and are opened only when a phase cites a specific chapter. Across the whole system the same ratio holds: 189,028 B of routers index 139,091,825 B across 3,080 files — about 1 : 736. The index is small enough to keep resident precisely because it contains no content.
A router in full
This is the entire negotiation router, 1,760 bytes, translated from Chinese:
---
name: negotiation
description: "Negotiation assistant: rent, salary, offers, contract
terms. Decision framework built from Chris Voss + Getting to Yes +
Influence. Triggers: negotiate, counteroffer, haggle, salary
negotiation, rent negotiation, renewal, lease negotiation, offer
negotiation, ..."
---
# Negotiation — decision framework
## Flow
trigger → identify scenario
├─ rent / renewal → read references/rent.md
├─ salary / offer → read references/salary.md
└─ anything else → go straight to the framework
ALL scenarios → read references/framework.md (four-phase tree)
Phase 0: PREP — BATNA + one sheet + market intelligence
Phase 1: OPEN — tactical empathy + invite "No"
Phase 2: EXPLORE — calibrated questions + interests + black swans
Phase 3: PROPOSE — Ackerman + objective criteria + influence
Phase 4: CLOSE — three confirmations + get it in writing
after producing text → read references/anti-patterns.md, check line by line
└─ LOOP until no anti-pattern remains
need depth on a technique? → open the source:
references/books/never-split-the-difference/ tactical execution
references/books/getting-to-yes/ principled framing
references/books/influence/ psychological levers
## RULES
- The four phases run in order. PREP cannot be skipped.
- Every technique cites its source book; open the chapter for detail.
- The anti-pattern check is the last step, not an optional one.
Note what is absent: there is not a single fact about me in there. Personal state lives in the record and is read by path when a step needs it. That separation is rule 2 of the assertion, and it is what makes a module inspectable — and in principle shareable — without leaking anything.
Where the expertise comes from
A module is only worth routing to if it contains something the base model would not have produced. Three inputs, in order of how much work they are:
- Book distillation. A book is parsed, split by chapter, and reduced to the decisions it supports. The chapters stay on disk so a claim can be traced back.
- Information search. For things no book can supply — the actual asking rent in this building this month, current comp bands — the module does not guess. It names where to look and what to bring back.
- Distillation into gates. The output of the first two is not a summary. It is a checklist that can be run against a draft.
Gates
Four of the ten gates in the negotiation module, translated as they appear:
□ 1. Multiple fallbacks
grep: "alternatively" / "option" / "or we could"
→ Keep exactly one ask. Offering options tells them
you will accept anything.
📖 NSTD Ch9: one offer on the table at a time
□ 2. Revealing your floor
grep: "maximum" / "at most" / "budget"
→ Delete. Your floor is your BATNA. It is an internal tool.
📖 GTY Ch6: BATNA is not for disclosure
□ 4. Naming competitor prices
grep: "$" followed by digits
→ Say "competitive offers" instead. A specific number hands
them an anchor to beat rather than a reason to concede.
📖 NSTD Ch6: anchoring
□ 6. Length
body over 150 words → cut
→ Every extra sentence of justification reads as weakness.
📖 NSTD Ch2: silence is leverage
Two properties are worth copying even if you never negotiate anything:
- Each gate names a string to search for. The check does not depend on the model judging whether the draft “feels” over-explained. It greps. A gate that cannot be reduced to something mechanical is a gate that will pass whenever the model is in a good mood.
- Each gate carries its citation. When a gate produces a bad call, it can be audited against the source chapter and revised, rather than argued about from memory. Provenance is what makes the checklist maintainable rather than folklore.
Checklists resist chunking
This is the most concrete reason the gates are a file the router names rather than entries in an index. A checklist is the wrong shape for similarity retrieval. Embed ten gates, retrieve the top three against a draft, and you get the three gates most lexically similar to the text you already wrote — which, by construction, are the ones the draft already addresses. The other seven are skipped, and nothing reports the omission.
A checklist is only a checklist if it is read whole. Partial retrieval of a ten-item list does not give you seventy percent of the value; it gives you a seven-item silent failure, and it fails hardest on exactly the items the draft neglected — the ones you needed.
Procedure: building a module
- Wait for the third occurrence. One-off questions do not justify a module, and a module nobody routes to is worse than nothing because it still occupies resident description budget.
- Write the router first, and keep it near 2 KB: scenario branches, files to read, and the rules that cannot be skipped.
- Put the decision procedure in a reference file, not the router. If the router starts explaining, it will grow until it is too expensive to keep resident.
- Give it an output gate — a checklist that runs on the draft before it reaches me.
- Every gate names a string to search for and cites its source.
- Keep personal facts out. If the module needs one, it reads it from the record by path.
- Register it, so its description joins the resident index. That step is 2.3.
2.3 Schema evolution
The system changes shape over time: new modules, split domains, added gates, re-routed branches, retirements. The rules for changing it are stricter than the rules for using it, for the same reason schema migrations are more careful than queries.
When a change is triggered
Not when someone feels inspired. Two triggers, both scheduled:
- Periodic review. A daily briefing and a weekly review that read what happened and ask what should be different.
- Task boundary. A check that runs before a task is declared complete, asking whether anything from this task should become durable. This is the one that actually catches things, because it fires while the failure is still legible.
What a change can be
- Create a module — a subject came up a third time.
- Split a module — it was holding two subjects, and its router had grown two unrelated branches.
- Add a gate or rule to an existing module — something went wrong once and the failure is describable.
- Re-route — facts that should land in A were landing in B.
- Retire — the subject stopped occurring, or the data should not be held at all.
If a proposed change is none of the five, it is not a system change. It is a fact, and it goes to the record via 2.1. That test alone kills most of what looks like “the assistant should learn this.”
Who may make it
One module owns all five operations. Nothing else creates, moves, or deletes parts. The output of that gatekeeper is not new capability — it is sameness. Module 72 has the same shape as module 1, which is the only reason a single routing rule reaches both. Let each module invent its own layout and routing has to special-case each one; at that point the resident index no longer tells you enough to route, and you are back to guessing, which is 1.1 wearing a different hat.
The domains grew; they were not designed
I did not sit down and design nine domains. Each one appeared the week its subject first needed a durable home. The history is still in git:
$ git log --reverse --diff-filter=A --format='%ad' --date=short \
--name-only -- references/personal/
2026-03-02 career, education, identity, immigration
2026-03-04 ideas
2026-03-23 relationships
2026-03-25 identity_documents, network, pay_stubs
2026-04-01 finance, living
2026-04-14 health
2026-05-22 aesthetic-care
2026-08-06 travel
Fourteen domains created over five months, in four bursts. Nine exist today. If you are building one of these, the useful inference is that the initial layout does not matter very much, because it will not survive contact with use — but the rule for changing it matters enormously, because that is what determines whether five months of drift leaves you with a structure or a pile.
Five of the fourteen were retired, and each left a rule behind
This is the part I would inspect first in someone else’s system, because it is where the difference between a filing convention and an enforced schema shows up:
| Retired domain | What happened | What the tree says now |
|---|---|---|
immigration/ |
outgrew the record, promoted to its own project directory | routed at question two, with an explicit note that identity documents stay in the record |
ideas/ |
moved into the career project | anti-duplication table names the new canonical path |
relationships/ |
folded into network/ |
one person, one folder, under network/relationships/ |
identity/ |
renamed to identity_documents/; one of its files deleted outright |
scans live in the directory; the border-crossing record is fetched, never stored |
pay_stubs/ |
deleted, never re-created | “do not store — download from payroll when needed” |
The last row is the interesting one. The right resolution was
not a better location. It was a decision not to hold the
data at all, because the authoritative copy is one login
away and a local copy would go stale silently — the exact
failure mode from 2.1. Two other entries carry the same rule for
the same reason: border-crossing records and current pay are
fetched, never stored. The border-crossing record is the sharper
case, because it was stored once — it sat in
identity/ in the first commit that created the
record, and the rule that replaced it exists because that copy
went stale. Deciding what not to store is
part of the schema, and it is the part a system that
only ever appends can never express.
Debt is visible
A split that was never finished is on disk right now:
career.md sits next to a career/
directory. Under different readings of the tree both are
legitimate destinations, which is precisely the condition rule 3
forbids. The same is true of identity.md next to
identity_documents/.
I am not showing that as a success. It is unresolved, and it has
been for months. The point is narrower and it is the strongest
practical argument for paths as keys: I know it is
there. The address space is made of file paths, so
ls shows both, and any audit of the domain surfaces
the collision immediately. The equivalent condition in an
embedding index — two documents that disagree, both
indexed, neither marked, the winner decided per query by cosine
distance — has no ls. You do not find it. It
finds you, later, in an answer you had no reason to doubt.
The write-back rule
The top-level instruction file forbids the cheapest possible outcome of a review:
Never claim something was remembered on the basis of a
store_memory call alone. Conclusions and rules go into a
module or a reference — visible and verifiable.
This is the rule that makes 1.3 fixable. A lesson that lands in
an opaque store cannot be audited, diffed, or deleted. A lesson
that lands in a file shows up in git log, can be
read by a person, and can be deleted when it turns out to be
wrong. The requirement is not that the system remembers more. It
is that every claimed piece of learning has a diff behind it.
A concrete instance from writing this article: the handoff document for this repository now contains a rule about section headings — noun phrases, no slogans — added after a draft came back reading like marketing copy. That is what learning looks like in this system. Not a stored preference; a committed constraint that the next draft has to pass.
Procedure: changing the system
- Name the failure that motivated the change, in one sentence. If you cannot, there is no change to make.
- Decide which of the five kinds it is. If it is none of them, it is a fact — file it and stop.
- Check whether an existing module owns the subject. Prefer adding a gate over creating a module.
- Make the change in exactly one place.
- Grep the old path or the old rule, update every reference, delete the old copy.
- Update the tree file. The tree is the index; a change that is not in the index did not happen.
- Write down what you expect to see if the change worked, so the next review has something to check against.
I have no misroute rate. I do not know how often a fact lands on the wrong branch, because detecting that requires knowing where it should have gone — and the failures I catch are the ones I stumble into while looking for something else. A serious version of this would log every assignment along with the branch that matched, sample them weekly, and track how many facts in the record have not been touched since the state they describe changed. Neither exists today.
03
The deployed system
What follows is an inventory, not a recommendation. It is here because articles about agent architecture usually stop before the part where you find out how big the thing actually got.
3.1 Domain inventory
Nine domains hold long-lived personal state. Contents are not shown — only what each domain is for, and how many files it holds.
| Domain | Files | What it holds |
|---|---|---|
living/ |
614 | apartment, floor plans, car, furniture inventory, subscriptions |
network/ |
49 | one folder per person, with a lookup table at the top; work, friends, family |
health/ |
13 | one folder per test type, reports named by year, summary at the top |
identity_documents/ |
13 | passport, visa, work authorization, student records |
career/ |
9 | employment documents, CV, equity statements, long-range career planning |
finance/ |
9 | one folder per institution; card and account numbers in an encrypted file |
aesthetic-care/ |
4 | service providers: who, where, what was done, what it cost |
travel/ |
4 | stable preferences, a reusable packing baseline, one folder per trip |
education/ |
3 | degree certificates — the only copy anywhere in the system |
Two things in that table are worth reading as design output
rather than trivia. living/ is two orders of
magnitude larger than education/, and that is fine
— domains are units of addressing, not units of size, and
nothing breaks when they are lopsided. And four flat files
— academic.md, career.md,
identity.md, side-business.md —
predate the directory layout and still sit alongside it. Two of
them collide with directories of the same name, which is the
debt described in 2.3.
3.2 Module catalog
Seventy of the 72 modules, one line each. Two are withheld because their names alone disclose something private. Four names marked ∗ are generalized from internal tool names.
Running the system
system-maintenance— the only module allowed to create, move, or delete parts; owns the address tree.session-history-ops— searches past sessions and transcripts.copilot-config— changes default model and reasoning effort.mcp-ops— installs, removes, and debugs tool servers.sync-all— pushes every tracked project to remote.clean-copilot— runs the agent in an isolated container with a controlled subset of configuration, for experiments.reporting-ops— daily briefing and weekly review; the scheduled trigger behind 2.3.
Communication and people
email-ops— reading, searching, drafting, and sending across four accounts.teams-ops,slack-ops,loop-ops— work chat and collaborative documents.sms-ops,wechat-bot— personal messaging.apple-notification— pushes time-sensitive alerts to phone and watch.people-ops— the write path for thenetwork/domain: one person, one folder.workplace-communication— difficult conversations, managing upward, replies to colleagues.negotiation— rent, salary, offers, contract terms; the module dissected in 2.2.social-scout— gathers community opinion across forums when a question needs lived experience rather than theory.
Research and writing
paper-ops— paper lifecycle: outline, drafting, figures, rebuttal, camera-ready.theory-writing— how theorems, assumptions, and proofs are stated and cross-linked.notation-management— a symbol registry, consulted before any formula is written.overleaf-ops— sync, compilation errors, figure placement, typesetting.openreview-ops— review assignments, submissions, rebuttals.poster-ops,html-slide-ops,office-docs-ops— conference posters, slide decks, documents.pdf-ops— reading PDFs and filling forms that have no form fields.de-ai-tone— an output gate that strips machine-sounding prose.academic-profile-ops,download-cv— homepage, scholar profile, CV.add-book— parses a book, splits it by chapter, files it under the module that will use it.compliance-process∗ — internal publication and open-source release review.
Compute and experiments
env-control— decides where code runs; forbids experiments on the laptop.experiment-ops— experiment lifecycle: design, submit, evaluate, report.code-writing— the single authority for touching code: contracts, placement, surgical edits.gpu-cluster-ops∗,chtc-ops— two clusters with different schedulers and different queue etiquette.job-scheduler-cli∗ — job submission, log retrieval, artifact download.azure-ops— blob storage for artifacts too large for experiment tracking.wandb-ops— querying runs and pulling results.
Money
asset-snapshot— pulls live balances; forbidden from estimating or rounding.investment-ops— execution procedures: reviews, contributions, vesting, screening.spending-ops— transaction tracking, monthly bills, card rewards.purchase-ops— the checkout path, including the confirmation gate before any payment.tax-filing— document collection, residency determination, deadlines.expense-ops∗ — work expense reports and card reconciliation.adp— payroll documents, fetched rather than stored.finance-ops— a compatibility alias kept so older instructions still route.
Life administration
calendar-ops— four calendars, one write target, a local snapshot read before any API call.travel-ops— flights, points, packing lists, reservation linking.address-change-ops— enumerates every obligation triggered by moving, then executes them.apartment-search— pricing with the fees that are not in the advertised rent.home-renovation-ops— floor plans, cabinet drawings, contractor review.health-ops— portals, lab reports, prescriptions.account-ops— credential store; consulted before any login.legal-advisor— every conclusion must carry a citation to primary law.high-stakes— a slower read-check-fix-reread loop for documents that cannot be wrong.internet-debugging— network diagnosis and router administration.secondhand-ops,facebook-ops— resale listings and buyer messages.browser— routes web work from cheapest to most expensive: curl, then fetch, then a real browser.ghostty-ops— terminal configuration.
Personal
personal-development— emotional regulation and decision principles, distilled from classical sources.relationship-advisor— relationship questions, judged against one specific school of thought rather than general advice.beauty-search— skincare, treatments, and gift research.
Public presence
xhs— drafting, cover images, performance review for a social platform.twitter-ops,linkedin-ops— announcement drafts, iterated against a scoring rubric.social-media-development— account growth strategy.notion-ops— publishing to a shared workspace.
Scale, and how to measure it
Every number in this article came from one of these:
$ ls -1d */ | wc -l # modules
72
$ cat */SKILL.md | wc -c # router bytes, all modules
189028
$ find . -type f | wc -l # files under modules
3080
$ find . -type f -exec cat {} + | wc -c # bytes under modules
139091825
$ wc -c < copilot-instructions.md # always-resident charter
6960
| Quantity | Value |
|---|---|
| Modules | 72 |
| Router bytes, all modules | 189,028 B (mean 2.6 KB) |
| Files under modules | 3,080 |
| Bytes under modules | 139,091,825 B |
| Resident per turn | 33,788 B (charter + 72 descriptions) |
| Router-to-content ratio | 1 : 736 |
| Distilled books | 14, held inside the modules that cite them |
| Vector indexes, embeddings, frameworks | 0 |
That last row is the one I would push back on hardest if I were reading this. It is not a claim that similarity search is useless — it is a claim about what it is for. Retrieval is the right tool when the question is “what has been written about this,” and the wrong tool when the question is “what is true right now.” The system above answers the second kind almost exclusively, so it is built out of paths instead of distances. A system that did literature search would need the opposite.
One honest closing note on cost. All of this is text a human wrote and maintains. Fourteen domains became nine because somebody moved them; five retirements happened because somebody noticed. The design does not remove that work — it makes the work enumerable, which is a smaller claim than it sounds and the only one I am willing to defend.