Skip to content

feat(skills): recent-work, a wrap-up that offers to onboard, and a repo-first check-follow-ups - #45

Merged
dimeloper merged 2 commits into
mainfrom
feat/recent-work-and-onboarding-ask
Sep 18, 2026
Merged

dimeloper merged 2 commits into
mainfrom
feat/recent-work-and-onboarding-ask

Conversation

@dimeloper

@dimeloper dimeloper commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Three read-side gaps, all in something a session already knows and never says.

recent-work — what the daily notes say was achieved

The mirror of check-follow-ups. That one answers what is still open; this answers what got done, from the same notes, the same window rule (notes back, not days back, so a weekend or a vacation costs nothing), the same attribution and the same group-never-filter discipline.

  • Reads each note's ## Built bullets and the ## Follow-ups ticks that closed, newest first — there, age is the finding; here, the most recent thing is what a status update leads with.
  • This repo in full, every other repo as a count. --full expands, --repo reports on one you are not standing in, and the total is stated before any grouping.
  • make recent-work, NOTES=n for a wider window, SINCE=YYYY-MM-DD for a calendar span (a sprint, a month).
  • A #outcome/dropped or #outcome/handed-off tick is never reported here. The tick records that nobody did the work; listing it as an achievement is the inverse of what it says. superseded is reported and labelled, and a bare - [x] counts as done, as it always has.
  • The footer says how many notes in the window had no ## Built section at all — a thin record and a quiet week read identically in a summary and lead to opposite conclusions.

A ## Built (<repo>: …) label now attributes its own section's items. note_context_repo deliberately refuses to answer for a day with two labelled streams — it is a question about the whole note — so every bullet on such a day landed in "no repo identified" while the heading two lines above it named the repo.

check-follow-ups is repo-first by default, and says what to do next

