- name
- learning-capturer
- description
- Capture recurring fixes from Littlebird activity. Use after a hard debugging session or for a weekly personal knowledge-base review. Read README.md for the guide map.
- license
- AGPL-3.0-or-later
- compatibility
- Claude Cowork, Claude Code 2.1 or newer, Cursor 2.4 or newer, Codex
- metadata
- {"hive-tier":"standalone","version":"1.0.0","author":"Mario Aldayuz / Littlebird","requires":"Littlebird MCP (Power or Pro plan)"}
# learning-capturer
## Purpose
The same wall, twice. An error the user spent ninety minutes on in March shows up again in
August and they start from zero, because the fix lived in a terminal scrollback that closed
months ago.
Littlebird watched the whole first fight. This skill reads that capture, finds the moments
where something broke and then stopped being broken, and turns each one into an entry in a
personal knowledge base keyed on the thing the user will actually search for next time,
which is the literal error text.
Two facts shape the design. Error message explanations are among the most frequent things
developers search the web for [references/research/distilled-personal-knowledge-capture.md
section 1], and search behavior has not declined despite AI assistants arriving
[references/research/distilled-personal-knowledge-capture.md section 1]. So the retrieval
key is the error string, and building a local searchable artifact is not fighting a dying
habit.
**The founding premise, that people re-debug problems they already solved, is a premise.**
No source in this skill's archive measures a re-finding rate
[references/research/distilled-personal-knowledge-capture.md section 8]. Do not present it
to the user as a research finding.
**Mode: weekly routine that proposes, plus on-demand after a hard session.** The routine
never writes. The user confirms every entry.
---
## Littlebird MCP calls used
Real tool names, verified 2026-08-17. List the tools available in this session and use what
is actually there.
| Tool | Used for |
|---|---|
| `search_user_context` | Every retrieval sweep. Error surfaces, the grind, resumption, message threads, activity summaries, and the historical recurrence check. |
| `LB_INTERNAL_SEARCH_MEETINGS` | A wall solved during a call or a pairing session, looked up BY TOPIC. |
| `LB_INTERNAL_LIST_MEETINGS` | A wall solved in a specific known meeting, looked up BY NAME. |
| `LB_INTERNAL_GET_MEETING` | The structured summary, for who supplied the fix. Attribution comes from Decisions and Action Items, never from raw transcript. |
| `LB_INTERNAL_GET_MEETING_TRANSCRIPT` | Only when the exact wording of a spoken fix is needed. |
| `LB_INTERNAL_GET_ROUTINE_REPORTS` | Reading past sweep reports so a rejected candidate stays rejected. |
| `LB_INTERNAL_GET_ROUTINE_CONFIG` | Before any routine update, because `prompt` replaces the whole prompt. |
| `LB_INTERNAL_CREATE_ROUTINE` | Offering to create the weekly sweep. |
| `LB_INTERNAL_UPDATE_ROUTINE` | Adding a permanently rejected fingerprint to the routine's do-not-propose list. |
| `LB_INTERNAL_GET_SUBSCRIPTION_STATUS` | Checking the plan gate and whether another routine can be created. |
There is no Littlebird tool that searches past Littlebird chat conversations. Where this
skill needs prior context it uses `search_user_context`.
---
## Trigger
Fires on: "capture what I learned", "log this fix", "add that to my knowledge base", "what
did I figure out this week", "I have solved this before", "stop re-debugging this", "write
up how I fixed that", "did I hit this error before", "what have I been getting stuck on".
Also fires when the weekly sweep report lands and the user opens Cowork to work it.
Does not fire for: documenting a procedure that worked first time, which is `sop-forge`, or
for general note-taking.
---
## Capability gate
This skill requires the **Littlebird MCP on a Power or Pro plan**. Before anything else:
1. **List the tools actually available in this session.** Use the real names you find. The
table above is verified as of 2026-08-17 and is a starting point, not a contract.
2. If no Littlebird tools are present, **stop**. Say the skill needs the Littlebird MCP
connected and that it cannot reconstruct a solve from the user describing it, because
the whole point is the detail they no longer remember.
3. If the plan gate is in doubt, check subscription status before promising a sweep.
4. If the user asks for the weekly routine, check the plan's routine limit first.
There is no degraded mode.
---
## Do this first, every time
Read these two before you touch retrieval:
1. `references/evidence-standards.md` - the receipt format, the observed / inferred /
external / unknown split, the attribution guardrail, the confirmation gates.
2. `references/littlebird-mcp-reference.md` - tool parameters, return shapes, and the
limitations to design around.
Then `references/solve-detection.md`, which governs stages 2 and 3. The other guides load
at the stage that needs them.
---
## Routine cadence
**Weekly.** Friday 16:30 local, so the week is done and the report is waiting on Monday.
The routine observes and proposes. It does not write files, does not ask questions, and
does not append to the knowledge base. Routines cannot do approvals or produce file
deliverables (`references/littlebird-mcp-reference.md`, "Do not ask a routine to do work it
cannot finish unattended in one pass"). The user opens Cowork and this skill does the rest.
The on-demand mode runs the same pipeline against a window the user names, usually "today"
or "yesterday afternoon", right after a session that hurt.
---
## Process
| Stage | Guide | Output |
|---|---|---|
| 1. Fix the window and load the base | this file, `references/kb-structure-and-dedupe.md` section 1 | Window, existing entries, `rejected.md`, staleness flags |
| 2. Six sweeps | Retrieval brief below, `references/solve-detection.md` sections 1 to 2 | Raw retrieval, timestamp-sorted |
| 3. Classify each candidate | `references/solve-detection.md` sections 3 to 5 | Solved / abandoned / other-solved / ai-solved, with confidence |
| 4. **Scrub** | `references/secret-scrubbing.md` | Scrubbed strings, typed placeholders, rotation flags |
| 5. Dedupe | `references/kb-structure-and-dedupe.md` sections 3 to 5, `scripts/kb_index.py --check` | New / update / rejected-already, plus recurrence escalations |
| 6. Draft | `references/entry-schema.md` | Draft entries and draft updates, nothing written |
| 7. Confirm | `AskUserQuestion` | Approved, edited, or rejected, one by one |
| 8. Write and index | `references/kb-structure-and-dedupe.md` sections 4, 6, 7 | Files appended, `rejected.md` updated, `INDEX.md` rebuilt |
Stage 4 runs before stage 5, so no unscrubbed string reaches a comparison or a report.
Stage 4 never gets skipped, not on-demand, not when the user says the session was harmless.
Stage 7 never gets skipped either. See the guardrail.
---
## Retrieval brief
The exact queries. Default window for the weekly routine: the last 7 days. For on-demand,
the window the user names. Split anything longer than about two hours into sub-windows,
because a single broad sweep exceeds the tool result limit and gets dumped to a file
instead (`references/littlebird-mcp-reference.md`, "Oversized results"). Prefer several
narrow parallel queries over one broad one
(`references/littlebird-mcp-reference.md`, retrieval pattern 1).
**Sweep A. Shape of the week.** `search_user_context`,
`filters: {"data_source": "summaries"}`, window fixed. Queries:
`["troubleshooting or debugging session", "blocked on an error", "spent a long time on one
problem"]`. Cheapest compressed view of the period and it names the apps for Sweep B
(`references/littlebird-mcp-reference.md`, retrieval pattern 3).
**Sweep B. Error surfaces.** `filters: {"data_source": "snapshots"}`, same window. Five
narrow queries:
1. `"terminal output with an error message or stack trace"`
2. `"red error banner or failed build output"`
3. `"exception or traceback in the editor"`
4. `"HTTP 4xx or 5xx response in browser devtools"`
5. `"database error, migration failure, or connection refused"`
**Sweep C. The grind.** `filters: {"data_source": "snapshots"}`, same window:
1. `"search engine results page for an error message"`
2. `"Stack Overflow question or GitHub issue page"`
3. `"documentation page for a library or framework"`
4. `"AI assistant chat panel containing code"`
5. `"config file, environment file, or lockfile being edited"`
Query 4 is not optional. It is how the AI-assisted solve gets detected, which is the
highest-value entry type this skill produces
(`references/solve-detection.md` section 4).
**Sweep D. Resumption.** `filters: {"data_source": "snapshots"}`, window extended 24 hours
past the sweep window, because a fix late on Friday shows its success state on Saturday:
1. `"build succeeded or tests passing"`
2. `"deployment succeeded or server started listening"`
3. `"commit message or pull request describing a fix"`
**Sweep E. Human help.** `search_queries_messages` with
`filters: {"data_source": "messages"}`, same window:
`["someone helping debug an error", "sharing a stack trace in a thread", "asking about an
error message"]`. Feeds the solved-by-someone-else branch.
**Sweep F. Historical recurrence, one call per surviving candidate.** `standalone_query`
set to the **scrubbed** literal error string, `date_range` ending where the sweep window
begins and starting as far back as capture goes. This finds occurrences that predate the
knowledge base and is what makes the occurrence log honest
(`references/solve-detection.md` section 5).
**Sweep G, only when a call was involved.** Lookup by NAME uses `LB_INTERNAL_LIST_MEETINGS`
with `name`. Lookup by TOPIC uses `LB_INTERNAL_SEARCH_MEETINGS` with `query`. Using the
wrong one is the most common retrieval mistake against this server
(`references/littlebird-mcp-reference.md`, retrieval pattern 6).
**Then sort by timestamp.** Retrieval is relevance-ordered, not chronological
(`references/littlebird-mcp-reference.md`, known limitations), and the entire detection
method is a time-ordered shape, so an unsorted sweep detects nothing.
---
## Detecting a solve
Full method in `references/solve-detection.md`. The shape, in one table:
| Phase | What it is |
|---|---|
| **A. Surface** | An error string or a failure state appears in capture. |
| **B. Grind** | The error recurs across snapshots while the context churns: searches, docs, issue pages, an assistant panel, config edits, repeated command runs. |
| **C. Cessation and resumption** | The error stops appearing, AND the original work advances without it. |
**Both halves of C are required.** Cessation alone is what abandonment looks like too, and
that single discrimination carries most of the skill's accuracy.
The four outcomes, each filed differently:
| Outcome | Filed as |
|---|---|
| Solved | A full entry. |
| Abandoned | One line in `open-walls.md`. Never a fix entry. |
| Solved by someone else | A full entry, `solved-by: other`, attribution taken from meeting summaries rather than raw transcript. |
| Solved by an assistant, not understood | A full entry, `solved-by: ai-assistant`, `understood: no`, Root cause usually honestly empty. |
That last row is the most valuable capture in the skill. 59% of developers report using
AI-generated code they do not fully understand, from a survey of 800 professionals
[references/research/distilled-personal-knowledge-capture.md section 6], and separately
stated trust in AI tools fell from 40% in 2023 to 29% in 2025 against 84% adoption
[references/research/distilled-personal-knowledge-capture.md section 6]. Those measure
different things and are not merged. The consequence is the point: a fix accepted without
understanding is the one entry the user cannot reconstruct from memory, because no memory
was formed.
**Ambiguous means abandoned.** A missing entry costs one re-debug. A wrong entry costs a
re-debug plus the time spent trusting it.
Detection is a design decision in full. The archive contains no source on detecting a solve
from observational data [references/research/distilled-personal-knowledge-capture.md
section 8]. Say so if the user asks how it works.
---
## Evidence standards
Apply `references/evidence-standards.md` in full. The four that bite hardest here:
- **Receipts on everything** (rule 1), in the form
`[Tuesday, August 11, 2026 23:40 EDT | chrome]`. In this skill the receipt is also a
navigation aid: the user opens that timestamp in the Littlebird app to see the original
screen. Say so once, in the provenance block.
- **Observed, inferred, external, unknown stay visibly different** (rule 2). An error string
read cleanly off a snapshot is observed. A repaired OCR string is inferred. A root cause
concluded from the shape of the fix is inferred and says so. "Understood: no" is always
an inference.
- **Rate what the user will act on** (rule 3). A Low-confidence fix that touches production,
deletes data, or changes billing carries a stop marker telling the reader to verify before
running it.
- **Attribution guardrail** (rule 4). Capture shows what was viewed, not what was written.
A screen share is someone else's machine. A pasted block from an assistant is not the
user's reasoning. Every `solved-by` value is an attribution claim and gets the same
scrutiny.
---
## Secret scrubbing is mandatory and is this skill's top risk
Debugging capture is denser with credentials than any other kind, because credentials are
exactly what you look at when something is broken. A failing API call shows the bearer
token. A refused database connection shows the connection string with the password in it. A
401 shows the client secret. A failed deploy prints environment variables into the build
log.
Worse, **the secret is often inside the error message**, which is the one field this skill
preserves verbatim and makes greppable. The `SEARCH:` line is the highest-risk line in the
artifact.
`references/secret-scrubbing.md` is mandatory reading and the pass is mandatory execution.
The method itself is **inherited by reference** from the redaction-pass guide that ships
inside the `sop-forge` skill in this marketplace, which carries the category taxonomy, the
three-sweep scan, and the evidence behind them. It is not rebuilt here and it is not re-evidenced here.
The deltas that matter in this skill:
1. **Scrub before you compare.** Order is fixed: detect, scrub, compare, draft, confirm,
write. An unscrubbed string must never reach the dedupe check, because the check prints
what it matched.
2. **Never print a matched secret into the transcript.** Not the value, not a prefix, not a
masked form, not "the key ending in 8f2c". Report a count, a category, and a location.
Never ask the user to confirm whether a specific value is a real key.
3. **Structure-preserving placeholders in error strings.**
`Error: connect ECONNREFUSED postgres://[USER]:[PASSWORD]@[DB_HOST]:5432/[DATABASE]`
keeps `ECONNREFUSED postgres` and the port, which is what the user will grep for. Never
`[REDACTED]`. An entry whose commands carry placeholders the reader cannot resolve is a
named failure mode of operational documentation
[references/research/distilled-personal-knowledge-capture.md section 3].
4. **Where scrubbing destroys the search key, say so and lose the key.** Never keep a secret
to preserve searchability.
5. **The rotation flag goes at the top of the sweep report**, naming the field, the time,
and the app. Never the value. Screen capture of a credential is exposure.
6. **The entry persists**, so the floor is higher than for a one-time document. Assume every
entry will eventually be pasted into a chat, because the useful ones are exactly the ones
the user will send to a colleague.
---
## Deduplication, and why recurrence is the point
The same gotcha recurs. A second encounter **updates the existing entry** with a new
occurrence row. It does not create a second entry. Full rules in
`references/kb-structure-and-dedupe.md` section 3.
Run the deterministic first pass:
```
python3 scripts/kb_index.py knowledge-base --check "the scrubbed error string"
```
It normalizes away paths, ids, hashes, line numbers, and ports, keeps version numbers and
error codes because those are the discriminators, scores against every `SEARCH:` line and
title, and checks `rejected.md` in the same call. It matches text, not meaning, so judge
symptom, cause, and fix by hand before merging. The thresholds are a design decision; the
archive has no research on deduplicating personal knowledge base entries
[references/research/distilled-personal-knowledge-capture.md section 8].
**Recurrence escalates.** The occurrence log is not bookkeeping. Google's postmortem
practice runs automated trend analysis across many postmortems precisely so recurrence
becomes visible [references/research/distilled-personal-knowledge-capture.md section 4].
The personal version:
| Occurrences | Report behavior |
|---|---|
| 2 | Noted. |
| 3 | Flagged, with elapsed span and summed lower-bound time cost. |
| 4 or more | Top of the report, above new candidates, with a specific structural fix proposed: a pinned version, a lint rule, a CI check, a removed dependency. |
Keep it blameless. "You have hit this four times, here is the structural fix", never "you
keep making the same mistake". A record that indicts the person reading it stops getting
written [references/research/distilled-personal-knowledge-capture.md section 4]. The
escalation is a proposal. This skill never changes the user's code or config.
---
## Staleness
A fix from two majors ago is a wrong answer the user's own past self vouched for.
This is the best-evidenced risk in the skill. Of measured obsolete answers on a public
platform, 58.4% were already obsolete when first posted and only 20.5% were ever updated,
with an average 118-day lag between someone noticing and anyone acting
[references/research/distilled-personal-knowledge-capture.md section 5]. Third-party
libraries and language versions together account for roughly 63% of obsolescence
[references/research/distilled-personal-knowledge-capture.md section 5]. The authors'
recommendation to writers is exactly what this skill implements: include version and time
information [references/research/distilled-personal-knowledge-capture.md section 5].
Every entry carries pinned versions, a `review-after` date, and a `last-confirmed` date.
Every sweep runs:
```
python3 scripts/kb_index.py knowledge-base --stale
```
and surfaces **at most four** flagged entries, ordered by how much the user loses if the
entry is wrong. A staleness list longer than the candidate list turns the report into a
chore, and a chore gets muted.
Outcomes are reconfirm, revise, or retire. **Retire, never delete**: a retired entry still
answers "did I already decide this does not apply", and deletion destroys the occurrence
history that drives escalation. Full rules in `references/staleness-and-versions.md`.
---
## Output
### The artifact
```
knowledge-base/
├── INDEX.md generated, never hand-edited
├── entries/
│ └── YYYY-MM-DD--kebab-slug.md
├── open-walls.md abandoned problems, one line each
└── rejected.md the rejection ledger
```
Flat `entries/`, one markdown file per entry, filename equal to the entry id. Location
confirmed with the user on first run and recorded; default `knowledge-base/` in the working
directory.
Flat rather than topic folders because the retrieval path is a human running grep for an
error string, and topic folders force a filing decision at write time about a category the
user will not remember at read time. The archive's one concrete personal knowledge base
layout uses topic folders and explicitly does not solve search
[references/research/distilled-personal-knowledge-capture.md section 7]; the practitioner
source that repaired a failing base did it by abandoning topic grouping for
index-by-future-retrieval-context [references/research/distilled-personal-knowledge-capture.md
section 2]. Flat plus tags plus a generated index is a design decision filling that gap.
### The entry
Fixed schema, every field present, empty fields stated rather than dropped. Full template
and worked example in `references/entry-schema.md`.
| Field | Rule |
|---|---|
| **Title** | Names the symptom, not the cause and not the fix. |
Voir sur GitHub