docs: function (key, value, opts) {
              key = key.toLowerCase();
  
              return Promise.try(function () {
                  if (!(value.intent && value.message && value.editor)) {
                      throw new Error("An intent, message, and editor are all needed to set a new factoid.");
                  }
  
                  if (value.message.length > maxMessageLength) {
                      return Fail("message-length-exceeded")
                  }
  
                  return [
                      disallowTooLongMessages(value.message),
                      disallowAtCharacterInKey(key),
                      disallowUnsafeReplace(key, (opts && opts.isSafeReplace) || false),
                      getPreviousKeyForEditing(key, value.editor)
                  ].reduce(Result.and);
              })
              .then(bindr(Result.map, function (previousValue) {
                  return {
                      intent: value.intent,
                      message: value.message,
                      editor: value.editor,
                      time: now(),
                      frozen: previousValue ? previousValue.frozen : false
                  };
              }))
              .then(bindr(Result.andThen, beforeUpdate))
              .then(bindr(Result.map, function (value) {
                  db.set(key, value);
  
                  return value;
              }));
          }