diff --git a/.gitignore b/.gitignore
index 73041fa172458844ed9fb63376a65e3893929796..d92c19c88b771f93c86183ed55afa7be9be09ba8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,3 @@
-*.sekret
-*.sqlite
-*.log
 *~
 \#*\#
 .\#*
diff --git a/primary/.gitignore b/primary/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c4c53c804943031be0c755915d85c53e73beca7b
--- /dev/null
+++ b/primary/.gitignore
@@ -0,0 +1 @@
+/var
diff --git a/primary/server/app.js b/primary/app.js
similarity index 70%
rename from primary/server/app.js
rename to primary/app.js
index f44582a04fa392f94a16296b771fd88e3b5bbbd8..9aee24b82fa72d8d1a29753e3a6dcf17d2903bc5 100644
--- a/primary/server/app.js
+++ b/primary/app.js
@@ -1,21 +1,27 @@
 const        path = require('path'),
+fs = require('fs'),
 url = require('url'),
-wsapi = require('./wsapi.js'),
-httputils = require('./httputils.js'),
-webfinger = require('./webfinger.js'),
+wsapi = require('./lib/wsapi.js'),
+httputils = require('./lib/httputils.js'),
+webfinger = require('./lib/webfinger.js'),
 sessions = require('cookie-sessions'),
-secrets = require('./secrets.js');
+secrets = require('./lib/secrets.js');
 
-const STATIC_DIR = path.join(path.dirname(__dirname), "static");
+// create the var directory if it doesn't exist
+var VAR_DIR = path.join(__dirname, "var");
+try { fs.mkdirSync(VAR_DIR, 0755); } catch(e) { }
 
-const COOKIE_SECRET = secrets.hydrateSecret('cookie_secret', __dirname);
+const STATIC_DIR = path.join(__dirname, "static");
 
-function handler(request, response, serveFile) {
+const COOKIE_SECRET = secrets.hydrateSecret('cookie_secret', VAR_DIR);
+
+function handler(request, response, next) {
     // dispatch!
     var urlpath = url.parse(request.url).pathname;
 
     if (urlpath === '/sign_in') {
-        serveFile(path.join(STATIC_DIR, "dialog", "index.html"), response);
+        request.url = "/dialog/index.html";
+        next();
     } else if (/^\/wsapi\/\w+$/.test(urlpath)) {
         try {
             var method = path.basename(urlpath);
@@ -38,13 +44,11 @@ function handler(request, response, serveFile) {
     } else if (urlpath === "/code_update") {
         console.log("code updated.  shutting down.");
         process.exit();
-    } else {
-        // node.js takes care of sanitizing the request path
-        if (urlpath == "/") urlpath = "/index.html"
-        serveFile(path.join(STATIC_DIR, urlpath), response);
     }
 };
 
+exports.varDir = VAR_DIR;
+
 exports.setup = function(app) {
     var week = (7 * 24 * 60 * 60 * 1000);
     app.use(sessions({
diff --git a/primary/server/db.js b/primary/lib/db.js
similarity index 97%
rename from primary/server/db.js
rename to primary/lib/db.js
index ff44730468f91055182d544d8614cb5e54579ec2..e30356da5db9df584a0ee27061764ee12d78811b 100644
--- a/primary/server/db.js
+++ b/primary/lib/db.js
@@ -3,7 +3,7 @@ const sqlite = require('sqlite'),
 
 var db = new sqlite.Database();
 
-db.open(path.join(path.dirname(__dirname), "userdb.sqlite"), function (error) {
+db.open(path.join(path.dirname(__dirname), "var", "userdb.sqlite"), function (error) {
   if (error) {
     console.log("Couldn't open database: " + error);
     throw error;
diff --git a/primary/server/httputils.js b/primary/lib/httputils.js
similarity index 100%
rename from primary/server/httputils.js
rename to primary/lib/httputils.js
diff --git a/primary/server/secrets.js b/primary/lib/secrets.js
similarity index 100%
rename from primary/server/secrets.js
rename to primary/lib/secrets.js
diff --git a/primary/server/webfinger.js b/primary/lib/webfinger.js
similarity index 100%
rename from primary/server/webfinger.js
rename to primary/lib/webfinger.js
diff --git a/primary/server/webfinger_template.xml b/primary/lib/webfinger_template.xml
similarity index 100%
rename from primary/server/webfinger_template.xml
rename to primary/lib/webfinger_template.xml
diff --git a/primary/server/wsapi.js b/primary/lib/wsapi.js
similarity index 100%
rename from primary/server/wsapi.js
rename to primary/lib/wsapi.js
diff --git a/primary/server/standalone.js b/primary/run.js
old mode 100644
new mode 100755
similarity index 73%
rename from primary/server/standalone.js
rename to primary/run.js
index 7197e7c6902c792318e2c9b17f8fa440ffcbf88e..228d290925afbb7cc614b02ad39143dd0bb4660c
--- a/primary/server/standalone.js
+++ b/primary/run.js
@@ -1,6 +1,6 @@
+#!/usr/bin/env node
+
 var   sys = require("sys"),
-     http = require("http"),
-      url = require("url"),
      path = require("path"),
        fs = require("fs"),
   express = require("express");
@@ -13,13 +13,13 @@ var handler = require("./app.js");
 var app = express.createServer();
 
 app.use(express.logger({
-    stream: fs.createWriteStream(path.join(__dirname, "server.log"))
+    stream: fs.createWriteStream(path.join(handler.varDir, "server.log"))
 }));
 
 // let the specific server interact directly with the connect server to register their middleware
 if (handler.setup) handler.setup(app);
 
 // use the connect 'static' middleware for serving of static files (cache headers, HTTP range, etc)
-app.use(express.static(path.join(path.dirname(__dirname), "static")));
+app.use(express.static(path.join(__dirname, "static")));
 
 app.listen(PRIMARY_PORT, PRIMARY_HOST);
diff --git a/run.js b/run.js
index fdb42c908980e4ea2a69a71187de5234d5a0c671..915da6e668ea5f275f8db68c9d14f65ecf1a9702 100755
--- a/run.js
+++ b/run.js
@@ -157,7 +157,7 @@ console.log("Running test servers:");
 dirs.forEach(function(dirObj) {
   if (!fs.statSync(dirObj.path).isDirectory()) return;
   // does this server have a js handler for custom request handling?
-  var handlerPath = path.join(dirObj.path, "server", "app.js");
+  var handlerPath = path.join(dirObj.path, "app.js");
   var runJS = {};
   try {
     var runJSExists = false;
diff --git a/verifier/.gitignore b/verifier/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c4c53c804943031be0c755915d85c53e73beca7b
--- /dev/null
+++ b/verifier/.gitignore
@@ -0,0 +1 @@
+/var