     (Flows. (clj->js (map first @rule->flow)) (clj->js @rule->flow) #js {} (clj->js @kind->name->rules) (clj->js @name->transient?))))
 
 ;; TESTS
+
 (comment
 (enable-console-print!)
 


          ;; add a clause to output used vars to agg-index-ix
          (swap! rule-id->clauses update-in [rule-id] conj [rule-id "know" agg-clause-id agg-index-id])
          (swap! clause-id->fields update-in [agg-clause-id] conj [agg-clause-id "variable" limit limit])
          (doseq [[_ var] (@rule-id->group-by rule-id)]
            (swap! clause-id->fields update-in [agg-clause-id] conj [agg-clause-id "variable" var var]))
          (doseq [[_ ix var] (@rule-id->sort-by rule-id)]
            (swap! clause-id->fields update-in [agg-clause-id] conj [agg-clause-id "variable" var var]))
          (doseq [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
            (swap! clause-id->fields update-in [agg-clause-id] conj [agg-clause-id "variable" in-var in-var]))

          ;; create an aggregate flow to read from agg-index-id
          (let [group-by-vars (for [[_ var] (@rule-id->group-by rule-id)]
                                var)
                sort-by-vars (into (sorted-map)
                                   (for [[_ ix var] (@rule-id->sort-by rule-id)]
                                     [ix var]))
                agg-in-vars (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                              in-var)
                agg-out-vars (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                               out-var)
                in-vars (into-array (distinct (concat group-by-vars [limit] (vals sort-by-vars) agg-in-vars)))
                out-vars (into-array (distinct (concat group-by-vars [limit] (vals sort-by-vars) agg-in-vars [ordinal] agg-out-vars)))
                var->ix (into {}
                              (for [i (range (alength out-vars))]
                                [(aget out-vars i) i]))
                index (.get-or-create-index kn "know" agg-index-id in-vars)
                group-len (count (conj (set group-by-vars) limit))
                limit-ix (var->ix limit)
                ascending? (= ascending|descending "ascending")
                agg-ixes (into-array
                          (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                            (var->ix in-var)))
                agg-funs (into-array
                          (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                            (aget js/aurora.aggregates agg-fun)))
                sinks (into-array
                       (for [[_ clause-type clause-id name] clauses
                             :when (not= clause-type "when")]
                         (sink-of rule-id clause-type clause-id name var->ix)))]
            (swap! rule->flow assoc agg-rule-id (AggregateFlow. index group-len limit-ix ascending? agg-ixes agg-funs sinks))
            (swap! kind->name->rules update-in ["know" agg-index-id] conj agg-rule-id)))))

    (doseq [[rule-id clauses] @rule-id->clauses]
      (let [var->when-count (atom {})]

              agg-index-id (str rule-id "-agg-index")
              has-aggs (@rule-id->has-agg rule-id)
              _ (assert (= (count has-aggs) 1))
              [_ _ limit ordinal ascending|descending] (first has-aggs)
              group-by-vars (for [[_ var] (@rule-id->group-by rule-id)]
                              var)
              sort-by-vars (into (sorted-map)
                                 (for [[_ ix var] (@rule-id->sort-by rule-id)]
                                   [ix var]))
              agg-in-vars (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                            in-var)
              agg-out-vars (set
                            (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                              out-var))
              pass-through-vars (for [[_ clause-type clause-id name] clauses
                                      :when (not= clause-type "know")
                                      [_ field-type key val] (@clause-id->fields clause-id)
                                      :when (= field-type "variable")
                                      :when (not= ordinal val)
                                      :when (not (agg-out-vars val))]
                                  val)
              in-vars (into-array (distinct (concat group-by-vars [limit] (vals sort-by-vars) agg-in-vars pass-through-vars)))
              out-vars (into-array (distinct (concat group-by-vars [limit] (vals sort-by-vars) agg-in-vars pass-through-vars [ordinal] agg-out-vars)))
              var->ix (into {}
                            (for [i (range (alength out-vars))]
                              [(aget out-vars i) i]))
              index (.get-or-create-index kn "know" agg-index-id in-vars)
              group-len (count (conj (set group-by-vars) limit))
              limit-ix (var->ix limit)
              ascending? (= ascending|descending "ascending")
              agg-ixes (into-array
                        (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                          (var->ix in-var)))
              agg-funs (into-array
                        (for [[_ in-var agg-fun out-var] (@rule-id->agg-over rule-id)]
                          (aget js/aurora.aggregates agg-fun)))
              sinks (into-array
                     (for [[_ clause-type clause-id name] clauses
                           :when (not= clause-type "when")]
                       (sink-of rule-id clause-type clause-id name var->ix)))]

          ;; remove output clauses
          (doseq [[_ clause-type clause-id name] clauses
