explain-session
GitHub将编码会话上下文转化为简短教学笔记,涵盖交付内容、核心概念、方案对比、潜在陷阱及复习问题。适用于SessionEnd钩子或手动分析提交范围,旨在帮助非开发者快速理解并记忆技术实现细节。
Trigger Scenarios
Install
npx skills add v9ai/ai-engineer-roadmap --skill explain-session -g -y
SKILL.md
Frontmatter
{
"name": "explain-session",
"license": "Proprietary",
"metadata": {
"author": "vadim",
"version": "1"
},
"description": "Explain what a coding session just implemented, as a short teaching note — what shipped, the concept behind it, why this approach beat the alternative, the gotcha, and one recall question. Use when handed a session context bundle (git log, diffstat, diff, and the user's prompts) and asked to explain, summarise, or teach back what was built. Invoked headlessly by a SessionEnd hook, and usable by hand on any commit range.",
"compatibility": "Designed for Claude Code. Reads its context bundle from stdin and writes the note to stdout — needs no tools, no network, and no filesystem access."
}
Explain this session
You are handed a context bundle on stdin describing one coding session: a commit range, a diffstat, a truncated diff, and the prompts the user typed. Turn it into a short teaching note that makes the work understandable and memorable later.
The reader is the person who commissioned the work. They watched it happen but did not write it, and they will read this days later with the details gone. Write for that person.
Output contract
Emit either a single markdown note in exactly the structure below, or the
single line SKIP: <one-line reason> and nothing else.
Emit nothing else — no preamble, no "Here's the note", no closing commentary. Your entire stdout becomes the file.
When to SKIP
Most sessions should skip. Emit SKIP: when the bundle shows:
- no commits, or only merge/revert commits
- changes confined to lockfiles, generated data, formatting, or dependency bumps
- pure investigation, reading, planning, or configuration — nothing implemented
- a diff so small the commit subject already says everything (a typo, a version bump, a one-line constant change)
A note that explains something trivial is worse than no note: it trains the reader to skim past the ones that matter. When genuinely unsure, skip.
The note
# <what was built, 5-9 words, no filenames>
**What shipped.** One paragraph, plain language. What the system can now do that it
could not before. Name the moving parts in prose, not as a file list.
**The concept.** The transferable idea this exercised — name it, then define it in
one or two sentences. This is the part worth remembering in six months; the code is
not. If the session exercised no transferable concept, that is a strong signal to
SKIP.
**Why this way.** The approach that was rejected and what it would have cost. If the
bundle does not show a real alternative being weighed, write one line on the
constraint that forced this shape instead. Never invent a debate that did not happen.
**The gotcha.** The non-obvious thing that would bite on a repeat — the silent
failure, the ordering constraint, the API that lies. Omit this section entirely if
the session surfaced none; do not pad it.
**Recall.** One question testing the *concept*, not the filenames. Its answer must
not be stated anywhere above — the reader has to reconstruct it. Never a yes/no
question.
Rules
Ground every claim in the diff. The prompts show what was asked for; the diff shows what was built. Where they disagree, the diff wins. Never describe intent the code does not support, and never describe a feature the diff does not contain.
Under 400 words, excluding the heading. Shorter is better. If the session did several unrelated things, explain the largest and name the rest in one clause — do not write parallel notes.
No file paths in prose. lib/foo.ts:42 is meaningless to a reader six months
out and is already in git. Describe what a thing does, then name it if it has a
memorable name.
Plain language over jargon, but never at the cost of precision. If a term is the real name of the concept ("idempotence", "progressive disclosure", "content-addressed storage"), use it and define it — that is the vocabulary worth acquiring. Do not substitute a vague paraphrase for a precise term.
Uncertainty is stated, not smoothed. If the diff is truncated and you cannot see how something works, say so in the note rather than guessing plausibly. A confident wrong explanation is the worst possible output here.
Never flatter the work. No "elegant", "robust", "clean", "nice". If the session shipped a workaround, call it a workaround and say what it defers.
Example
Input bundle: commits adding a chapter_cache flag to a grounding pipeline, plus a
test asserting a hash is overwritten rather than deleted.
# Cache invalidation by overwrite, not deletion
**What shipped.** The grounding pipeline can now re-run a single chapter instead of
the whole document, cutting a full regeneration to one call. A cached chapter is
reused only when the hash of its input still matches.
**The concept.** Content-addressed caching: the cache key *is* a hash of the input,
so a changed input can never collide with a stale entry. The subtlety is what a
*missing* key means — this pipeline treats absent-hash as "adopt and trust", which
makes deletion and invalidation opposites rather than synonyms.
**Why this way.** Storing a modification timestamp instead would have been simpler,
but the inputs are rewritten by a generator that preserves mtimes, so timestamps
would report unchanged content as changed on every run.
**The gotcha.** Deleting the stored hash does not invalidate the cache — it makes
the entry adoptable, so the pipeline reports reuse and silently serves stale text.
Invalidation means *overwriting* the hash with a wrong value.
**Recall.** Why can a cache that treats a missing key as "trust the existing value"
never be safely invalidated by clearing state?
Version History
- fa07a94 Current 2026-07-24 11:47


