The problem

LLM conversations branch faster than they converge. One question spawns another, that answer turns into a new thread, and by the end of the week a single topic is spread across five sessions I don't remember starting. Three days later I come back with the same question and have to reconstruct what I already figured out. Branching is efficient. The branches never merging is not.

session-log is the merge step. It reads the current conversation and writes the result into one place: today's daily note.

What it does today

Two things, in order.

  1. Always append to the daily note. Daily notes live inside the weekly file as ### YYMMDD DAY sections (Obsidian Periodic Notes pattern). Every session gets at least one bullet there, classified with a 5 Values tag (#learn, #build, #share, #grow, #execute) plus any habit modifier tag (#english, #exercise, #writing, #sleep, #focus) that applied.
  2. Conditionally route permanent knowledge. If the session produced reusable material (a debugging pattern, an English expression, a meeting decision, a new Wiki page's worth of understanding), route it to the permanent doc. Work sessions split further: projects, learnings, and meetings get separate homes.

The design value isn't in any single step. It's in what the skill doesn't ask me to decide. "Is this worth logging?" "Which folder?" "Did I already record this today?" Those questions all die quietly inside the skill's heuristics. I just type /session-log.

flowchart LR
    classDef session fill:#ddd6fe,stroke:#6d28d9,color:#374151
    classDef hub fill:#3b82f6,stroke:#1e3a5f,color:#ffffff
    classDef daily fill:#ecfdf5,stroke:#047857,color:#374151
    classDef perm fill:#fffbeb,stroke:#b45309,color:#374151

    subgraph sessions["A day's LLM sessions"]
        direction TB
        S1([CRM API debugging]):::session
        S2([English expressions review]):::session
        S3([Blog draft]):::session
        S4([Slack message draft]):::session
        S5([CELPIP practice]):::session
    end

    SL((session-log)):::hub

    subgraph daily["Daily note · always"]
        DN["<b>260421 TUE</b><br/>· CRM API auth  #execute #learn<br/>· 7 English expressions  #english<br/>· Slack message relayed  #share<br/>· CELPIP writing  #focus<br/>· Blog draft  #build #writing"]:::daily
    end

    subgraph perm["Permanent docs · conditional"]
        P1["Work/projects/active/crm-api/session-notes.md"]:::perm
        P2["Work/learnings/api-auth.md"]:::perm
        P3["Wiki/english/expressions.md"]:::perm
    end

    S1 --> SL
    S2 --> SL
    S3 --> SL
    S4 --> SL
    S5 --> SL
    SL ==>|"always"| DN
    SL -.->|"conditional"| P1
    SL -.-> P2
    SL -.-> P3

    linkStyle 0,1,2,3,4 stroke:#6d28d9,stroke-width:2px
    linkStyle 5 stroke:#047857,stroke-width:3px
    linkStyle 6,7,8 stroke:#b45309,stroke-width:2px,stroke-dasharray:5 5

Three improving moments

From two skills to one

vault-sync and session-log lived side by side. vault-sync had a narrow scope: digest sessions from my WSL dev box into the Work/ directory, so work-related notes lived where the work happened. session-log covered everything else, including the daily note.

The problem surfaced every morning. I'd open the daily note and see only personal items. Work bullets had gone straight into Work/ via vault-sync and never touched the daily note. But the daily note is supposed to be the first place I check each morning, a single scannable list of everything I need to take care of today. Half of that list was missing.

So I merged vault-sync into session-log. One skill, one entry point. The daily note now shows work and personal side by side. Permanent routing still splits (Work items go to Work/, personal items to Wiki/), but the daily log gets both.

The lesson: when you carve a skill along the storage boundary (Work folder vs the rest), you can break the reader's boundary (the daily note, which wants everything in one view). The daily log is the index. Fragmenting its input is how you lose the overview.

Appending isn't enough, stale detection matters

Stale detection is a recent addition. The gap showed up while I was deep in a long-term project. I'd run session-log at the end of each session and the skill would faithfully add bullets to the daily note and occasionally spin up a new learnings file. Surface-level writes, done well. But the related files (the project doc I'd been evolving for weeks, the Wiki page whose decisions the session had just overturned) rarely got touched. I kept stacking fresh captures on top of docs that were quietly drifting out of date.

That was the problem I wanted to fix, so I wrote it explicitly into the skill. After analyzing the session, session-log now scans docs that look affected (by path, by keyword, by last-updated date) and flags stale candidates. Not auto-rewrite: that's review-gate territory, because a wrong edit to a canonical file compounds into every future retrieval. The skill surfaces "this might be stale, want to review?" and waits.

The lesson: knowledge isn't append-only. Any write-capture skill that treats it that way develops a bias toward the surface: the daily log stays fresh while the deeper files rot underneath.

Language policy: English default, high-resolution simple

Skill outputs used to come out in Korean by default. Consistent, readable, and frictionless, which was exactly the problem. Reading Korean required zero effort from me, so daily use of the skill did nothing for my English. And I use this skill every day.

That collided with my broader stance. AGENTS.md enforces English across the vault for immersion reasons, but session-log had quietly carved an exception for itself. So I flipped the default. New daily bullets, learnings files, and meeting summaries all come out in English now. Korean only in narrow cases: the file is already Korean (don't flip mid-document), the user passes --ko (emergencies), or the file is a verbatim transcript from a Korean-language meeting.

The style rule mattered as much as the default. "Simple English" can slide into vague English. The rule I settled on is simple but high-resolution: use the precise word when it matters, and inline-gloss uncommon terms (idempotent (same input → same output, safe to retry)) instead of dodging them. The skill's own prompts enforce this, so outputs land consistent across sessions.

The lesson: daily-use tools are daily practice opportunities. If you want to improve at something, the tools you touch every day shouldn't route around the effort.

What I haven't automated yet

A few things stayed off the table.

  • Auto-rewrite of stale docs. Stale detection surfaces candidates; approval stays with me, so the skill doesn't quietly accumulate wrong rewrites in canonical docs.
  • LLM-graded bullet quality. I do want the LLM to evaluate quality eventually, silently and in the background. Not yet. Right now I'm fine with a noisy, even verbose-looking daily log; the signal-to-noise ratio works at current volume. When volume outgrows scannability, I'll compact the log after the fact rather than filter at capture time. A filter that silently drops the thing I wanted to find is worse than a long log I can skim.
  • Cross-session summarization. Session-log handles one session. Aggregation belongs to /retro (weekly) and /monthly-retro. Skills that try to own multiple lifecycles get confused.

Same spirit as the broader vault design: autonomy is the goal, but trust is earned per domain. Stale detection flagging is where this skill starts; once the flags prove reliable, auto-apply opens up for low-stakes files first. High-stakes docs likely stay review-gate for good.