Skip to content

Nothing checks the story-coverage figures in CONTRIBUTING.md, which is how they drifted #229

Description

@vladimirrott

Corrected 2026-09-03 at 60af0ad. This issue was filed on 2026-08-17. PR #242 landed the next day and fixed two of the three claims below. One is still wrong, and the guard the issue asks for still does not exist. The original text is kept underneath so the history reads straight.

CONTRIBUTING.md publishes story-coverage figures that nothing derives from the story files.

What is still wrong at 60af0ad

CONTRIBUTING.md:50 says:

The suite is 133 stories: 54 atomic + 79 Ubuntu. Every Debian-only action now has one.

CONTRIBUTING.md:47, four lines above it in the same table, says the opposite:

Remaining: story coverage for the cross-family actions, and five Debian-only ones that still have none: the four fail2ban actions and GrubSetKargs.

Line 47 is the true one. Recounted at 60af0ad:

$ for a in Fail2banStatus Fail2banBanIp Fail2banUnbanIp ConfigureFail2banJail GrubSetKargs; do
    echo "$a: $(grep -rl "\"$a\"" tests/e2e/stories/ | wc -l)"
  done
Fail2banStatus: 0
Fail2banBanIp: 0
Fail2banUnbanIp: 0
ConfigureFail2banJail: 0
GrubSetKargs: 0

The story totals and the uncovered counts are correct today. Both recounted at 60af0ad:

$ ls tests/e2e/stories/story-*.sh | wc -l
133
$ # family from each story's own header line
ubuntu=79 atomic=54

and the derivation below now returns {'All': 59, 'Fedora': 10, 'Ubuntu': 5}, which is what CONTRIBUTING.md:50 prints.

So the numbers are right and nothing keeps them right. They were wrong for a day in August, somebody fixed them by hand, and the next story added or retired puts them back out.

The guard, which is the part worth doing

scripts/check_evidence_claims.py has no rule that derives an uncovered-action count. Its checks at 60af0ad:

$ grep -nE '^def check_' scripts/check_evidence_claims.py
124:def check_figure
149:def check_bare_test_totals
194:def check_story_claims
261:def check_bare_story_counts
306:def check_action_figures
382:def check_validated_tiers

check_bare_story_counts matches \b([0-9]{2,})[-\s]stor(?:y|ies)\b, so it catches "133 stories" and misses "59 are still untouched by any story" and "54 atomic". The guard is sound; the claim shape slips past it.

Scope

  • Fix the contradiction: CONTRIBUTING.md:50 still claims every Debian-only action has a story.
  • Add a check_evidence_claims.py rule that derives the uncovered counts and the family split from the tree, so neither can drift again. The derivation in the original text below is the whole implementation.

Tests first

Feed the checker a CONTRIBUTING.md fixture carrying a wrong count and assert it fails naming both figures, the published one and the derived one. A test that only exercises the agreeing case proves nothing, since that is the state the file is in today. Prove the rule bites by changing the published number and watching the checker go red, and again by adding a story file and watching it go red the other way.

Difficulty

medium. The documentation half is a two-line edit; the guard rule is the work.


Original text, filed 2026-08-17, before #242

CONTRIBUTING.md publishes two coverage figures and one prose claim about story coverage. All three are wrong.

The prose claim

Remaining: story coverage for the cross-family actions. The Debian-only ones are all covered now.

Five Ubuntu-family actions have no story: Fail2banStatus, Fail2banBanIp, Fail2banUnbanIp, ConfigureFail2banJail and GrubSetKargs. The fail2ban four are the subject of #219, which exists because of this gap.

The figures

of the action names available on both families, 57 are still untouched by any story, plus 8 Fedora-only ones.

Derived from the catalogue and the story files:

family uncovered CONTRIBUTING says
All (both families) 59 57
Fedora only 10 8
Ubuntu only 5 not mentioned
total 74 65

Derivation, from a clean checkout:

python3 - <<'PY'
import re, glob
rows = re.findall(r'^\| `([A-Za-z0-9_]+)` \|.*?\| (All|Ubuntu|Fedora) \|',
                  open('docs/action-reference.md').read(), re.M)
named = set()
for f in glob.glob('tests/e2e/stories/*.sh'):
    named |= set(re.findall(r'"([A-Za-z0-9_]+)"', open(f, errors='replace').read()))
from collections import Counter
print(Counter(d for n, d in rows if n not in named))
PY

Two caveats a fixer should keep: this counts an action as covered if its name appears as a quoted literal anywhere in a story, which over-counts, because ConfigureWifi, GrubSetKargs and SetLocale appear only in "must not confuse with" comments. And covered-by-any-story is not the same as exercised-on-Ubuntu: 98 of the 164 Ubuntu-and-All actions are named by no ubuntu-family story.

Why the guard missed it

CONTRIBUTING.md is in CLAIM_FILES (scripts/check_evidence_claims.py), so this is not an unguarded file. check_bare_story_counts matches \b([0-9]{2,})[-\s]stor(?:y|ies)\b, and neither "57 are still untouched by any story" nor "all covered now" presents a number next to the word it looks for. The guard is sound and the claim shape slipped past it.

Scope

  • Correct the three claims in CONTRIBUTING.md.
  • Consider deriving them instead of writing them, the way docs/action-reference.md is generated. A check_evidence_claims.py rule for "N ... untouched by any story" would keep the number honest, and the derivation above is already the whole implementation.

Difficulty

easy as a documentation fix. medium if you also add the guard rule, which is the version worth doing.

Getting started

CONTRIBUTING.md has the build and test commands. No CLA and no copyright waiver. The project is MIT.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

claimedSomeone has said in the thread that they are working on thisenhancementNew feature or requestgood first issueGood for newcomersmediumDifficulty: needs familiarity with one subsystem

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions