Some Shared Files Cannot Be Identical
Most of the shared layer is byte-identical everywhere, which is what makes the comparison trivial. A few files cannot be. The clearest case is an app-shell service worker: the caching strategy, the lifecycle handling, the update flow — all identical by design. But the cache name has to be unique per app, or two apps served from the same origin fight over one cache, and the list of shell URLs is different for every app because their entry points differ.
So those files ship as templates. The kit source contains placeholder tokens; the manifest carries a variable block per consumer; and the deploy substitutes before writing.
The Ordering Trap
Here is the mistake that is easy to make and annoying to diagnose: substitute on deploy, and compare the raw source on check. The result is that every templated file reports drift in every consumer, permanently, because of course the deployed file differs from the unsubstituted source — that is the entire purpose of the template.
The fix is one line of ordering: render the source for that consumer, then compare. The check must ask "does this file match what a deploy would write here right now", not "does this file match the source". For non-templated files those two questions have the same answer, which is exactly why the mistake survives testing until the first template arrives.
Generation Is Just a Bigger Transform
The same machinery covers a case that looks different but is not. One kit source is a plain data file: a catalog of the assistant brains, their labels, their effort options, their route paths. It is not deployed as-is anywhere. Instead, three transforms render it into a Python module, a TypeScript module, and a Swift file, and each of those is deployed to the consumers that need that language.
The check handles it without any special case, because rendering is just another transformation applied before comparison. And this is where a real benefit shows up: hand-writing three language bindings of one table is a guaranteed drift source, since one of them will be updated and the others forgotten. Generating them from one file means the drift check now covers not only "nobody edited a copy" but also "all three languages agree" — one mechanism, two invariants.