← Blog Posts

I Built a Second Brain That Writes Itself

For years my notes were a graveyard. I took them diligently during a Data Cloud discovery call, filed them somewhere sensible, and never opened them again. Then a quarter would end, my manager would ask what I’d accomplished, and I’d reconstruct three months of my own life from calendar archaeology and Slack scrollback. What came out was vague and undersold genuinely good work.

The problem was never the notes app. Obsidian was already excellent. The problem was that a human had to do the structuring, and structuring is exactly the work nobody has energy for at 6pm on a Thursday.

I wrote about the fix back in February: an Obsidian vault, linked note types, and a Claude Code skill that turned a brain dump into a structured daily log. Six months later it’s still running, which is more than I can say for any other capture habit I’ve tried. This post is about why it survived, and about the one skill I didn’t have in February that has since become the most valuable thing in the vault.

Boring data, smart tooling

The whole system is two halves, and the split is deliberate.

Obsidian is the durable substrate. Plain Markdown files on my laptop. YAML frontmatter for structured fields. Wikilinks for relationships. Dataview for live queries. No database, no API, no vendor. I can grep it, back it up to git, and open it in any text editor made in the last forty years.

Claude Code is the intelligence layer. It reads and writes those files directly, following instructions I’ve written down as skills: Markdown files that teach it how my vault is shaped and what to do when I say certain things.

That split is the actual insight, and it generalizes well past note-taking. Keep the data layer boring and permanent. Keep the intelligence layer swappable. If a better model ships next year, I swap it and lose nothing. If Obsidian disappears tomorrow, my notes are still Markdown files. Every AI-native notes product I’ve evaluated inverts this: the intelligence is the product and your data is the hostage.

If you spend your days arguing for warehouse-first architectures over black-box SaaS, you already believe this. I just applied it to my own head.

Structure is what makes it work

This is the part most “I use AI for notes” posts skip, and it’s the part that matters most.

Every note in my vault has a type in its frontmatter. Three families:

  • Temporal: daily logs, weekly reviews, quarterly reviews
  • Entities: people, companies, projects, goals, credentials
  • Content: action items, decisions, big wins, reference notes

Relationships are wikilinks, not folders. An action item links up to its project, its goal, the people involved, and the day it was created. The daily log links back down. Everything is bidirectional, which is what lets a dashboard exist that I never maintain.

I also enforce a controlled tag vocabulary. About eleven tags across two facets, domain and activity, with a documented migration table from retired tags to canonical ones. Domain is data-cloud, agentforce, marketing-cloud, platform, ai-tooling. Activity is architecture, integration, discovery, thought-leadership, reusable-asset, delivery. That’s the whole list. Two per facet, maximum.

This one is load-bearing. Turn a language model loose on tagging and it will cheerfully invent a new tag every session, and within a month nothing is findable. The rule I wrote into the taxonomy note: tags are a coarse topical filter, and precise retrieval runs on type, folder, and links.

The lesson generalizes. The model is a client of your schema, not a substitute for one. Design the schema first. I’ve rewritten my skills twice. I’ve never regretted an hour spent on frontmatter design.

The four skills

A Claude Code skill is a Markdown file: instructions, plus a description that governs when it fires. I have four.

dailylog takes a freeform brain dump, or a screenshot of my Outlook calendar, and writes a structured daily log.

adr captures architecture decisions in ADR form, including superseding earlier ones. It has become the most valuable one, and it gets its own section below.

goal creates, updates, reviews, and closes goals.

review is read-only synthesis: weekly review, quarterly review, or a brag sheet over an arbitrary date range.

Two design details separate a system that works from one that rots.

Match before you create

When I mention a colleague in a brain dump, the skill searches my People/ folder before writing anything, and links to the existing note rather than spawning a near-duplicate. Same for projects and goals. Without this rule you end up with Sarah, Sarah K, and Sarah Kim as three separate people, and your graph quietly becomes garbage.

This is identity resolution. If you’ve ever configured a match ruleset in Data Cloud, you already know both the failure mode and the fix, and you know that fuzzy-matching at read time is strictly worse than resolving at write time.

Close the loop, or the list only grows

Every task system I’ve ever abandoned got the same thing wrong. Capture is easy. Closure is not. Nobody goes back and ticks boxes.

But a brain dump naturally reports completions. Sent the deck. Submitted the ticket. Followed up with the PM. So the daily log skill greps for open action items, matches them against what I just said, and proposes closing them. I confirm, it writes.

That single rule is why my open-items list is a real list instead of a monument.

What it actually looks like

Here’s a lightly redacted example. On a Thursday I dictated maybe four minutes of rambling about an Agentforce and Data Cloud pre-sales scoping day. What came back into the vault:

---
type: daily-log
date: 2026-08-13
projects:
  - "[[Agentforce & Data Cloud Scoping]]"
goals:
  - "[[Ship 3 More Reusable Practice Assets]]"
