run
Extracts typeNames (fully-qualified @Serializable class names) into a snapshot written to output. If jsonInstanceFqn is set, that Json instance's configuration and module are read, and failing to load it throws (the check would otherwise run under the wrong config). If it is null, the default Json config is assumed (design §6 resolution order).
When typeNames is empty, types are discovered instead: the classpath manifest (see TYPES_RESOURCE) unioned with a class-dir scan of scanDirs (issue #55). Generic classes found by the scan are resolved as roots by extracting their descriptor with type-parameter holes (issue #139): each contributes its own CLASS contract whose type-parameter positions render as a stable sentinel, so its envelope fields are checked while the holes stay covered at concrete use sites. A generic sealed/polymorphic hierarchy is out of scope and degrades to an OPAQUE coverage gap. Unreadable class files degrade to OPAQUE coverage gaps whenever scanDirs were scanned, even alongside explicit typeNames.
discovery refines the scanned candidates (issue #115): OPT_OUT drops types carrying @SerialkompatIgnore; OPT_IN keeps only @SerialkompatChecked types. Manifest entries and explicit typeNames are deliberate acts and bypass the filter.