Can't really find anything wrong with the logic, but you might need to dial back your scope variable to be a view scope.
I basically copied your code and took out the save logic. I clicked the button and the session scope variable was null. clicked the pdf link and then clicked the button and the session scope variable was Yes.
Remember that once a session scope variable is set, even if they load another page that uses that same variable the value remains until the browser is closed or the session times out.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:link
escape="true"
text="Required: Click to Review Certificate of Insurance Requirements"
id="link1"
value="http://info.lmsnet.com/lms/assets/vendortracking/coirequirements.pdf"
target="_blank"
style="background-color:rgb(255,128,128)">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="btnSubmit"
id="eventHandler1">
<xp:this.action><![CDATA[#{javascript:sessionScope.put( "vendorAppReadCOI", "Yes" );}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
<xp:button
value="Finish"
id="btnSubmit">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:if(sessionScope.vendorAppReadCOI=="Yes"){
println(sessionScope.vendorAppReadCOI+" should be yes")
} else {
println(sessionScope.vendorAppReadCOI+" should be null")
}
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>
This is the output in the log file from the above code.
[0D54:0009-0C38] 08/08/2012 12:53:01 AM HTTP JVM: null should be null
[0D54:0009-0C38] 08/08/2012 12:53:49 AM HTTP JVM: Yes should be yes