feat(skills): lead every run report with a TL;DR - #212
Conversation
A run report is read once, in a terminal, and all eight report-producing skills opened straight into their first group — so how much was found, how much was acted on and what decision is being asked for only emerged by reading every group and adding it up. validate-skills had already written the roll-up and put it last, after the findings it was meant to frame. Add a sixth mirrored block, scripts/tldr-block.md -> <skills-tldr>, on the mechanic the other five use: the report opens with a TL;DR carrying the counts, what the run acted on and the ask, before the first group, and names whatever the run could not establish. The roster is a strict subset of the plan block's — a skill leads with a result only where it closes by reporting one — and test/isolation.test.ts asserts both the roster and that containment. Refs #176
The issue asked for two things in order: an evaluation of what each report-producing skill opens with today, and a choice between reusing the tldr skill and adding a shared block. Both belong in the log — the survey is what makes the choice decidable, and without it the block reads as a convention nobody weighed an alternative against. Records why tldr was not called: it summarises on request, owns its whole output and sources it from the conversation and git, while a report's lead is made of facts only the producing run holds. Refs #176
AI review — changes requested (round 1 of 3, head
|
The block landed as the tenth generated artifact, but three of the four places that state the count were left at nine: the `skills:sync` row of the Commands table (seven lines above the paragraph that already said ten), the generator's own header comment and its silent-`--write` warning. `skills/README.md` carried a fourth statement — stale count and an enumeration that never mentioned the block at all, which is the one CLAUDE.md points a contributor at for the skill contract. No test catches any of this: `skills:check` compares generated blocks, and the CLAUDE.md/AGENTS.md mirror test passes on two files stale in the same way. Refs #176
The plan block called itself the only mirrored contract about a skill's output, and the report-lead block three lines below falsifies that — its own comment already describes the two as halves of one pair. The ordinal stands as history; the exclusivity does not, and it sat directly above the block that broke it. Refs #176
Re-work — round 1 feedback addressed (head
|
| # | Item | Fix |
|---|---|---|
| 1 | CLAUDE.md / AGENTS.md contradict themselves |
The pnpm skills:sync row now reads ten, matching the paragraph seven lines below. Fixed in CLAUDE.md and copied with cp CLAUDE.md AGENTS.md — diff prints nothing. |
| 2 | skills/README.md:57 says nine, block missing from the enumeration |
Now Ten, with scripts/tldr-block.md added to the list as the report-lead rule, carrying the same strict-subset clause the other two statements use. |
| 3 | scripts/gen-skills.ts plan-block comment claim is false |
"the only one about the skill's output" → "the first about the skill's output — the one below is its other half", and "Every other contract here" → "The four contracts above". The ordinal is kept as history, as suggested; only the exclusivity is narrowed, folded into the pairing the new comment already describes. |
Two further instances of item 1's drift, same file as item 3. The review named three places; a sweep for the count found two more that the change had made stale, both in scripts/gen-skills.ts — the header comment (projects them into nine artifacts, now ten, with the report-lead rule appended to its enumeration) and the silent---write warning at the ENOENT guard (all nine artifacts, now ten). Fixed here rather than left, since they are the same defect the review blocked on.
Two stale counts deliberately left alone, because they predate this branch and are not this change's drift — test/gen-skills.test.ts:1 says seven and skills/meta/validate-skills/REFERENCE.md:259 says six, both already wrong on dev before this branch existed. docs/99.adr/0011 says seven too and is correct as an append-only record of its own moment.
Test discipline
The round is comment- and prose-only — four files, no behaviour touched, scripts/gen-skills.ts changed only inside comments — so tdd was not driven, per the prose-only rule. No new seam exists to test: the defect class is a prose count no gate reads, which is exactly why the review had to catch it.
pnpm verify re-run in a throwaway worktree installed from the head's own lockfile (pnpm install --frozen-lockfile): exit 0, 181 tests, 0 failures. pnpm skills:sync reports the registry already in sync (22 skills); diff CLAUDE.md AGENTS.md is empty.
AI review — accepted (round 2 of 3, head
|
ADR numbers are claimed on a branch and collide only once two branches are open at the same time. #212 took 0026 first and #213 had already moved to 0027, so the older claim keeps its number and this one takes the next free: 0028, checked live against `dev` and every open pull request rather than against the tree this branch started from. Refs #185
…th-a-tldr # Conflicts: # AGENTS.md # CLAUDE.md # docs/99.adr/index.md # scripts/gen-skills.ts # test/gen-skills.test.ts # test/isolation.test.ts
Summary
Every skill whose run ends in a report now opens it with a TL;DR, before the first group.
Step 1 — the evaluation the issue asked for first. All eight report-producing skills opened straight into their first group, so "no TL;DR" is the house default rather than a prune-specific gap:
prune-branchesprune-commentsmerge-depsupdate-depsvalidate-skillsreleasework-implement-queuework-review-queuevalidate-skillsis the evidence the need is real: it had already written the roll-up and placed it after the twenty findings it was meant to frame.Step 2 — the mechanism: a shared block, not a call into
tldr.tldrsummarises on request, owns its whole output, and sources it from the conversation and git state — while a report's lead is made of facts only the producing run holds (which branches, on which side, held for which reason). A call would have to hand the summariser every fact it was to summarise. Sotldris left untouched and named as the frame this shares, and the rule becomesscripts/tldr-block.md→<skills-tldr>, the sixth mirrored block, on the mechanic the other five already use.The roster is a strict subset of the plan block's — a skill leads with a result only where it closes by reporting one; a plan awaiting a yes already opens with what it proposes.
tldris the one deliberate absence that is not about the criterion: the frame is its whole product, already fixed in its own workflow.Reasoning recorded in ADR-0026.
Type of change
Checklist
pnpm verifypasses locallySKILL.mdupdated (description, examples)Related issues
Refs #176
Test discipline
Prose is most of this change, but the roster and the generator wiring are code, so the loop was driven where a test reaches. The issue body supplied the seams outright — "a shared block … mirrored into each report-producing skill, exactly as
plan-block.md… already [is]" and "rosters intest/isolation.test.ts" — which named both the mechanism under test and the file that asserts it.Red first: the roster assertion in
test/isolation.test.tsand thetldr blockartifact expectation intest/gen-skills.test.tswere written and run before the block existed, failing withactual: []against the eight expected carriers. Green after the block, the generator wiring and the fixture landed. Three assertions were added — the roster matches the tags on disk, every tldr carrier also carries the plan block (so a report can never have a specified lead and an unrenderable body), and no link inside the block leaves the skill folder.pnpm verify— 181 tests, exit 0.