Skip to content

/github-delivery-retro — contract

The skill lives at .agents/skills/github-delivery-retro/SKILL.md; the file under .claude/skills/ is an adapter that points at it. This page is the contract: what the skill guarantees, what it refuses, and how to tell when it is lying.

What it answers

Was this period fruitful, relative to the previous period of equal length? Not "how much happened" — how much of what happened moved the active milestone.

/github-delivery-retro --days 7
/github-delivery-retro --from 2026-08-03 --to 2026-08-10

Read-only. It opens no PRs, edits no issues, and posts no comments.

The measurement stance

Five dimensions, defined in the skill: delivered outcomes, flow, quality, focus, review effectiveness. Every figure is reported as this period → previous period, because a bare number has no interpretation.

Four things are not measured, and the exclusion is the point:

Excluded Because it rewards
Commit count Splitting work
Lines added or changed Verbosity — and punishes deletion, which is often the delivery
Merged-PR count as a standalone score Volume over outcome
Hours, sessions, days active Nothing this skill has any business scoring

Merged-PR count still appears, as an input, next to what those PRs served. The distinction between an input and a score is load-bearing: a founder merging ten small PRs is not more productive than one who closed a release gate, and the verdict rules in §7 of the skill make that fall out of the arithmetic rather than being asserted.

The one rule shared with the Linear skills

A merged implementation PR does not complete a release gate. The gate needs its own acceptance evidence. /github-delivery-retro and /linear-release-audit must never disagree about whether a gate was delivered; if they do, one of them has accepted a PR merge as gate evidence and that is the bug.

Verdicts

Verdict Condition
Fruitful ≥1 release-gate outcome completed with evidence, and the majority of merged work served the active milestone, and no unresolved rework from the window
Low-delivery No gate outcome completed and under half of merged work served the active milestone
Mixed Anything else — stated as which half is which, never averaged into a shrug
Unscoped No milestone could be resolved for the window. The evidence is reported, the verdict is withheld, and the missing scope source is named

Unscoped is not a fourth flavour of bad week — it is the refusal to score one. The other three verdicts all divide by the milestone share, so a run that cannot establish what the milestone was has no denominator and says so.

Scope is resolved as of the window, not as of today

The milestone comes from docs/product/mvp-scope.md as it stood at the window's to, pinned through git history (git log --before=$TO … && git show $SHA:…), or from an explicit caller-supplied --milestone, or the run is Unscoped. Linear is not a fallback: projectMilestone is current state and carries no history, so any Linear-derived milestone figure on a past window is labelled as read-now.

This matters most for windows that predate the scope contract itself (mvp-scope.md first landed on main on 2026-08-07). Scoring one of those against today's milestone silently re-attributes old work and produces a confident wrong verdict — which is exactly the failure Unscoped exists to prevent.

On summary numbers

No single opaque productivity score, ever. If one summary figure is useful it is delivery confidence — how much of the active milestone this window's evidence supports — and it ships with its inputs visible so a reader can disagree with a component rather than with a verdict.

It is not a statement about a person. It is not comparable across people, it does not stand in for effort or hours, and it is not a performance metric. A week spent deleting a dependency, reading a source, or proving that a planned approach does not work can be the most valuable week of a release and will score low. When that happens, the report is required to say so.

How to tell when it is lying

The failure mode is a report that reads as improvement because activity rose. The fixtures under .agents/skills/github-delivery-retro/fixtures/ are built to catch exactly that: the current window merges 7 PRs against the previous window's 3, and must still come out Low-delivery, because it completed no gate, served the milestone with 2 of 7 merges, and spent two of them reworking the prior week.

The fixture's milestone is caller-supplied, and the dry run only holds on that condition. Those windows sit in July 2026, before mvp-scope.md existed, so the git-pinned lookup finds nothing: a live run over the same dates without --milestone "MVP-1 release gate" is correctly Unscoped, not Low-delivery. The fixtures carry the milestone inline precisely so the dry run tests the verdict arithmetic rather than the scope lookup. Reading the fixture's Low-delivery as unconditional is the one way to mistake it.

Three further traps are built into the fixture data, each catching a rule prose cannot enforce: PR #219 merges at exactly the window's exclusive to and must be excluded under [from, to); the ci.runs counts deliberately disagree with the per-merge ci_at_merge values so that using them as the CI denominator fails; and PR #216's checks complete after its mergedAt, so it belongs in the merged before checks completed bucket rather than the green one.

That third bucket exists because statusCheckRollup is check state at read time, not at merge. A PR that merged before its checks finished looks identical to one that waited, unless every check is filtered to completedAt ≤ mergedAt first — so "CI green at merge" is reported as three buckets, green / red / merged-before-checks, and the last is never folded into the first.

Run the fixture dry run after any edit to the skill. If the verdict comes back Fruitful or Mixed, the edit broke it — and if it comes back Low-delivery while the report claims the scope was git-pinned, the scope label is wrong even though the verdict is right.