The example below shows that you can get generated values out of an s/merge using mult-specs that don't make sense with the intended spec.
Looking at the implementation of the generator for s/merge each arg to s/merge gets generated individually, but it would be nice if they instead flowed through from right to left so things like multi-specs wouldn’t choose randomly from their dispatches.
(s/def :ent/id string?)
(defmulti ent-multi-id :ent/id)
(defmethod ent-multi-id :default [_] (s/keys))
(defn maybe-retag-fn [retag-k]
(fn [gen-v dispatch-tag]
(if (= dispatch-tag :default)
gen-v
(assoc gen-v retag-k dispatch-tag))))
(s/def ::ent (s/merge (s/multi-spec ent-multi-id (maybe-retag-fn :ent/id))
(s/keys :req [:ent/id])))
(gen/sample (s/gen ::ent) 5)
;; => ({:ent/id ""} {:ent/id "w"} {:ent/id ""} {:ent/id "66"} {:ent/id "63v"})
(s/def :foo/id string?)
(defmethod ent-multi-id "foo" [_]
(s/keys :req [:foo/id]))
(gen/sample (s/gen ::ent) 5)
;; => ({:foo/id "", :ent/id ""} {:foo/id "6", :ent/id "f"} {:foo/id "A", :ent/id "W"} {:foo/id "L", :ent/id "nd"} {:ent/id "H"})