people:
  - "[[Commercial Lead]]"
energy: High
---

Then structured Accomplishments, Blockers, and Notes sections. The blockers it pulled out on its own:

  • NDA not executed, customer’s paper. Nothing downstream moves until it clears: no prioritized use-case list, no org access.
  • Salesforce AE questions unanswered. Whether they own the Agentforce Service Agent SKU, which consumption model the org is on, order end date and remaining Flex Credits, whether their edition enables Data Cloud in sandbox. None of it is answerable from documentation.
  • Client edition unknown, Enterprise vs Unlimited. Decides whether Digital Engagement is a five-figure add-on or already included.
  • Read-only production access approved verbally on the 8/12 readback call, still not provisioned. Carried forward from 8/12.

That last one is the tell. Carried forward from 8/12. I didn’t say that. It read the previous log, saw the same blocker unresolved, and carried it with its age attached. Three days later that becomes “still blocked after a week,” which is exactly the sentence you need to say out loud on a status call and exactly the sentence nobody remembers to say.

The ADR skill, or how I stopped re-deriving my own reasoning

This is the one that changed how I work, so it gets its own section.

An Architectural Decision Record captures a single non-obvious choice: the context that forced it, what you chose, why, what you rejected and why, and what it makes harder later. It’s an old practice from software engineering. It is wildly underused in Salesforce consulting, and I think that’s a mistake. Our entire value is the decisions we make under uncertainty. The config is downstream.

My skill enforces five sections and refuses to let two of them be empty:

  • Context: the situation that forced a choice
  • Decision: the choice, in one or two sentences
  • Rationale: why, in bullets
  • Alternatives Considered: required
  • Consequences: required

The two hard rules are what make it work. A decision without rejected alternatives isn’t a decision, it’s a default, so the skill pushes back until I name at least one. And every real decision has trade-offs, so if I list no consequences it asks what this makes harder later.

Here’s a real one, redacted. Note the shape of it more than the content.

Ingest Community Feed as Best Answers plus structured objects only

Status: Accepted. Tags: data-cloud, agentforce, architecture

Context. The client’s Experience Cloud community has rich discussion data: questions, replies, comments, news posts, events, feature requests. Surfacing all of it through Agentforce risks low-signal noise overwhelming high-signal posts.

Decision. Ingest only replies explicitly marked Best Answer, plus the structured News, Events, and Feature Request objects. Skip non-best-answer replies and free-form comment chains.

Rationale. Best Answer is the curation signal worth trusting. Best Answers are maybe 10–15% of total replies, so ingesting everything would multiply community-feed volume six to ten times with mostly low-quality content. Lower volume means better retrieval quality and lower platform cost.

Alternatives Considered. Ingest the full feed: rejected, poor signal-to-noise, and it risks surfacing unanswered or contradicted user posts as authoritative. Ingest everything and filter at retrieval time: rejected, cheaper to filter at ingest. Storing data you’ll never serve is waste, and tuning a retriever to suppress noise you chose to ingest is harder than not ingesting it.

Consequences. Higher signal-to-noise, smaller index, faster queries. Editorial dependency on the Best Answer marking process: if community managers stop marking consistently, retrieval quality silently degrades, so it’s worth periodic audits. Open question, validate that the FeedItem, Question, and Reply objects are supported via the Data Cloud CRM connector.

Three things worth stealing from that.

The strikethrough. In the live note, that last open question is struck through and annotated: Resolved the next day. The CRM connector is not the supported path. See [[Use S3 UDLO for Community Feed ingestion]]. The ADR doesn’t get edited to look like I was right the first time. It shows the open question, it shows the day it closed, and it links to the decision that closed it. The record of being wrong is the most valuable thing in the file.

Supersession is two-way. When a decision gets replaced, the skill creates the new ADR, sets the old one to status: Superseded, and cross-links them in both directions. Anyone landing on either one finds the other. Status values are a closed set: Proposed, Accepted, Superseded, Deprecated. An open-ended status field becomes prose within a month.

The rejected alternative is the reusable asset. “We chose S3 UDLO ingestion” helps nobody. “We chose S3 UDLO over the CRM connector because the connector doesn’t support these objects, and over Zero Copy because it can’t support near-real-time identity resolution” is a paragraph I have since reused in a SOW, an internal enablement session, and a client architecture review. I wrote it once, on the day I figured it out, in four minutes of talking.

That’s the actual pitch. ADRs turn decisions made under time pressure into IP you can bill against later. Without them, every engagement starts from zero and every architect on your team re-derives the same conclusions independently. Mine currently hold nine decisions across identity resolution, ingestion architecture, retrieval strategy, and grounding. The honest finding from my last weekly review was that eight of the nine come from a single project. The system told me that, too.

The read path: queries, not searching

Because everything is structured frontmatter, my dashboard is a set of live Dataview queries rather than a document I maintain:

