diff --git a/replication/ir/Rules.mk b/replication/ir/Rules.mk
new file mode 100644
index 0000000000000000000000000000000000000000..8c6fcfa2fd0e9f101183467896924c6c1bd97e4d
--- /dev/null
+++ b/replication/ir/Rules.mk
@@ -0,0 +1,18 @@
+d := $(dir $(lastword $(MAKEFILE_LIST)))
+
+SRCS += $(addprefix $(d), \
+	record.cc)
+
+PROTOS += $(addprefix $(d), \
+	    ir-proto.proto)
+
+OBJS-ir-client :=  $(o)ir-proto.o \
+                   $(OBJS-client) $(LIB-message) \
+                   $(LIB-configuration)
+
+OBJS-ir-replica := $(o)record.o $(o)ir-proto.o \
+                   $(OBJS-replica) $(LIB-message) \
+                   $(LIB-configuration)
+
+#include $(d)tests/Rules.mk
+
diff --git a/replication/ir/ir-proto.proto b/replication/ir/ir-proto.proto
new file mode 100644
index 0000000000000000000000000000000000000000..fd1abaa12582f0e101c41db07a6b6c86b9be5b03
--- /dev/null
+++ b/replication/ir/ir-proto.proto
@@ -0,0 +1,52 @@
+import "replication/common/request.proto";
+
+package replication.vr.proto;
+
+message OpID {
+    required uint64 clientid = 1;
+    required uint64 clientreqid = 2;
+}
+
+message ProposeInconsistentMessage {
+    required replication.Request req = 1;
+}
+
+message ReplyInconsistentMessage {
+    required uint64 view = 1;
+    required uint32 replicaIdx = 2;
+    required OpID opid = 3;
+}
+
+message FinalizeInconsistentMessage {
+    required OpID opid = 1;
+}
+
+message ConfirmMessage {
+    required uint64 view = 1;
+    required uint32 replicaIdx = 2;
+    required OpID opid = 3;
+}
+
+message ProposeConsensusMessage {
+    required replication.Request req = 1;
+}
+
+message ReplyConsensusMessage {
+    required uint64 view = 1;
+    required uint32 replicaIdx = 2;
+    required OpID opid = 3;
+    required bytes reply = 4;
+}
+
+message FinalizeConsensusMessage {
+    required OpID opid = 1;
+    required bytes reply = 2;
+}
+
+message UnloggedRequestMessage {
+    required replication.UnloggedRequest req = 1;
+}
+
+message UnloggedReplyMessage {
+    required bytes reply = 1;
+}
\ No newline at end of file
diff --git a/replication/ir/record.cc b/replication/ir/record.cc
new file mode 100644
index 0000000000000000000000000000000000000000..42019d784da9d68ff1c0b4f66e74e1bbcd92c4ab
--- /dev/null
+++ b/replication/ir/record.cc
@@ -0,0 +1,109 @@
+// -*- mode: c++; c-file-style: "k&r"; c-basic-offset: 4 -*-
+/***********************************************************************
+ *
+ * log.h:
+ *   a replica's log of pending and committed operations
+ *
+ * Copyright 2013 Dan R. K. Ports  <drkp@cs.washington.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************************/
+
+#include "replication/ir/record.h"
+#include "lib/assert.h"
+
+namespace ir {
+
+Record::Record()
+{
+
+}
+
+
+RecordEntry &
+Record::Add(view_t view, opid_t opid, RecordEntryState state,
+            const Request &request, const string &reply)
+{
+    RecordEntry entry;
+    entry.view = vs;
+    entry.opid = opid;
+    entry.request = requet;
+    entry.state = state;
+
+    // Make sure this isn't a duplicate
+    ASSERT(entries.count(opid) == 0);
+    
+    entries[opid] = entry;
+    return entries[opid];
+}
+
+// This really ought to be const
+RecordEntry *
+Record::Find(opid_t opid)
+{
+    if (entries.empty() || entries.count(opid) == 0) {
+        return NULL;
+    }
+
+    RecordEntry *entry = &entries[opid];
+    ASSERT(entry->viewstamp.opid == opid);
+    return entry;
+}
+
+
+bool
+Record::SetStatus(opnum_t op, RecordEntryState state)
+{
+    RecordEntry *entry = Find(op);
+    if (entry == NULL) {
+        return false;
+    }
+
+    entry->state = state;
+    return true;
+}
+
+bool
+Record::SetRequest(opnum_t op, const Request &req)
+{
+    RecordEntry *entry = Find(op);
+    if (entry == NULL) {
+        return false;
+    }
+
+    entry->request = req;
+    return true;
+}
+
+void
+Record::Remove(opid_t opid)
+{
+    entries.erase(opid);
+}
+    
+bool
+Record::Empty() const
+{
+    return entries.empty();
+}
+
+} // ir
diff --git a/replication/ir/record.h b/replication/ir/record.h
new file mode 100644
index 0000000000000000000000000000000000000000..a75a66efa2299f404aa0945eec73d10d152a576e
--- /dev/null
+++ b/replication/ir/record.h
@@ -0,0 +1,90 @@
+// -*- mode: c++; c-file-style: "k&r"; c-basic-offset: 4 -*-
+/***********************************************************************
+ *
+ * log.h:
+ *   a replica's log of pending and committed operations
+ *
+ * Copyright 2013 Dan R. K. Ports  <drkp@cs.washington.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************************/
+
+#ifndef _IR_RECORD_H_
+#define _IR_RECORD_H_
+
+#include "replication/common/request.pb.h"
+#include "lib/assert.h"
+#include "lib/message.h"
+#include "lib/transport.h"
+#include "replication/common/viewstamp.h"
+
+#include <map>
+#include <string>
+#include <pair>
+
+namespace ir {
+
+enum RecordEntryState {
+    RECORD_STATE_TENTATIVE,
+    RECORD_STATE_FINALIZED
+};
+
+typedef pair<uint64_t, uint64_t> opid_t;
+    
+struct RecordEntry
+{
+    view_t view;
+    opid_t opid;
+    RecordEntryState state;
+    Request request;
+    std::string result;
+    
+    RecordEntry() { replyMessage = ""; }
+    RecordEntry(const RecordEntry &x)
+        : view(x.view), opid(x.opid), state(x.state), request(x.request),
+          result(x.result) { }
+    RecordEntry(view_t view, opid_t opid, RecordEntryState state,
+                const Request &request, const std::string &reply)
+        : view(view), opid(opid), state(state), request(request),
+          reply(reply) { }
+    virtual ~RecordEntry() { }
+};
+
+class Record
+{
+public:
+    Record();
+    RecordEntry & Add(view_t v, const Request &req, RecordEntryState state);
+    LogEntry * Find(opid_t opid);
+    bool SetStatus(opid_t opid, RecordEntryState state);
+    bool SetRequest(opid_t opid, const Request &req);
+    void Remove(opid_t opid);
+    bool Empty() const;
+
+private:
+    std::map<opid_t, RecordEntry> entries;
+
+};
+
+}      // namespace ir
+
+#endif  /* _IR_RECORD_H_ */