codex/skills/learnings/SKILL.md
Capture, browse, and query evidence-backed execution learnings in `.learnings.jsonl`. Trigger cues: `$learnings`, browse/recent/search learnings, lessons learned, takeaways, wrap up, handoff, before commit/PR, after tests pass, fail-to-pass, strategy pivot, footgun, retry loop.
npx skillsauth add tkersey/dotfiles learningsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Capture durable lessons as soon as evidence appears, not only at explicit retrospective requests.
Also use the same CLI for interactive browsing and filtered search so prior learnings can be loaded deliberately instead of defaulting every read to recall.
Write each validated learning as JSONL so future agents can reuse successful patterns and avoid footguns quickly.
When iterating on the Zig-backed learnings/append_learning helper CLI path, use these two repos:
skills-zig ($HOME/workspace/tk/skills-zig): source for the learnings and append_learning Zig binaries, build/test wiring, and release tags.homebrew-tap ($HOME/workspace/tk/homebrew-tap): Homebrew formula updates/checksum bumps for released learnings binaries.$learningsfail->pass)recall: implementation preflight for a concrete task. Use the active request text as the query and treat hits as constraints/invariants.recent: interactive browsing. Use when the user wants to look around, skim the latest learnings, or orient before deciding what matters.query: filtered or aggregated browsing. Use when the user wants search, ranking, grouping, or summaries by status/tag/path/time.recall; start with recent or query, then switch to recall only when transitioning into implementation.recall during context gathering rather than on empty SessionStart hooks; if early exploration materially narrows the slice, rerun recall with the refined query.review_later with placeholders.appended: id=..., duplicate-skip: <reason>, or 0 records appended: <reason>.duplicate-skip: or 0 records appended: prefix so hooks can distinguish a valid no-write from a missed capture.learnings append/run_learnings_tool append for normal writes; keep append_learning available as a compatibility binary, and treat manual .learnings.jsonl edits as emergency-only with explicit rationale.git rev-parse --show-toplevel fails or the active task lives in a non-repo workspace such as ~/.codex/memories, skip capture and emit 0 records appended: non-repo cwd.--path .learnings.jsonl; if the CLI reports a different target path, treat that append as failed, repair the stray write if needed, and reappend correctly before closing..learnings.jsonl even if the append happened in an earlier turn. If it has pending changes and git check-ignore -v --no-index .learnings.jsonl does not report .git/info/exclude, include those learnings in the next commit by default. If the file is local-only by .git/info/exclude, or the user explicitly asks for a commit that excludes learnings, leave it unstaged and state that boundary in the proof. If the shared file also holds unrelated fresh rows, stage only the session-owned rows with an index patch rather than leaving all learnings for a follow-up commit.CODEX_SKILLS_HOME="${CODEX_HOME:-$HOME/.codex}"
CLAUDE_SKILLS_HOME="${CLAUDE_HOME:-$HOME/.claude}"
LEARNINGS_SPECS_DIR="$CODEX_SKILLS_HOME/skills/learnings/specs"
[ -d "$LEARNINGS_SPECS_DIR" ] || LEARNINGS_SPECS_DIR="$CLAUDE_SKILLS_HOME/skills/learnings/specs"
run_learnings_tool() {
local subcommand="${1:-}"
if [ -z "$subcommand" ]; then
echo "usage: run_learnings_tool <datasets|query|recent|recall|codify-candidates|quality-audit|value-report|memory-digest|append> [args...]" >&2
return 2
fi
shift || true
local mode=""
local bin=""
local marker=""
case "$subcommand" in
append|append-learning|append_learning)
mode="append"
bin="learnings"
marker="append_learning.zig"
;;
datasets|query|recent|recall|codify-candidates|quality-audit|value-report|memory-digest)
mode="learnings"
bin="learnings"
marker="learnings.zig"
;;
*)
echo "unknown learnings subcommand: $subcommand" >&2
return 2
;;
esac
learnings_repo_root() {
git rev-parse --show-toplevel 2>/dev/null
}
run_learnings_append() {
local repo_root=""
local expected_path=""
local output=""
local status=0
local actual_path=""
repo_root="$(learnings_repo_root)" || {
echo "0 records appended: non-repo cwd" >&2
return 3
}
expected_path="$repo_root/.learnings.jsonl"
output="$(
cd "$repo_root" &&
"$bin" append --path .learnings.jsonl "$@"
)"
status=$?
printf '%s\n' "$output"
[ $status -ne 0 ] && return $status
actual_path="$(printf '%s\n' "$output" | sed -n 's/.* path=//p' | tail -n 1)"
if [ -n "$actual_path" ] && [ "$actual_path" != "$expected_path" ]; then
echo "append-path-mismatch: expected $expected_path got $actual_path" >&2
return 4
fi
}
install_learnings_direct() {
local repo="${SKILLS_ZIG_REPO:-$HOME/workspace/tk/skills-zig}"
if ! command -v zig >/dev/null 2>&1; then
echo "zig not found. Install Zig from https://ziglang.org/download/ and retry." >&2
return 1
fi
if [ ! -d "$repo" ]; then
echo "skills-zig repo not found at $repo." >&2
echo "clone it with: git clone https://github.com/tkersey/skills-zig \"$repo\"" >&2
return 1
fi
if ! (cd "$repo" && zig build -Doptimize=ReleaseSafe); then
echo "direct Zig build failed in $repo." >&2
return 1
fi
mkdir -p "$HOME/.local/bin"
for direct_bin in learnings append_learning; do
if [ ! -x "$repo/zig-out/bin/$direct_bin" ]; then
echo "direct Zig build did not produce $repo/zig-out/bin/$direct_bin." >&2
return 1
fi
install -m 0755 "$repo/zig-out/bin/$direct_bin" "$HOME/.local/bin/$direct_bin"
done
}
local os="$(uname -s)"
if command -v "$bin" >/dev/null 2>&1 && (
[ "$mode" != "append" ] && "$bin" --help 2>&1 | grep -q "$marker" ||
[ "$mode" = "append" ] && "$bin" append --help 2>&1 | grep -q "$marker"
); then
if [ "$mode" = "append" ]; then
run_learnings_append "$@"
else
"$bin" "$subcommand" "$@"
fi
return
fi
if [ "$os" = "Darwin" ]; then
if ! command -v brew >/dev/null 2>&1; then
echo "homebrew is required on macOS: https://brew.sh/" >&2
return 1
fi
if ! brew install tkersey/tap/learnings; then
echo "brew install tkersey/tap/learnings failed." >&2
return 1
fi
elif ! (
command -v "$bin" >/dev/null 2>&1 && (
[ "$mode" != "append" ] && "$bin" --help 2>&1 | grep -q "$marker" ||
[ "$mode" = "append" ] && "$bin" append --help 2>&1 | grep -q "$marker"
)
); then
if ! install_learnings_direct; then
return 1
fi
fi
if command -v "$bin" >/dev/null 2>&1 && (
[ "$mode" != "append" ] && "$bin" --help 2>&1 | grep -q "$marker" ||
[ "$mode" = "append" ] && "$bin" append --help 2>&1 | grep -q "$marker"
); then
if [ "$mode" = "append" ]; then
run_learnings_append "$@"
else
"$bin" "$subcommand" "$@"
fi
return
fi
echo "learnings binary missing or incompatible after install attempt: $bin" >&2
if [ "$os" = "Darwin" ]; then
echo "expected install path: brew install tkersey/tap/learnings" >&2
else
echo "expected direct path: SKILLS_ZIG_REPO=<skills-zig-path> zig build -Doptimize=ReleaseSafe" >&2
fi
return 1
}
Capture at least once per coding turn when any of these checkpoints occurs:
fail->pass, pass->fail, timeout->stable).Auto-trigger rule: if none of these checkpoints occurred and nothing decision-shaping emerged, do not append anything.
Before writing a learning, require all three:
If any answer is no, skip capture (or use review_later only when uncertainty itself is decision-shaping).
git status -sb, git diff --stat, targeted git diff).When X, prefer Y because Z).do_more or do_less when they fit.investigate_more, codify_now, avoid_for_now).learning contains explicit condition + action (When/If ... prefer/do ...).evidence includes at least one concrete anchor (command outcome, commit SHA, run ID, file path, or exact error string).application states what to do on the next similar task.status reflects intent (avoid defaulting to do_more when codify_now/investigate_more/avoid_for_now is more accurate)./tmp, /var/folders/...), either skip or mirror only high-signal lessons into a durable repo .learnings.jsonl.git rev-parse --show-toplevel; if that fails, skip capture with 0 records appended: non-repo cwd unless the user explicitly names another durable target..learnings.jsonl in that repo root (0 records is valid when nothing qualifies).learnings append via run_learnings_tool append, which changes into the verified repo root and passes --path .learnings.jsonl.path=..., require an exact match with $repo_root/.learnings.jsonl; treat any mismatch as a failed append and repair/reappend before finishing..learnings.jsonl explicitly even if the append happened in an earlier turn..learnings.jsonl has pending changes, stage the publishable learning rows into that next commit by default.git check-ignore -v --no-index .learnings.jsonl reports .git/info/exclude, treat the file as local-only, leave it unstaged, and never use git add -f to satisfy commit coupling, even if .learnings.jsonl is already tracked..learnings.jsonl unstaged and state that boundary in the proof..learnings.jsonl, use a targeted index patch instead of postponing the learnings write.appended: id=..., duplicate-skip: <reason>, or 0 records appended: <reason>).Write one JSON object per line:
{
"id": "lrn-20260207T173422Z-a91f4e2c",
"captured_at": "2026-02-07T17:34:22Z",
"status": "do_more",
"learning": "Boundary parsing eliminated downstream guard duplication.",
"evidence": [
"uv run pytest tests/parser_test.py::test_rejects_invalid passed after boundary parse refactor"
],
"application": "Parse and refine request payloads once at API boundaries.",
"tags": [
"api",
"testing"
],
"context": {
"repo": "owner/repo",
"branch": "main",
"paths": [
"src/parser.py",
"tests/parser_test.py"
]
},
"related_ids": [
"lrn-20260130T120000Z-deadbeef"
],
"supersedes_id": "lrn-20260101T090000Z-cafebabe",
"source": "skill:learnings",
"fingerprint": "a91f4e2c6b5d3f10"
}
Required keys:
idcaptured_atstatuslearningevidenceapplicationsourcefingerprintOptional keys:
contexttagsrelated_idssupersedes_idUse one append call per learning:
run_learnings_tool append \
--status do_more \
--learning "Boundary parsing eliminated downstream guard duplication." \
--evidence "uv run pytest tests/parser_test.py::test_rejects_invalid passed after boundary parse refactor" \
--application "Parse and refine request payloads once at API boundaries." \
--tag api \
--tag testing
Call the wrapper from a real repo checkout only; for non-repo tasks such as memory-folder maintenance, default to 0 records appended: non-repo cwd unless the user explicitly names a target repo/file.
The helper script:
status to snake_case.status to review_later when omitted..learnings.jsonl.--path .learnings.jsonl.--quality-mode best_effort for intentional thin capture.--allow-temp-path when temporary-repo capture is unavoidable.best_effort mode only, backfills missing evidence/application with placeholders.remote.origin.url (or falls back to repo dir name)..learnings.jsonl in repo root by default.Use the miner script both for interactive browsing and for task-start loading once the user prompt is available.
Routing:
run_learnings_tool recent --limit 10run_learnings_tool query --spec "@$LEARNINGS_SPECS_DIR/top-tags.json"run_learnings_tool query --spec "@$LEARNINGS_SPECS_DIR/top-paths.json"run_learnings_tool memory-digest (defaults to $CODEX_HOME/memories/extensions/learnings/resources/latest_learnings_digest.md, falling back to $HOME/.codex/... when CODEX_HOME is unset)run_learnings_tool recall --query "<focused task terms>" --limit 5 --drop-supersededrun_learnings_tool recall once after parse, seq, or early file reads only if those steps materially narrow the implementation slice; tighten the query rather than replaying the full prompt.recent before escalating to query or recall.CLI:
run_learnings_tool datasets
run_learnings_tool query --spec "@$LEARNINGS_SPECS_DIR/status-rank.json"
run_learnings_tool query --spec "@$LEARNINGS_SPECS_DIR/top-tags.json"
run_learnings_tool query --spec "@$LEARNINGS_SPECS_DIR/top-paths.json"
run_learnings_tool recent --limit 15
run_learnings_tool recall --query "fix flaky pre-commit hook" --limit 5
run_learnings_tool codify-candidates --min-count 3 --limit 20
run_learnings_tool quality-audit --since 2026-02-01 --until 2026-03-05 --format json
run_learnings_tool value-report --sessions-root "$HOME/.codex/sessions" --since 2026-03-01 --comparator impl_nonrecall --format json
run_learnings_tool memory-digest --limit-candidates 12
Promotion rule of thumb:
codify_now, promote it into durable docs (for example codex/AGENTS.md or a relevant skill doc).--related-id/--supersedes-id and a codified tag).Runtime bootstrap policy for learnings mirrors cas: use Zig binaries only (learnings with append plus append_learning compatibility), default to Homebrew install on macOS, and fallback to direct Zig install from skills-zig on non-macOS.
status action-oriented and semantically meaningful for the situation..learnings.jsonl, revert it immediately and reappend through the verified repo-root CLI path..learnings.jsonl matches .git/info/exclude, treat it as local-only state even if the file is already tracked: keep capture local, and do not force-add, stage, or commit it unless the user explicitly requests publication.status and/or make the learning statement more specific) or re-run with --allow-duplicate intentionally.review_later and placeholders, then enrich later.testing
Use before local patching when bugs, regressions, malformed state, crashes, parser failures, migrations, cache drift, protocol problems, compatibility requests, tolerant readers, fallbacks, coercions, retries, catch-and-continue logic, or local workarounds may broaden accepted invalid state.
testing
Use for bug reports, PR/issue prose, reviewer comments, user diagnoses, generated summaries, memories, retrieved context, public tracker context, claimed root causes, proposed fixes, fake-minimal repro risk, or any investigation where natural-language context could anchor the implementation scope.
development
Use when non-trivial work needs Challenge Escalation, latent-intelligence activation, frame-market selection, doctrine operators, dominant-move selection, ablation/surface-tax judgment, reification, review comment law, negative capability, route receipts, or proof-bearing refusal to mutate.
development
Apply Algebra-Driven Design. Use for ADD, denotational design, combinator models, law-driven architecture, domain algebra, property tests, codebase modeling, event sourcing, workflow design, or agentic skill design. If the canonical bundle is unavailable, use this wrapper as the minimal ADD kernel and report the missing bundle path.