redis/reflect
Capture an agent experience note into the commit message — the lived reasoning behind a change (what was learned, what was rejected, what future-you must not break), written where the work happens so it travels with the code. Use right after finishing a meaningful chunk of coding/writing, when about to commit, or to amend the last un-pushed commit. Skip for mechanical changes. Feeds the squash-time distiller and the learning skills.
npx skills add https://github.com/redis/docs --skill reflect
You did the work, so you hold context that exists nowhere else and lasts about five
minutes: the false starts, the *why*, the thing that surprised you. This skill serialises
that context into the commit message while you still have it, so a future you — in the
IDE, with only git log and git blame on the file in front of you — gets it back at the
exact spot it matters.
This is judgment work, not a logging step. Most commits deserve no note. The value is
in the few that do, and in the compression. A note on every commit is noise the
squash-time distiller has to filter back out.
/reflect (here) → WIP commit messages [episodic, provisional, disposable]
PR review + bots → PR comments [external critique, via assess-comments]
↓ at squash/merge
distiller (later skill)→ surviving commit trailers [durable, location-reachable]
↓
promotion → learning skills / memory [cross-cutting, always-loaded]
Two rules follow from this and they are not negotiable:
being wrong here is *fine*, it's the interim space. Do not treat a WIP note as the
durable record.
pre-merge), after the PR has had its say. Never promote a note to "final" mid-cycle; the
review may overturn it.
Write a note only if one of these is true. If none are, commit normally and stop.
gotcha, a non-obvious cause, a "looks wrong but isn't").
fact) and should be re-checked later.
Skip: typo fixes, renames, formatting, dependency bumps, pure mechanical edits, anything
where the diff fully explains itself.
Prose reflection → commit body. One short paragraph, in plain language. This is what a
human reviewer reads and what a semantic-matching history bot recalls on. Keep it about
*this change*; cross-cutting lessons go to a learning skill instead (see Step 3).
Atomic facts → trailers. Flat Key: value, one line each, in a single contiguous block
at the very end of the message, no blank lines inside the block (git's trailer parser needs
this — a stray blank line or an earlier Foo: bar line in the body will break extraction).
These are defined once in ../_shared/commit-trailers.md so
they can't drift between this skill and /finalize. Read it now for the core vocabulary
(Constraint / Rejected / Directive / Learned), the situational fields, the
DOC-XXXX subject convention, and the format rules that keep trailers parseable.
The one rule worth repeating here: a field only earns its place if reading it before touching
the code would change a decision. When in doubt, leave it out and let the body prose carry it.
The sort picks the destination, so it must run before Step 4 lands anything — once a note
is committed or amended in, you can't honour a "this didn't belong in the commit" decision
without a rewrite.
the commit message (Step 4).
process rule, a standing gotcha like "check the running image, not the client version") →
a commit can never guarantee it'll be seen, so flag it for promotion to the relevant
learning skill or memory. Tell the user what you're proposing to promote and where;
don't edit a learning skill silently.
A note can split: the location-bound part goes in the commit, the cross-cutting part gets
promoted. Decide the split here, then carry only the location-bound part into Step 4.
write. (Preferred — no rewrite.)
git commit --amend to add the note.the next related commit, or **post it as a PR comment prefixed with the <!-- reflect-note -->
marker** so /finalize classifies it as author-side reflection, not reviewer critique (see
../_shared/commit-trailers.md). An *uncommitted* working
note is invisible to /finalize — don't rely on one. Say which you did.
Verify the trailers parse — but against the message you actually wrote, not whatever HEAD
happens to be:
git log -1 would read the previous commit and give a false pass:
git interpret-trailers --parse <message-file>
git log -1 --format='%(trailers:only,unfold)'
If either prints nothing but you wrote trailers, the block isn't contiguous/last — fix the
blank lines. (Format and unfold rules:
../_shared/commit-trailers.md.)
squash-time distiller's job, and it should run after review, not now.
trailer is worse than none, which is exactly why the durable write is deferred and
reviewable.
skipped the learning-skills tier quietly starves.
empty note is the right output for most commits.
Take redis/reflect from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.