diff --git a/resources/static/dialog/controllers/is_this_your_computer.js b/resources/static/dialog/controllers/is_this_your_computer.js
index 970c7bb9cc4664c64367d562b64793cc36e2a707..120c5ca1ef6b6899e32ce88d38d8cb63980745f2 100644
--- a/resources/static/dialog/controllers/is_this_your_computer.js
+++ b/resources/static/dialog/controllers/is_this_your_computer.js
@@ -38,6 +38,7 @@ BrowserID.Modules.IsThisYourComputer = (function() {
     },
 
     no: function() {
+      storage.usersComputer.setDenied(network.userid());
       this.publish("email_chosen", { email: email });
     }
 
diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js
index a6b47c7ebdf6352836f9a974c6e74ef9764bbfcd..7d5ef5c7525517df3cb60fe59d41d7c89022d626 100644
--- a/resources/static/dialog/resources/state.js
+++ b/resources/static/dialog/resources/state.js
@@ -17,8 +17,7 @@ BrowserID.State = (function() {
       addPrimaryUser = false,
       email,
       requiredEmail,
-      primaryVerificationInfo,
-      isYourComputerAsked = false;
+      primaryVerificationInfo;
 
   function startStateMachine() {
     var self = this,
@@ -179,9 +178,7 @@ BrowserID.State = (function() {
     });
 
     subscribe("email_chosen", function(msg, info) {
-      if (!isYourComputerAsked &&
-          !storage.usersComputer.confirmed(network.userid())) {
-        isYourComputerAsked = true;
+      if (storage.usersComputer.shouldAsk(network.userid())) {
         publish("is_this_your_computer", info);
         return;
       }
diff --git a/resources/static/shared/storage.js b/resources/static/shared/storage.js
index 1d6bc4f5c84359dbdbeaab1132b29db86f21e52d..ccdeb53d33317bb3c922faeb82f58e2b4f05e19d 100644
--- a/resources/static/shared/storage.js
+++ b/resources/static/shared/storage.js
@@ -5,7 +5,8 @@
 BrowserID.Storage = (function() {
 
   var jwk,
-      storage = localStorage;
+      storage = localStorage,
+      ONE_DAY_IN_MS = (1000 * 60 * 60 * 24);
 
   function prepareDeps() {
     if (!jwk) {
@@ -211,33 +212,94 @@ BrowserID.Storage = (function() {
     return allInfo[emailOrUserID];
   }
 
-  // tools to manage knowledge of whether this is the user's computer, which helps
-  // us set appropriate authentication duration.
-  function userConfirmedOnComputer(userid) {
-    userid = mapEmailToUserID(userid);
-    var allInfo = JSON.parse(storage.usersComputer || "{}");
-    return allInfo[userid] === 'confirmed';
+  // tools to manage knowledge of whether this is the user's computer,
+  // which helps us set appropriate authentication duration.
+  function validState(state) {
+    return (state === 'seen' || state === 'confirmed' || state === 'denied');
   }
-  function userSeenOnComputer(userid) {
+    
+  function setConfirmationState(userid, state) {
     userid = mapEmailToUserID(userid);
-    var allInfo = JSON.parse(storage.usersComputer || "{}");
-    return !!(allInfo[userid]); // "seen" or "confirmed"
+
+    if (typeof userid !== 'number') throw 'bad userid ' + userid;
+
+    if (!validState(state)) throw "invalid state";
+
+    var allInfo;
+    var currentState;
+    var lastUpdated = 0; 
+    try {
+      allInfo = JSON.parse(storage.usersComputer);
+      if (typeof allInfo !== 'object') throw 'bogus';
+      if (allInfo[userid]) {
+        currentState = allInfo[userid][0];
+        lastUpdated = Date.parse(allInfo[userid][1]);
+        if (!validState(currentState)) throw "corrupt/outdated";
+        if (NaN === lastUpdated) throw "corrupt/outdated";
+      }
+    } catch(e) {
+      currentState = undefined;
+      lastUpdated = 0;
+      allInfo = {};
+    }
+    
+    // ...now determine if we should update the state...
+
+    // first if the user said this wasn't their computer over 24 hours ago,
+    // forget that setting (we will revisit this)
+    if (currentState === 'denied' &&
+        ((new Date()).getTime() - lastUpdated) > ONE_DAY_IN_MS) {
+      currentState = undefined;
+      lastUpdated = 0;
+    }
+
+    // if the user has a non-null state and this is another user sighting
+    // (seen), then forget it
+    if (state === 'seen' && currentState) return;
+    
+    // good to go!  let's make the update
+    allInfo[userid] = [ state, new Date().toString() ];
+    storage.usersComputer = JSON.stringify(allInfo);    
   }
-  function setUserSeenOnComputer(userid) {
-    userid = mapEmailToUserID(userid);
-    var allInfo = JSON.parse(storage.usersComputer || "{}");
-    if (!allInfo[userid]) {
-      allInfo[userid] = "seen";
-      storage.usersComputer = JSON.stringify(allInfo);
+
+  function userConfirmedOnComputer(userid) {
+    try {
+      userid = mapEmailToUserID(userid);
+      var allInfo = JSON.parse(storage.usersComputer || "{}");
+      return allInfo[userid][0] === 'confirmed';
+    } catch(e) {
+      return false;
+    } 
+  }
+  function shouldAskUserAboutHerComputer(userid) {
+    // we should ask the user if this is their computer if they were
+    // first seen over a minute ago, if they haven't denied ownership
+    // of this computer in the last 24 hours, and they haven't confirmed
+    // ownership of this computer
+    try {
+      userid = mapEmailToUserID(userid);
+      var allInfo = JSON.parse(storage.usersComputer);
+      
+      var s = allInfo[userid][0];
+      var timeago = new Date() - Date.parse(allInfo[userid][1]);
+
+      if (s === 'confirmed') return false;
+      if (s === 'denied' && timeago > ONE_DAY_IN_MS) return true;
+      if (s === 'seen' && timeago > (60 * 1000)) return true;
+    } catch (e) {
+      return true;
     }
+
+    return false;
+  }
+  function setUserSeenOnComputer(userid) {
+    setConfirmationState(userid, 'seen');
   }
   function setUserConfirmedOnComputer(userid) {
-    userid = mapEmailToUserID(userid);
-    var allInfo = JSON.parse(storage.usersComputer || "{}");
-    if (allInfo[userid] !== 'confirmed') {
-      allInfo[userid] = 'confirmed';
-      storage.usersComputer = JSON.stringify(allInfo);
-    }
+    setConfirmationState(userid, 'confirmed');
+  }
+  function setNotMyComputer(userid) {
+    setConfirmationState(userid, 'denied');
   }
 
   // update our local storage based mapping of email addresses to userids,
@@ -245,7 +307,6 @@ BrowserID.Storage = (function() {
   // to a user who has already confirmed their ownership of a computer.
   function updateEmailToUserIDMapping(userid, emails) {
     var allInfo = JSON.parse(storage.emailToUserID || "{}");
-    console.log(emails);
     _.each(emails, function(email) {
       allInfo[email] = userid;
     });
@@ -327,10 +388,17 @@ BrowserID.Storage = (function() {
        * @param {integer} userid - the user's numeric id, returned from session_context when authed.
        * @method usersComputer.setConfirmed */
       setConfirmed: setUserConfirmedOnComputer,
-      /** Query whether a user has been "seen" on this computer before
+      /** Save the fact that a user denied that this is their computer
        * @param {integer} userid - the user's numeric id, returned from session_context when authed.
+       * @method usersComputer.setDenied */
+      setDenied: setNotMyComputer,
+      /** Should we ask the user if this is their computer, based on the last
+       * time they used browserid and the last time they answered a question
+       * about this device
+       * @param {integer} userid - the user's numeric id, returned
+       *   from session_context when authed.
        * @method usersComputer.seen */
-      seen: userSeenOnComputer,
+      shouldAsk: shouldAskUserAboutHerComputer,
       /** Save the fact that a user has been seen on this computer before, but do not overwrite
        *  existing state
        * @param {integer} userid - the user's numeric id, returned from session_context when authed.