You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Recounted 2026-09-21 at ba1a7b8f. Every figure below still holds. One
sentence in the caveat section said all three named actions sit in the
uncovered set; GrubSetKargs left it when story 138 landed, which the cluster
list already said. Corrected so the two halves agree.
Recounted at 30b9e315 on 2026-09-17.#447 landed story 138 and closed the
GRUB cluster, so every figure below moved again: uncovered 62 to 61, off-Ubuntu
96 to 95, 83 ubuntu-tagged files to 84, next free id 138 to 139. The numbers in
the first version of this issue (164 / 64 / 98, 189 rows, 79 ubuntu-tagged
files, next id 134) and the 2026-09-16 recount at b2c823e6 (62 / 96 / 83 /
138) are both superseded by the ones now in the text.
61 of the 166 Ubuntu-and-cross-family actions are named by no story at all, and 95 of them are named by no story that runs on Ubuntu. This issue is the map, so the work can be taken one cluster at a time.
Derivation
python3 - <<'PY'import re, globfrom collections import Counterrows = re.findall(r'^\| `([A-Za-z0-9_]+)` \|.*?\| (All|Ubuntu|Fedora) \|', open('docs/action-reference.md').read(), re.M)U = {n for n, d in rows if d in ('All', 'Ubuntu')}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()))ub = [f for f in glob.glob('tests/e2e/stories/*.sh') if re.search(r'^# Story \d+ \([^)]*ubuntu[^)]*\)', open(f, errors='replace').read(), re.M)]named_ub = set()for f in ub: named_ub |= set(re.findall(r'"([A-Za-z0-9_]+)"', open(f, errors='replace').read()))print('|U| =', len(U), 'uncovered =', len(U - named), 'not on ubuntu =', len(U - named_ub))PY|U| = 166 uncovered = 61 not on ubuntu = 95
Catalogue split: 191 tabled rows, All 99, Ubuntu 67, Fedora 25. 84 story files carry an ubuntu header tag.
One honest caveat, and one I withdraw.
I wrote that the derivation over-counts, because it treats a quoted literal
anywhere in a story as coverage, and named ConfigureWifi, GrubSetKargs and SetLocale as actions carried only by "must not confuse with" comments. That is
wrong and was wrong when I filed it. All three appear unquoted in prose comments,
so the regex never saw them. ConfigureWifi and SetLocale are still in the
uncovered set where they belong; GrubSetKargs left it when story 138 landed in #447, and the cluster list below records that. No action in the catalogue has its only quoted occurrence on
a comment line, so the figure is not inflated by that mechanism at all.
The caveat that does hold: 34 Ubuntu-and-All actions are covered only by stories 1 to 54, the atomic family, which no recorded Ubuntu run includes, so AptListUpgradable, a Debian-only action, has its sole coverage in a Fedora-family story.
Pick a cluster, write one story per action, and record on Ubuntu the way the current 84 run:
UBUNTU_RELEASE=noble ./tests/e2e/ubuntu-vm.sh
Then commit the cassette and its replay twin so the suite still runs offline. run-stories.sh accepts story numbers, so you can record only yours. Any of the seven *_API_KEY variables the runner recognises works; no credentials are needed from the maintainer.
The header decides the family and a wrong one fails silently, so use # Story <id> (ubuntu, <read-only|medium-risk|high-risk>): <name> and check that bash tests/e2e/run-stories.sh --metadata puts your story in the ubuntu family. Next free id is 139.
Start with a read-only cluster if this is your first story. GetMounts, GetSysctl and GetListeningPorts need no approval receipt and exercise the whole chain.
Worth fixing alongside
Nothing compares the story set against the action catalogue, which is why this drifted unnoticed. The derivation above is small enough to become a gate, and it would keep the number in #229 honest at the same time.
Difficulty
medium per cluster. The harness and the pattern exist; the work is writing intents and recording a clean pass.
Getting started
CONTRIBUTING.md has the build and test commands, and its E2E section covers the VM harness. No CLA and no copyright waiver. The project is MIT.
61 of the 166 Ubuntu-and-cross-family actions are named by no story at all, and 95 of them are named by no story that runs on Ubuntu. This issue is the map, so the work can be taken one cluster at a time.
Derivation
Catalogue split: 191 tabled rows,
All99,Ubuntu67,Fedora25. 84 story files carry anubuntuheader tag.One honest caveat, and one I withdraw.
I wrote that the derivation over-counts, because it treats a quoted literal
anywhere in a story as coverage, and named
ConfigureWifi,GrubSetKargsandSetLocaleas actions carried only by "must not confuse with" comments. That iswrong and was wrong when I filed it. All three appear unquoted in prose comments,
so the regex never saw them.
ConfigureWifiandSetLocaleare still in theuncovered set where they belong;
GrubSetKargsleft it when story 138 landed in#447, and the cluster list below records that. No action in the catalogue has its only quoted occurrence on
a comment line, so the figure is not inflated by that mechanism at all.
The caveat that does hold: 34 Ubuntu-and-
Allactions are covered only by stories 1 to 54, the atomic family, which no recorded Ubuntu run includes, soAptListUpgradable, a Debian-only action, has its sole coverage in a Fedora-family story.Clusters, each one a reasonable PR
Ubuntu-family exclusive, highest priority:
fail2ban (4): stories 134-137 landed in test(e2e): cover fail2ban action family #401 on 2026-09-15. Add E2E story coverage for the fail2ban action family #219 stays open for the live recording behind them.GRUB kargs (1):GrubSetKargslanded as story 138 in test(e2e): cover GrubSetKargs with story 138 #447 on 2026-09-17. No Ubuntu-family-exclusive action is left without a story.Cross-family (
All):GetSysctl,SetSysctl,GetAuditRules,AddAuditRule,RemoveAuditRuleGetPasswordAging,SetPasswordAging,SetPasswordPolicy,SetAccountLockout,LockUserAccount,UnlockUserAccountGetSudoGrants,GrantSudoAccess,RevokeSudoAccessCreateGroup,DeleteGroupGetMounts,AddMount,RemoveMount,AddSwap,RemoveSwapGetLvmReport,CreateLogicalVolume,ExtendLogicalVolume,CreateLvSnapshotGetLogrotateStatus,ConfigureLogRotation,RemoveLogRotation,ConfigureRemoteSyslog,RemoveRemoteSyslogGetJournalLog,VacuumJournal,CollectDiagnosticsCreateContainer,StartContainer,StopContainer,RemoveContainerListFlatpakRemotes,AddFlatpakRemote,RemoveFlatpakRemote,GetFlatpakAppInfoListToolboxes,RemoveToolboxGetCertificates,ObtainCertificate,RenewCertificatesResolvectlStatus,ResolvectlSetDns,ConfigureWifi,GetListeningPortsUnmaskService,CreateScheduledJob,GetServiceResourceLimits,SetServiceResourceLimitsGetDateTime,SetNtp,SetLocaleSetSshdOption,SignalProcessGetFirewallBackendState,GetNftablesRuleset, added by feat(network): report nftables and firewall backend observations #413 after this map was drawnHow to take one
Pick a cluster, write one story per action, and record on Ubuntu the way the current 84 run:
Then commit the cassette and its replay twin so the suite still runs offline.
run-stories.shaccepts story numbers, so you can record only yours. Any of the seven*_API_KEYvariables the runner recognises works; no credentials are needed from the maintainer.The header decides the family and a wrong one fails silently, so use
# Story <id> (ubuntu, <read-only|medium-risk|high-risk>): <name>and check thatbash tests/e2e/run-stories.sh --metadataputs your story in theubuntufamily. Next free id is 139.Start with a read-only cluster if this is your first story.
GetMounts,GetSysctlandGetListeningPortsneed no approval receipt and exercise the whole chain.Worth fixing alongside
Nothing compares the story set against the action catalogue, which is why this drifted unnoticed. The derivation above is small enough to become a gate, and it would keep the number in #229 honest at the same time.
Difficulty
mediumper cluster. The harness and the pattern exist; the work is writing intents and recording a clean pass.Getting started
CONTRIBUTING.md has the build and test commands, and its E2E section covers the VM harness. No CLA and no copyright waiver. The project is MIT.