```dataview
TABLE status, due-date AS "Due", project.display-name AS "Project"
FROM "Action Items"
WHERE status != "Done" AND status != "Cancelled"
SORT due-date ASC
```

Open action items. Active goals. A rolling 14-day energy trend. Nothing to update, ever.

But the queries aren’t the payoff. The weekly review is.

Every Friday the review skill reads the week’s logs and surfaces four things I would never notice on my own:

  • Neglected goals: active goals that no daily log touched this week
  • Overdue action items, with the number of days attached
  • Energy trend: a sustained Low or a downward run gets named as a burnout signal
  • Network atrophy: every person note carries a cadence (weekly, monthly, quarterly), and the review flags anyone past due

Here is a real finding from a recent one:

The structural problem got fixed this week. 24 consecutive logs had carried goals: []. Not sloppiness: every goal completed in June and July and nothing replaced them. There was nothing left to log against.

Twenty-four days. I was logging diligently the entire time and would have sworn I was making progress on my goals. I had no goals. The system noticed because it can count and I can’t.

And this one, which I think about more than I’d like:

[[Certification]] (Active, target 2026-09-04, progress 10%). Zero study sessions logged, and the target is three weeks out. The goal’s own stated enforcement mechanism, link it in the daily log whenever a session happens, has been followed zero times, and the calendar-hold action item is 17 days overdue. This is the one goal the week didn’t help. Either protect the time next week or move the target date honestly. Carrying a three-week-out date at 10% is the version that quietly fails.

That is a harder read of my week than I would have given myself. It isn’t invested in my excuses, and it has the receipts.

The payoff nobody expects

Performance review season used to mean a half-day of reconstruction. Now it’s a query.

The quarterly mode rolls up wins, projects shipped, certifications earned, decisions made, and goal progress. All of it pulled from notes written when the details were still precise. Compare two versions of the same accomplishment.

What I’d have written from memory in October:

Led a Salesforce org assessment for a client. Found a lot of technical debt. Delivered a readback to their leadership.

What the vault produced, because it was captured the day it happened:

Three-day sprint from standing start to delivered readback. Built read-only assessment tooling: resumable Metadata API sweeps, dependency and cardinality analysis passes. Inventoried 221 objects and 14,734 fields, and corrected the org’s own reported field count from 38,383 down to 10,746, verified two independent ways. Found Work Order had hit four platform ceilings simultaneously, 127 unsupported Workflow Rules still in force, roughly 99 automations firing per Work Order save with zero trigger-order settings configured, and 1,401 retirement candidates. Delivered the executive readback to three stakeholders including an incoming sales leader. The call generated a same-day follow-on analysis surfacing 210 fields on Opportunity of which about 6 were genuinely user-entered, and a channel that is 46% of pipeline but 0.1% of reporting.

Same week of work. One of those gets you promoted.

The precision isn’t because I’m more diligent than you. It’s because the number was captured within hours of being true, by something that asked for it while I still had it.

Friction is the whole ballgame

My entire user-facing surface is two slash commands: /checkin mid-day and /eod at close.

The design principle underneath: if capture costs more than ten seconds of deliberate thought, the system dies. Every “please confirm” you add is a place where a real person quits.

So the skill infers my energy level from the tone of what I wrote rather than asking. It only asks about calendar entries too generic to place, the ones just labeled “Sync” or “Meeting,” and never about anything it can confidently infer.

But it does stop and confirm before creating action items, because a wrong action item is worse than a missing one, and one bad write teaches you to distrust the whole vault. The rule I settled on: automate the inference, gate the writes.

If you want to build one

Five things, in the order they’ll bite you.

Start with the schema, not the AI. Decide your note types and your frontmatter fields before you write a single instruction. Everything downstream is queries against that schema.

Control the vocabulary or the model will invent one. A short controlled tag list beats infinite expressive tagging every time.

Version your skills separately from the deployed copy. My sources live in a dev directory and get built and deployed to the live bundle. Editing a running skill in place is unversioned change management straight into production, and you already know how that story ends.

Make anything that synthesizes read-only by default. My review skill never edits a note without explicit confirmation. Analysis tools that quietly mutate state are how you stop trusting your own records.

Keep it plain files. Non-negotiable. It’s what makes every other part possible.

What actually changed

Not “I’m more productive.” Something more specific, and I think more useful.

I stopped losing the why behind decisions. Six months later I can read the reasoning on an identity resolution ruleset or an ingestion path, including the two options I rejected and what would have to be true for me to revisit them. That reasoning used to evaporate the moment the engagement closed.

Quarterly self-assessment went from dread to a query, and the version that comes out is dramatically better than the one I used to write. Not because it’s embellished, but because it’s precise.

And the one I didn’t see coming. Getting an honest energy trend and a neglected-goals list every Friday changed what I actually did the following Monday. The real output of this system isn’t the notes.

It’s a weekly conversation with something that has read everything I’ve done, remembers what I said I’d do, and has absolutely no stake in letting me off the hook.