Standing in a repo and asking what is open is one question, and it was taking two: run the check, then ask it to focus on this repo. --brief computed exactly the right shape and was opt-in, so the common case printed thirteen fully-described items from three other repos whenever the flag was forgotten.

  • --recent is now brief by default. --full lists every repo's items; --brief still works and now collapses the long-range audit too; the two together are refused rather than resolved.
  • The --stale-days audit is unchanged, so make audit and a vault's CI print exactly what they did. That one is a sweep, and it usually runs where there is no repo to be relative to.
  • A repo-scoped run ends with Next: at most four lines, from what the report already computed — a blocker to clear first, work the repo says already landed and should be confirmed, the oldest item still open here, and how many have been open past three weeks and are worth re-deciding (closing one #outcome/dropped is a real answer).

Each Next line points at an item by date, never by repeating its text. Every item appearing exactly once is what makes this report readable, and a suggestions block that re-lists items breaks it the same way the "blockers first" section did. Nothing is ticked: the landed line says confirm, because the evidence is about the ref and the item usually says more than the ref does. The block is absent when there is nothing to suggest, when there is no repo, and in the audit — an invented next step is worse than none.

A wrap-up in a repo that was never onboarded says so, once

update-second-brain asks onboarding-state.py in Step 1 and, when the answer is not-onboarded, offers in a new Step 5b: shared, quiet (--local, so the repo's remote never sees the rules), not now, or never for this repo. It picks none of them — shared and quiet differ in who else ends up seeing those files.

The question comes after the capture is committed and pushed, never before. A question is a place a session can stop, and a wrap-up that stops before its commit is the exact failure Step 5 exists to prevent.

"Never for this repo" is recorded in ${XDG_CONFIG_HOME:-~/.config}/second-brain-workflow/onboard-declined — same format as the repo registry beside it, optional reason, --undecline to reverse. A separate file rather than a registry field: the registry is the set of repos this machine rendered into, and a mode value meaning "none" is one render.py is right to refuse. It stops a prompt and never an instruction — onboard-repo does not read it, so "onboard this repo" always wins.

make doctor reports the list's size on a clean run and make uninstall leaves it alone, because a decision nothing ever mentions is one nobody can undo. unrender-repo points at it too: a retired repo otherwise reads as never-onboarded and gets re-offered at the next wrap-up.

Supporting changes

  • lib/followups.py reads any of a daily note's list sections, not only ## Follow-upssection_items, labelled_sections, heading_repo; collect_spans takes an optional heading and is otherwise unchanged. One parser, so the two sides cannot disagree about what an item is.
  • registry.py gains rendered() (the Python mirror of sbw_registry_marker_present) and write_entries(), one atomic writer shared by the registry and the never-ask list. tests/test-repo-registry.sh now asserts all three copies of the provenance marker are the same string.
  • Docs: REFERENCE gains What got done, from the same notes and Is this repo onboarded at all?; the skill counts move seven → eight and four → five; AUDIT records which default changed and which did not.

Testing

make check green. 79 new assertions — tests/test-onboarding-state.sh (36), tests/test-recent-work.sh (28), 15 in test-check-followups.sh, plus test-doctor.sh and test-repo-registry.sh — and a fixture vault of its own so no existing count shifts. Two existing tests now pass --full, since they assert on items in other repos and the window collapses those by default.

After merging, make sync-skills installs recent-work; it stays invisible until an agent restart.

🤖 Generated with Claude Code

Two read-side gaps, both in what a session already knows and never says.

recent-work — what the daily notes say was achieved. The mirror of
check-follow-ups: same notes, same window rule (notes back, not days back),
same attribution, same group-never-filter. It reads each note's ## Built
bullets and the ## Follow-ups ticks that closed, newest first, this repo in
full and every other repo as a count. make recent-work, NOTES=n for a wider
window, SINCE=YYYY-MM-DD for a calendar span.

A #outcome/dropped or #outcome/handed-off tick is never reported as an
achievement — the tick records that nobody did the work, so listing it is the
inverse of what it says. superseded is reported and labelled; a bare `- [x]`
counts as done, as it always has.

A `## Built (<repo>: …)` label now attributes its own section's items.
note_context_repo deliberately refuses to answer for a day with two labelled
streams — it is a question about the whole note — so every bullet on such a day
went to "no repo identified" while the heading two lines above named the repo.

update-second-brain now asks onboarding-state.py in Step 1 and, when the repo
has never been rendered into, offers in a new Step 5b: shared, quiet (--local),
not now, or never for this repo. It picks none of them; shared and quiet differ
in who else ends up seeing those files. The question comes after the capture is
committed and pushed, never before — a question is a place a session can stop,
and a wrap-up that stops before its commit is the failure Step 5 exists to
prevent.

"Never for this repo" is recorded in a never-ask list beside the repo registry,
same format, optional reason, --undecline to reverse it. A separate file
because the registry is the set of repos this machine rendered into, and a mode
meaning "none" is one render.py is right to refuse. It stops a prompt and never
an instruction: onboard-repo does not read it. doctor reports its size on clean
runs and uninstall leaves it alone, because a decision nothing mentions is one
nobody can undo. unrender-repo points at it too — a retired repo otherwise
reads as never-onboarded and gets re-offered at the next wrap-up.

lib/followups.py now reads any of a daily note's list sections rather than only
## Follow-ups; registry.py gains rendered() and write_entries(), one atomic
writer shared by both lists, and the marker-drift test covers all three copies
of the provenance string.
Standing in a repo and asking what is open is one question, and it was taking
two: run the check, then ask it to focus on this repo. --brief computed exactly
the right shape and was opt-in, so the common case printed thirteen
fully-described items from three other repos whenever the flag was forgotten.

--recent is now brief by default: this repo's items in full, every other repo as
a count. --full is the way to every item; --brief still works and now collapses
the long-range audit the same way. The --stale-days audit's default is
unchanged, so make audit and a vault's CI print what they always did — that one
is a sweep, and it usually runs where there is no repo to be relative to.

A repo-scoped run also ends with Next: at most four lines, from what the report
already computed. A blocker to clear first, work the repo says already landed
and should be confirmed, the oldest item still open here, and how many have been
open past three weeks and are worth re-deciding — closing one #outcome/dropped
is a real answer, and a list of open items never said so.

Each line points at an item by date and never repeats its text. Every item
appearing exactly once is what makes this report readable, and a suggestions
block that re-lists items breaks it the same way the "blockers first" section
did. Nothing is ticked either: the landed line says confirm, because the
evidence is about the ref and the item usually says more than the ref does. The
block is absent when there is nothing to suggest, when there is no repo, and in
the audit — an invented next step is worse than none.
@dimeloper dimeloper changed the title feat(skills): recent-work, and a wrap-up that offers to onboard feat(skills): recent-work, a wrap-up that offers to onboard, and a repo-first check-follow-ups Sep 18, 2026
@dimeloper
dimeloper merged commit 64f3c57 into main Sep 18, 2026
4 checks passed
@dimeloper
dimeloper deleted the feat/recent-work-and-onboarding-ask branch September 18, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant