release

UnGathered 0.2 Finds the Items That Were Never Made

The first release had a blind spot, and the README said so. UnGathered checked what sat beside each item it found. A product folder nobody created, or an article that was planned and never written, left nothing to find. So the scan stayed quiet about it.

Version 0.2 closes that gap with a roster. A collection can now point at a list kept somewhere else: a product export, an issue plan, a plain text file with one name per line. Each name has to match a selected item. A name with no item is a missing_item gap, and it fails the scan like any other gap. Turn on unlisted: gap and it works the other way too, flagging an item that turned up without being on the plan.

The list has to be a real list. An empty roster, or one that is only a header row, used to be the sort of thing that would sail through as “complete”. Now it’s refused as invalid input, because a truncated export is far more likely than a plan with nothing in it.

A nested folder tree with drafts excluded, a roster where one name has no file, and a pull request check reporting four gaps

The second change is depth. Real asset trees are nested: issues inside years, product lines inside catalogs. In 0.1 every level needed its own collection. Now a ** segment matches any number of folders, the way it does in .gitignore, so issues/**/*.md finds every article however deep it sits. Drafts and templates are what exclude is for. issues/*/drafts/** keeps work in progress out of the count.

Symlinks needed some thought here. A deep pattern can reach a lot more of the tree, and a symlinked folder it can’t see into might be hiding items. So that’s still an error, as before. The one exception is a link inside a tree an exclude removes completely, since nothing below it could count anyway.

The third piece is the one most people will touch first: a GitHub Action. Point it at a manifest and a folder and it runs the scan on every pull request. Each problem lands as an annotation, next to the article that’s missing its credit line where it can. The job summary gets a table. The JSON and HTML reports are uploaded as an artifact. It downloads the release it’s pinned to and checks it against SHA256SUMS before running anything. The repository tests it on Linux, macOS and Windows runners, and again on the published binaries after each release.

An independent review went through all of this before the release and found a real problem in the Action. It made the report folder before the scan had checked where that folder was, so a careless setting could drop a folder into the very collection being scanned. Now UnGathered makes missing report folders itself, after the scan, and only once they are confirmed to sit outside it. The review also caught text output that printed odd file names raw, and a check that compared folder names byte for byte on a case-insensitive Mac. Both are fixed, with tests.

What hasn’t changed: UnGathered still checks presence, type, size and text patterns. It doesn’t open a PDF or measure an image. It still never writes to the collection, and it still keeps “something is missing” (exit 1) apart from “I couldn’t look” (exit 2).

The quick start has a roster example you can run in a minute, the reference covers the new manifest fields, and the download page has the 0.2 archives.