 
 (s/def :flow/from
   (s/or :task-name keyword?
-        :special-task (s/get-spec :flow/special-tasks)))
+        :special-task :flow/special-tasks))
 
 (s/def :flow/to
   (s/or :task-name keyword?
         :task-names (s/coll-of keyword? :kind vector?)
-        :special-task (s/get-spec :flow/special-tasks)))
+        :special-task :flow/special-tasks))
 
 (s/def :flow/predicate
-  (s/or :keyword keyword?
-        :coll (s/coll-of any? :kind vector?)))
+  (s/or :and (s/cat :op #{:and} :exprs (s/+ :flow/predicate))
+        :or (s/cat :op #{:or} :exprs (s/+ :flow/predicate))
+        :not (s/cat :op #{:not} :exprs (s/cat :pred :flow/predicate))
+        :fn keyword?
+        :fn-and-args (s/cat :fn (fn [x]
+                                  (and (keyword? x)
+                                       (not (some #{x} #{:and :or :not}))))
+                            :args (s/* keyword?))))
 
 (s/def :flow/post-transform namespaced-keyword?)
 
 (s/def :flow/thrown-exception? boolean?)
-
-(s/def :flow/action (s/get-spec :flow/action))
 
 (s/def :flow/short-circuit? boolean?)
 


(s/def :onyx/messaging #{:aeron :dummy-messenger})

(s/def :onyx.messaging/impl (s/get-spec :onyx/messaging))

(s/def :onyx/peer-config
  (s/keys :req [:onyx/tenancy-id

(s/def :job/trigger (s/multi-spec trigger-on :trigger/on))

(s/def :job/triggers
  (s/coll-of :job/trigger :kind vector?))

(s/def :jvm/function
  (s/or :fn fn? :var var?))
