# Second Brain Checkup

> Reconciles the second-brain KB (pending-actions.md, active-threads.md, rolling-context.md) against recent activity, scores quick wins, and flags what's gone stale. Use when the user says "check my pending actions", "second brain checkup", "what's stale", "what have I not done", "quick wins", or wants a status check on open threads or action items. Also called by `daily-briefing` (start of day) and `session-log` (end of day). Do NOT use for external-source recaps (Jira/GitHub/Slack status) -- that's `standup-writer`. Do NOT use for filing new content into the wiki -- that's `second-brain-ingest`.

- Skill: `jaquevan/second-brain-checkup` (Agent Skill, multi-file: 17 files)
- Install (CLI): `npx skillmds@latest add jaquevan/second-brain-checkup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jaquevan/second-brain-checkup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: jaquevan (https://skillmd.com/u/jaquevan)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/jaquevan/second-brain-checkup

---


# Second Brain Checkup

Reads the second-brain KB, reconciles it against real evidence, and reports
back -- this replaces what used to be manual grep archaeology every time
someone asked "what have I said I'd do that I haven't done."

## Step 1: Read the KB

Read all three files:
- `~/second-brain/pending-actions.md`
- `~/second-brain/active-threads.md`
- `~/second-brain/rolling-context.md`

**Minimum-evidence gate:** if `pending-actions.md`'s `## Open` section is
empty and `active-threads.md` has no threads, say so plainly ("nothing open
right now") and stop. Don't fabricate a checkup from nothing just to have
something to report.

## Step 2: Gather corroborating evidence (silent)

For each open item and thread, look for signals that resolve its status.
Gather everything before presenting anything -- don't narrate this step.

| Signal source | What to check | How |
|---|---|---|
| Recent wiki pages | Does a later meeting/page mention this item as done, superseded, or still pending? | Grep `~/second-brain/wiki/*.md` for keywords from the item; use `tags.md` first if the item names a known project/person (same fast-path `second-brain-wiki` already uses), prefer pages newer than the item's `captured` date |
| Jira (if linked) | Ticket status | Reuse `work-context`/`sprint-manager` query patterns, don't reimplement |
| Git activity (if linked) | Recent commits/PRs matching the item | Reuse `standup-writer` Step 2b patterns, don't reimplement |

## Step 3: Reconcile pending-actions.md

Follow [references/reconciliation-heuristics.md](references/reconciliation-heuristics.md)
for the exact rules. In short: a recurring unresolved mention across meetings
means still open; an explicit later confirmation means resolved; an explicit
supersession by a newer decision means dropped, not open; 14+ days untouched
with no signal either way means stale and worth a direct status check.

Move items between `## Open`, `## Stale`, `## Dropped`, and `## Resolved` --
move, don't duplicate. Delete from the old section when adding to the new
one; leaving it in both places is exactly the kind of half-reconciled state
this whole skill exists to prevent. Dropped and Resolved are not the same
thing: Dropped means the work was never done but a later decision
explicitly superseded it (see the reconciliation-heuristics.md example);
Resolved means the work actually happened. Don't fold a dropped item into
Resolved even if that seems tidier -- it misrepresents the history for
anyone who looks back at it later.

## Step 4: Update active-threads.md

For each thread, update `Last touched` and `Status` if Step 2 found new
activity. Mark a thread `stalled` (not `dropped`) when it's gone quiet
without an explicit resolution -- `dropped` is reserved for threads with an
actual decision to stop, the same distinction `pending-actions.md` uses for
resolved-vs-dropped items.

## Step 5: Refresh rolling-context.md

**Overwrite**, don't append, the `## Right Now`, `## Recent Decisions`, and
`## Top Open Threads` sections, per
[second-brain-ingest/references/kb-files.md](../second-brain-ingest/references/kb-files.md)'s
format rules. This file answers "what's true right now" -- if you're adding a
dated entry instead of replacing content, you're writing to the wrong file.

## Step 6: Score Quick Wins

Run the scoring script rather than re-deriving the arithmetic by hand each
time -- the point rules are fixed, so the score shouldn't vary run to run:

```bash
python3 scripts/score_quick_wins.py <path-to-pending-actions.md>
```

The script handles the additive scoring and the "explicitly blocked" /
"multi-step despite short wording" disqualifications from
[references/quick-wins-scoring.md](references/quick-wins-scoring.md)
mechanically. It can't see context outside the item's own text, though --
if a linked Jira ticket or wiki page changes the picture (e.g. the ticket
is actually still in early development despite short-sounding wording, or
a blocker mentioned elsewhere has since cleared), adjust the script's
output using that context rather than treating its score as final. Surface
the top 3-5 highest-scoring, non-disqualified items only -- the goal is
momentum, not a ranked spreadsheet of everything open.

## Step 7: Present and confirm

Present the narrative summary below. **Only if** an item's status is
genuinely ambiguous after Steps 2-4 (no evidence either way, not just
cleanly "still open"), ask about all such items in a single bundled
`AskQuestion` call -- never one at a time. Most checkups won't reach this
step at all; don't manufacture a question just to have one.

**Running unattended (headless, e.g. the daily launchd job):** there's no one
to ask. Instead of `AskQuestion`, write a short "Needs your confirmation"
bullet list into `rolling-context.md` for the ambiguous items and skip the
chat presentation -- the next time Evan opens a session, `rolling-context.md`
already has the question waiting rather than it being lost when the headless
run ends.

## Output Template

```
**Second Brain Checkup — YYYY-MM-DD**

**Still open (N):**
- <item> (<age> days old, last mentioned in <page>)

**Newly resolved (N):**
- <item> -- <how you know: quote or link the evidence>

**Stale, worth a direct check-in (N):**
- <item> (<N> days untouched, no signal either way)

**Quick wins (top 3-5):**
1. <item> -- <why: size/keyword/status signal>

**Threads:** <1-2 line summary of active-threads.md status changes, if any>
```

If nothing changed since the last checkup, say that plainly instead of
padding the output with restated old information.

## Example: good vs bad checkup output

**Good** (real data, abbreviated):

```
**Second Brain Checkup — 2026-07-21**

**Still open (2):** Define UX Spec format with <COLLEAGUE_1>/Yahav (5 days old);
Contact Peter Kiser re: OpenShift outcomes (8 days old, restated 07-17).

**Stale, worth a direct check-in (2):** Research Amplitude integration
(15 days since the explicit "next sprint" deferral, no follow-up since);
Build the evidence viewer (19 days, never mentioned again).

**Quick wins (1):** Contact Peter Kiser -- single email, no dependency,
restated twice without action.

**Threads:** Amplitude Integration Research moved from active to stalled,
consistent with the pending-actions change.
```

Specific counts, specific ages, specific evidence for every status change.
A reader can act on this without opening any file.

**Bad** (same underlying data):

```
**Second Brain Checkup — 2026-07-21**

I checked your pending actions and threads. Everything looks mostly on
track, though a couple of things have been sitting for a while and might
be worth revisiting. Let me know if you want me to dig into anything
specific!
```

No counts, no ages, no evidence, no quick wins, nothing the reader can act
on without asking a follow-up question -- exactly the kind of vague output
this skill exists to replace.

## Anti-patterns

- Asking about each ambiguous item one at a time instead of one bundled form.
- Re-scanning every wiki page from scratch instead of using `tags.md` first.
- Presenting a checkup with zero real findings as if something was found --
  the minimum-evidence gate in Step 1 exists specifically to prevent this.
- Deleting a resolved or dropped item immediately instead of keeping it in
  `## Resolved` / `## Dropped` for ~30 days -- the goal is to stop it from
  being re-asked, not to erase the record immediately.
- Folding a dropped item into `## Resolved`, or inventing a new section name
  for it instead of using the documented `## Dropped` -- found in the first
  eval run: with no dedicated section documented, the skill invented one on
  its own, inconsistent with what earlier runs had done.
- Marking an item `resolved` because it "seems old enough that it's probably
  done." Age alone is a `stale` signal, not a `resolved` one -- resolved
  requires an actual piece of evidence, quoted or linked.

## Non-negotiable rules and their excuses

| Rule | Excuse the model will reach for | Rebuttal |
|---|---|---|
| Minimum-evidence gate: don't report anything if the KB is empty | "The user asked for a checkup, so I should produce a full report even if it's thin" | An empty KB producing a thin report is fine; an empty KB producing a fabricated one is not. Saying "nothing open right now" IS the correct report -- it's not a fallback for when you can't do the real job. |
| Resolved requires quoted/linked evidence, not age | "This item is 20+ days old, it's probably been handled by now" | Age is exactly the `stale` signal, not a `resolved` one. If you mark it resolved on a guess and you're wrong, the real work silently drops off the list -- the failure mode is worse than leaving it open or stale one more cycle. |
| Dropped items get their own `## Dropped` section, not folded into Resolved | "Resolved already covers 'this isn't happening,' a new section is unnecessary overhead" | Found in the first eval run: this exact rationalization led to inventing a third, undocumented pattern instead of using either the documented section or the existing one -- neither consistent nor simpler. Use `## Dropped`, it's real. |

## Common Mistakes

| Problem | Fix |
|---|---|
| Treating this like `session-log`'s carry-forward (per-day diffing) | This reconciles a single rolling file, not dated log entries -- there's no "yesterday's version" to diff against, just the current KB state vs. current evidence |
| Reimplementing Jira/GitHub query logic | Compose with `work-context`/`sprint-manager`/`standup-writer` patterns -- this skill's job is reconciliation and scoring, not data collection from scratch |
| Running the full checkup when called from `daily-briefing`/`session-log` | Those callers only need Steps 1, 3-6 output folded into their own format -- skip Step 7's chat presentation and `AskQuestion` when composed into another skill's flow; let the caller decide how to surface ambiguity |

