Eight projects had been shipping into a room with no door
An allowlist fails silently. Eight projects had been shipping changelog entries into a feed that never knew they existed.
Why Care?
This site's whole claim is that it shows the work — all of it, across every repo in the tree. That claim was quietly false. Eight projects had been writing changelog entries for weeks and none of them appeared here, because the aggregation manifest is an allowlist and nobody had added them to it.
That design is deliberate and we would choose it again. An allowlist is what keeps roll-ups, corpus copies, and someone else's vendored docs out of a feed that is supposed to be ours. But an allowlist has a failure mode that a denylist doesn't: the gap is silent. A repo that was never declared doesn't error, doesn't warn, doesn't show up as zero. It simply isn't there, and the site renders a confident total that is missing thirty-seven entries.
The fix was not clever. It was an audit we had never run.
What's New?
Eight new streams, 37 entries, taking the aggregate from 39 streams to 47 and from 492 entries to 529.
| Stream | Parent | Entries | Newest |
| Reach Edu Hub | dididecks-ai | 14 | 2026-07-28 |
| Lossless Toolkit | astro-knots | 8 | 2026-09-15 |
| Flave | ai-labs | 7 | 2026-08-21 |
| Lossless Slides | astro-knots | 4 | 2026-09-15 |
| Dominocielo | astro-knots | 1 | 2026-09-11 |
| GTH | astro-knots | 1 | 2026-09-11 |
| Multiphasic | astro-knots | 1 | 2026-08-26 |
| Stenographer | content-farm | 1 | 2026-08-08 |
Also in this pass: the aggregate caught up on everything the declared streams had shipped since 2026-08-21, the commit and line series were rebuilt across 45 repos, and the ledger's busiest day moved from 129 to 156 commits on 2026-09-13.
How We Found Them
By walking the tree and asking a different question than the manifest asks.
The manifest says "here are the streams we aggregate." The audit asked "here is every directory on disk that looks like a changelog and holds markdown — which of those does the manifest not know about?" Sixty directories matched. Thirty-nine were declared. The remaining twenty-one split three ways:
60 changelog dirs on disk
├── 39 declared in streams.yaml ← the aggregate
├── 13 genuinely undeclared Lossless repos
├── 5 deliberate exclusions (rollups, corpus copies, sibling buckets)
└── 3 third-party study repos (mui, shadcn-svelte, hindsight)Of the thirteen, five are private — lossless-monorepo, calmstorm-decks,
lossless-at, eventcut-ai, chroma-decks. Those stay out, and not as an
oversight. This site is public, and the token that syncs it can read private
repos. A token's reach must never be the reason something becomes public. It's
the same call we made on 2026-09-09 when changelog-neo went private and we
dropped it from the sync state rather than letting it keep flowing.
One more was a false positive worth naming: matter-site/changelog/ looked
undeclared, but matter-site/changelog is a submodule, and we already
aggregate it as dark-matter pointing at changelog_matter-site — the repo
the submodule resolves to. The audit found the same entries by a different
path.
Under the Hood
Two things went wrong on the way, both worth recording.
The directory name is not the repo name. We declared Flave as
lossless-group/flave-ai because its checkout sits at ai-labs/flave-ai/. The
repo is lossless-group/flave. The sync failed loudly — path not found:
lossless-group/flave-ai:main/changelog — which is exactly the behaviour you
want, and a reminder that clones.mjs resolves repos by origin remote
rather than by directory name for precisely this reason.
A branch can hide entries. lossless-toolkit-site carries 5 changelog
entries on main and master, and 8 on development. The tier model puts
work on development first, so that's the ref we declared. A manifest that had
defaulted to the repo's default branch would have silently under-reported that
project by three entries — which is why ref is a required field here and is
never inferred.
We also wrote the exclusions down, in a block at the foot of the manifest. An audit that finds the same five private repos every quarter and has to re-derive why they're out is an audit that eventually re-adds one by mistake.
Verification
Declaring a stream is not evidence it resolves. After the sync we walked all 47 streams, listed each one's remote directory through the GitHub API, and compared filename-by-filename against what had landed on disk:
47 streams checked · 0 with drift · 47 API callsZero missing locally, zero extra locally. The aggregate now matches every remote exactly — which is a claim we can make for the first time, because it is the first time we checked.
What's Next
Nineteen of 47 streams still have no favicon, including
augment-itandmemopop-orchestrator— the two highest-volume streams on the site. The filter row and the ledger both look unfinished because of it.The audit should be a script, not a session. It exists as a one-off that ran once and was deleted. Next time a repo ships for six weeks into a room with no door, we should find out from CI, not from someone clicking around.
References
[[2026-08-21_01]] — every project gets a face, and none of them is the Astro logo
src/config/streams.yaml— the manifest, and the new "deliberately NOT aggregated" blockcontext-v/specs/Aggregate-Changelog-Streams-Across-the-Lossless-Tree-via-the-GitHub-API.md
