anchor.diff:        [], ses @ effect_and_lift_ses
   
     | Sig_new_effect(ne) ->
  -    let ne = tc_eff_decl env ne in
  +    let ne =
  +      if Options.use_two_phase_tc () then
  +        //first phase
  +        let ne = tc_eff_decl ({ env with lax = true }) ne in
  +        if Env.should_verify env then  //second phase
  +          //remove unification variables
  +          let se' = { se with sigel = Sig_new_effect (ne) } |> N.elim_uvars env in
  +          let ne = match se'.sigel with | Sig_new_effect ne -> ne | _ -> failwith "Impossible" in
  +          //verify
  +          tc_eff_decl env ne
  +        else ne
  +      else tc_eff_decl env ne
  +    in
       let se = { se with sigel = Sig_new_effect(ne) } in
       [se], []
   
  -  | Sig_sub_effect(sub) ->
  +  | Sig_sub_effect(sub) ->  //no need to two-phase here, since lifts are already lax checked
       let ed_src = Env.get_effect_decl env sub.source in
       let ed_tgt = Env.get_effect_decl env sub.target in
       let a, wp_a_src = monad_signature env sub.source (Env.lookup_effect_lid env sub.source) in
  
positive.code: 
    | Sig_bundle(ses, lids) ->
      let env = Env.set_range env r in
      let ses, projectors_ses = tc_inductive env ses se.sigquals lids in
      ses, projectors_ses
  
    | Sig_pragma(p) ->
      U.process_pragma p r;
      [se], []
  
    | Sig_new_effect_for_free (ne) ->
        (* This is only an elaboration rule not a typechecking one *)
  
        // Let the power of Dijkstra generate everything "for free", then defer
  
negative.code:         let _ = recheck_debug "lift-elab" env lift_elab in
          Some ([], lift_elab), ([], lift_wp)
      in
      (* we do not expect the lift to verify, *)
      (* since that requires internalizing monotonicity of WPs *)
      let env = {env with lax=true} in
  