diff --git a/resources/sql/autopatches/20141016.almanac.network.sql b/resources/sql/autopatches/20141016.almanac.network.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20141016.almanac.network.sql
@@ -0,0 +1,11 @@
+CREATE TABLE {$NAMESPACE}_almanac.almanac_network (
+  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  phid VARBINARY(64) NOT NULL,
+  name VARCHAR(128) NOT NULL COLLATE utf8_bin,
+  mailKey BINARY(20) NOT NULL,
+  viewPolicy VARBINARY(64) NOT NULL,
+  editPolicy VARBINARY(64) NOT NULL,
+  dateCreated INT UNSIGNED NOT NULL,
+  dateModified INT UNSIGNED NOT NULL,
+  UNIQUE KEY `key_phid` (phid)
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
diff --git a/resources/sql/autopatches/20141016.almanac.nxaction.sql b/resources/sql/autopatches/20141016.almanac.nxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20141016.almanac.nxaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_almanac.almanac_networktransaction (
+  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
+  authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
+  objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
+  viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
+  editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
+  commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
+  commentVersion INT UNSIGNED NOT NULL,
+  transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
+  oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
+  newValue LONGTEXT COLLATE utf8_bin NOT NULL,
+  contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
+  metadata LONGTEXT COLLATE utf8_bin NOT NULL,
+  dateCreated INT UNSIGNED NOT NULL,
+  dateModified INT UNSIGNED NOT NULL,
+  UNIQUE KEY `key_phid` (`phid`),
+  KEY `key_object` (`objectPHID`)
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -13,6 +13,7 @@
     'AlmanacConsoleController' => 'applications/almanac/controller/AlmanacConsoleController.php',
     'AlmanacController' => 'applications/almanac/controller/AlmanacController.php',
     'AlmanacCreateDevicesCapability' => 'applications/almanac/capability/AlmanacCreateDevicesCapability.php',
+    'AlmanacCreateNetworksCapability' => 'applications/almanac/capability/AlmanacCreateNetworksCapability.php',
     'AlmanacCreateServicesCapability' => 'applications/almanac/capability/AlmanacCreateServicesCapability.php',
     'AlmanacDAO' => 'applications/almanac/storage/AlmanacDAO.php',
     'AlmanacDevice' => 'applications/almanac/storage/AlmanacDevice.php',
@@ -31,6 +32,17 @@
     'AlmanacManagementWorkflow' => 'applications/almanac/management/AlmanacManagementWorkflow.php',
     'AlmanacNames' => 'applications/almanac/util/AlmanacNames.php',
     'AlmanacNamesTestCase' => 'applications/almanac/util/__tests__/AlmanacNamesTestCase.php',
+    'AlmanacNetwork' => 'applications/almanac/storage/AlmanacNetwork.php',
+    'AlmanacNetworkController' => 'applications/almanac/controller/AlmanacNetworkController.php',
+    'AlmanacNetworkEditController' => 'applications/almanac/controller/AlmanacNetworkEditController.php',
+    'AlmanacNetworkEditor' => 'applications/almanac/editor/AlmanacNetworkEditor.php',
+    'AlmanacNetworkListController' => 'applications/almanac/controller/AlmanacNetworkListController.php',
+    'AlmanacNetworkPHIDType' => 'applications/almanac/phid/AlmanacNetworkPHIDType.php',
+    'AlmanacNetworkQuery' => 'applications/almanac/query/AlmanacNetworkQuery.php',
+    'AlmanacNetworkSearchEngine' => 'applications/almanac/query/AlmanacNetworkSearchEngine.php',
+    'AlmanacNetworkTransaction' => 'applications/almanac/storage/AlmanacNetworkTransaction.php',
+    'AlmanacNetworkTransactionQuery' => 'applications/almanac/query/AlmanacNetworkTransactionQuery.php',
+    'AlmanacNetworkViewController' => 'applications/almanac/controller/AlmanacNetworkViewController.php',
     'AlmanacService' => 'applications/almanac/storage/AlmanacService.php',
     'AlmanacServiceController' => 'applications/almanac/controller/AlmanacServiceController.php',
     'AlmanacServiceEditController' => 'applications/almanac/controller/AlmanacServiceEditController.php',
@@ -2931,6 +2943,7 @@
     'AlmanacConsoleController' => 'AlmanacController',
     'AlmanacController' => 'PhabricatorController',
     'AlmanacCreateDevicesCapability' => 'PhabricatorPolicyCapability',
+    'AlmanacCreateNetworksCapability' => 'PhabricatorPolicyCapability',
     'AlmanacCreateServicesCapability' => 'PhabricatorPolicyCapability',
     'AlmanacDAO' => 'PhabricatorLiskDAO',
     'AlmanacDevice' => array(
@@ -2952,6 +2965,20 @@
     'AlmanacManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'AlmanacNames' => 'Phobject',
     'AlmanacNamesTestCase' => 'PhabricatorTestCase',
+    'AlmanacNetwork' => array(
+      'AlmanacDAO',
+      'PhabricatorPolicyInterface',
+    ),
+    'AlmanacNetworkController' => 'AlmanacController',
+    'AlmanacNetworkEditController' => 'AlmanacNetworkController',
+    'AlmanacNetworkEditor' => 'PhabricatorApplicationTransactionEditor',
+    'AlmanacNetworkListController' => 'AlmanacNetworkController',
+    'AlmanacNetworkPHIDType' => 'PhabricatorPHIDType',
+    'AlmanacNetworkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+    'AlmanacNetworkSearchEngine' => 'PhabricatorApplicationSearchEngine',
+    'AlmanacNetworkTransaction' => 'PhabricatorApplicationTransaction',
+    'AlmanacNetworkTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+    'AlmanacNetworkViewController' => 'AlmanacNetworkController',
     'AlmanacService' => array(
       'AlmanacDAO',
       'PhabricatorPolicyInterface',
diff --git a/src/applications/almanac/application/PhabricatorAlmanacApplication.php b/src/applications/almanac/application/PhabricatorAlmanacApplication.php
--- a/src/applications/almanac/application/PhabricatorAlmanacApplication.php
+++ b/src/applications/almanac/application/PhabricatorAlmanacApplication.php
@@ -44,6 +44,11 @@
           'edit/(?:(?P<id>\d+)/)?' => 'AlmanacDeviceEditController',
           'view/(?P<name>[^/]+)/' => 'AlmanacDeviceViewController',
         ),
+        'network/' => array(
+          '(?:query/(?P<queryKey>[^/]+)/)?' => 'AlmanacNetworkListController',
+          'edit/(?:(?P<id>\d+)/)?' => 'AlmanacNetworkEditController',
+          '(?P<id>\d+)/' => 'AlmanacNetworkViewController',
+        ),
       ),
     );
   }
@@ -56,6 +61,9 @@
       AlmanacCreateDevicesCapability::CAPABILITY => array(
         'default' => PhabricatorPolicies::POLICY_ADMIN,
       ),
+      AlmanacCreateNetworksCapability::CAPABILITY => array(
+        'default' => PhabricatorPolicies::POLICY_ADMIN,
+      ),
     );
   }
 
diff --git a/src/applications/almanac/capability/AlmanacCreateNetworksCapability.php b/src/applications/almanac/capability/AlmanacCreateNetworksCapability.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/capability/AlmanacCreateNetworksCapability.php
@@ -0,0 +1,16 @@
+<?php
+
+final class AlmanacCreateNetworksCapability
+  extends PhabricatorPolicyCapability {
+
+  const CAPABILITY = 'almanac.networks';
+
+  public function getCapabilityName() {
+    return pht('Can Create Networks');
+  }
+
+  public function describeCapabilityRejection() {
+    return pht('You do not have permission to create Almanac networks.');
+  }
+
+}
diff --git a/src/applications/almanac/controller/AlmanacConsoleController.php b/src/applications/almanac/controller/AlmanacConsoleController.php
--- a/src/applications/almanac/controller/AlmanacConsoleController.php
+++ b/src/applications/almanac/controller/AlmanacConsoleController.php
@@ -28,6 +28,14 @@
           pht(
             'Manage Almanac devices.')));
 
+    $menu->addItem(
+      id(new PHUIObjectItemView())
+        ->setHeader(pht('Networks'))
+        ->setHref($this->getApplicationURI('network/'))
+        ->addAttribute(
+          pht(
+            'Manage Almanac networks.')));
+
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Console'));
 
diff --git a/src/applications/almanac/controller/AlmanacNetworkController.php b/src/applications/almanac/controller/AlmanacNetworkController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/controller/AlmanacNetworkController.php
@@ -0,0 +1,14 @@
+<?php
+
+abstract class AlmanacNetworkController extends AlmanacController {
+
+  public function buildApplicationCrumbs() {
+    $crumbs = parent::buildApplicationCrumbs();
+
+    $list_uri = $this->getApplicationURI('network/');
+    $crumbs->addTextCrumb(pht('Networks'), $list_uri);
+
+    return $crumbs;
+  }
+
+}
diff --git a/src/applications/almanac/controller/AlmanacServiceEditController.php b/src/applications/almanac/controller/AlmanacNetworkEditController.php
copy from src/applications/almanac/controller/AlmanacServiceEditController.php
copy to src/applications/almanac/controller/AlmanacNetworkEditController.php
--- a/src/applications/almanac/controller/AlmanacServiceEditController.php
+++ b/src/applications/almanac/controller/AlmanacNetworkEditController.php
@@ -1,16 +1,16 @@
 <?php
 
-final class AlmanacServiceEditController
-  extends AlmanacServiceController {
+final class AlmanacNetworkEditController
+  extends AlmanacNetworkController {
 
   public function handleRequest(AphrontRequest $request) {
     $viewer = $request->getViewer();
 
-    $list_uri = $this->getApplicationURI('service');
+    $list_uri = $this->getApplicationURI('network/');
 
     $id = $request->getURIData('id');
     if ($id) {
-      $service = id(new AlmanacServiceQuery())
+      $network = id(new AlmanacNetworkQuery())
         ->setViewer($viewer)
         ->withIDs(array($id))
         ->requireCapabilities(
@@ -19,28 +19,28 @@
             PhabricatorPolicyCapability::CAN_EDIT,
           ))
         ->executeOne();
-      if (!$service) {
+      if (!$network) {
         return new Aphront404Response();
       }
 
       $is_new = false;
-      $service_uri = $service->getURI();
-      $cancel_uri = $service_uri;
-      $title = pht('Edit Service');
+      $network_uri = $this->getApplicationURI('network/'.$network->getID().'/');
+      $cancel_uri = $network_uri;
+      $title = pht('Edit Network');
       $save_button = pht('Save Changes');
     } else {
       $this->requireApplicationCapability(
-        AlmanacCreateServicesCapability::CAPABILITY);
+        AlmanacCreateNetworksCapability::CAPABILITY);
 
-      $service = AlmanacService::initializeNewService();
+      $network = AlmanacNetwork::initializeNewNetwork();
       $is_new = true;
 
       $cancel_uri = $list_uri;
-      $title = pht('Create Service');
-      $save_button = pht('Create Service');
+      $title = pht('Create Network');
+      $save_button = pht('Create Network');
     }
 
-    $v_name = $service->getName();
+    $v_name = $network->getName();
     $e_name = true;
     $validation_exception = null;
 
@@ -49,46 +49,47 @@
       $v_view = $request->getStr('viewPolicy');
       $v_edit = $request->getStr('editPolicy');
 
-      $type_name = AlmanacServiceTransaction::TYPE_NAME;
+      $type_name = AlmanacNetworkTransaction::TYPE_NAME;
       $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
       $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
 
       $xactions = array();
 
-      $xactions[] = id(new AlmanacServiceTransaction())
+      $xactions[] = id(new AlmanacNetworkTransaction())
         ->setTransactionType($type_name)
         ->setNewValue($v_name);
 
-      $xactions[] = id(new AlmanacServiceTransaction())
+      $xactions[] = id(new AlmanacNetworkTransaction())
         ->setTransactionType($type_view)
         ->setNewValue($v_view);
 
-      $xactions[] = id(new AlmanacServiceTransaction())
+      $xactions[] = id(new AlmanacNetworkTransaction())
         ->setTransactionType($type_edit)
         ->setNewValue($v_edit);
 
-      $editor = id(new AlmanacServiceEditor())
+      $editor = id(new AlmanacNetworkEditor())
         ->setActor($viewer)
         ->setContentSourceFromRequest($request)
         ->setContinueOnNoEffect(true);
 
       try {
-        $editor->applyTransactions($service, $xactions);
+        $editor->applyTransactions($network, $xactions);
 
-        $service_uri = $service->getURI();
-        return id(new AphrontRedirectResponse())->setURI($service_uri);
+        $id = $network->getID();
+        $network_uri = $this->getApplicationURI("network/{$id}/");
+        return id(new AphrontRedirectResponse())->setURI($network_uri);
       } catch (PhabricatorApplicationTransactionValidationException $ex) {
         $validation_exception = $ex;
         $e_name = $ex->getShortMessage($type_name);
 
-        $service->setViewPolicy($v_view);
-        $service->setEditPolicy($v_edit);
+        $network->setViewPolicy($v_view);
+        $network->setEditPolicy($v_edit);
       }
     }
 
     $policies = id(new PhabricatorPolicyQuery())
       ->setViewer($viewer)
-      ->setObject($service)
+      ->setObject($network)
       ->execute();
 
     $form = id(new AphrontFormView())
@@ -102,13 +103,13 @@
       ->appendChild(
         id(new AphrontFormPolicyControl())
           ->setName('viewPolicy')
-          ->setPolicyObject($service)
+          ->setPolicyObject($network)
           ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
           ->setPolicies($policies))
       ->appendChild(
         id(new AphrontFormPolicyControl())
           ->setName('editPolicy')
-          ->setPolicyObject($service)
+          ->setPolicyObject($network)
           ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
           ->setPolicies($policies))
       ->appendChild(
@@ -123,9 +124,9 @@
 
     $crumbs = $this->buildApplicationCrumbs();
     if ($is_new) {
-      $crumbs->addTextCrumb(pht('Create Service'));
+      $crumbs->addTextCrumb(pht('Create Network'));
     } else {
-      $crumbs->addTextCrumb($service->getName(), $service_uri);
+      $crumbs->addTextCrumb($network->getName(), $network_uri);
       $crumbs->addTextCrumb(pht('Edit'));
     }
 
diff --git a/src/applications/almanac/controller/AlmanacNetworkListController.php b/src/applications/almanac/controller/AlmanacNetworkListController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/controller/AlmanacNetworkListController.php
@@ -0,0 +1,52 @@
+<?php
+
+final class AlmanacNetworkListController
+  extends AlmanacNetworkController {
+
+  public function shouldAllowPublic() {
+    return true;
+  }
+
+  public function handleRequest(AphrontRequest $request) {
+    $controller = id(new PhabricatorApplicationSearchController())
+      ->setQueryKey($request->getURIData('queryKey'))
+      ->setSearchEngine(new AlmanacNetworkSearchEngine())
+      ->setNavigation($this->buildSideNavView());
+
+    return $this->delegateToController($controller);
+  }
+
+  public function buildApplicationCrumbs() {
+    $crumbs = parent::buildApplicationCrumbs();
+
+    $can_create = $this->hasApplicationCapability(
+      AlmanacCreateNetworksCapability::CAPABILITY);
+
+    $crumbs->addAction(
+      id(new PHUIListItemView())
+        ->setName(pht('Create Network'))
+        ->setHref($this->getApplicationURI('network/edit/'))
+        ->setIcon('fa-plus-square')
+        ->setDisabled(!$can_create)
+        ->setWorkflow(!$can_create));
+
+    return $crumbs;
+  }
+
+  public function buildSideNavView() {
+    $viewer = $this->getViewer();
+
+    $nav = new AphrontSideNavFilterView();
+    $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
+
+    id(new AlmanacNetworkSearchEngine())
+      ->setViewer($viewer)
+      ->addNavigationItems($nav->getMenu());
+
+    $nav->selectFilter(null);
+
+    return $nav;
+  }
+
+
+}
diff --git a/src/applications/almanac/controller/AlmanacNetworkViewController.php b/src/applications/almanac/controller/AlmanacNetworkViewController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/controller/AlmanacNetworkViewController.php
@@ -0,0 +1,95 @@
+<?php
+
+final class AlmanacNetworkViewController
+  extends AlmanacNetworkController {
+
+  public function shouldAllowPublic() {
+    return true;
+  }
+
+  public function handleRequest(AphrontRequest $request) {
+    $viewer = $request->getViewer();
+
+    $id = $request->getURIData('id');
+
+    $network = id(new AlmanacNetworkQuery())
+      ->setViewer($viewer)
+      ->withIDs(array($id))
+      ->executeOne();
+    if (!$network) {
+      return new Aphront404Response();
+    }
+
+    $title = pht('Network %s', $network->getName());
+
+    $property_list = $this->buildPropertyList($network);
+    $action_list = $this->buildActionList($network);
+    $property_list->setActionList($action_list);
+
+    $header = id(new PHUIHeaderView())
+      ->setUser($viewer)
+      ->setHeader($network->getName())
+      ->setPolicyObject($network);
+
+    $box = id(new PHUIObjectBoxView())
+      ->setHeader($header)
+      ->addPropertyList($property_list);
+
+    $crumbs = $this->buildApplicationCrumbs();
+    $crumbs->addTextCrumb($network->getName());
+
+    $xactions = id(new AlmanacNetworkTransactionQuery())
+      ->setViewer($viewer)
+      ->withObjectPHIDs(array($network->getPHID()))
+      ->execute();
+
+    $xaction_view = id(new PhabricatorApplicationTransactionView())
+      ->setUser($viewer)
+      ->setObjectPHID($network->getPHID())
+      ->setTransactions($xactions)
+      ->setShouldTerminate(true);
+
+    return $this->buildApplicationPage(
+      array(
+        $crumbs,
+        $box,
+        $xaction_view,
+      ),
+      array(
+        'title' => $title,
+      ));
+  }
+
+  private function buildPropertyList(AlmanacNetwork $network) {
+    $viewer = $this->getViewer();
+
+    $properties = id(new PHUIPropertyListView())
+      ->setUser($viewer);
+
+    return $properties;
+  }
+
+  private function buildActionList(AlmanacNetwork $network) {
+    $viewer = $this->getViewer();
+    $id = $network->getID();
+
+    $can_edit = PhabricatorPolicyFilter::hasCapability(
+      $viewer,
+      $network,
+      PhabricatorPolicyCapability::CAN_EDIT);
+
+    $actions = id(new PhabricatorActionListView())
+      ->setUser($viewer);
+
+    $actions->addAction(
+      id(new PhabricatorActionView())
+        ->setIcon('fa-pencil')
+        ->setName(pht('Edit Network'))
+        ->setHref($this->getApplicationURI("network/edit/{$id}/"))
+        ->setWorkflow(!$can_edit)
+        ->setDisabled(!$can_edit));
+
+    return $actions;
+  }
+
+}
diff --git a/src/applications/almanac/controller/AlmanacServiceEditController.php b/src/applications/almanac/controller/AlmanacServiceEditController.php
--- a/src/applications/almanac/controller/AlmanacServiceEditController.php
+++ b/src/applications/almanac/controller/AlmanacServiceEditController.php
@@ -6,7 +6,7 @@
   public function handleRequest(AphrontRequest $request) {
     $viewer = $request->getViewer();
 
-    $list_uri = $this->getApplicationURI('service');
+    $list_uri = $this->getApplicationURI('service/');
 
     $id = $request->getURIData('id');
     if ($id) {
diff --git a/src/applications/almanac/editor/AlmanacNetworkEditor.php b/src/applications/almanac/editor/AlmanacNetworkEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/editor/AlmanacNetworkEditor.php
@@ -0,0 +1,108 @@
+<?php
+
+final class AlmanacNetworkEditor
+  extends PhabricatorApplicationTransactionEditor {
+
+  public function getEditorApplicationClass() {
+    return 'PhabricatorAlmanacApplication';
+  }
+
+  public function getEditorObjectsDescription() {
+    return pht('Almanac Network');
+  }
+
+  public function getTransactionTypes() {
+    $types = parent::getTransactionTypes();
+
+    $types[] = AlmanacNetworkTransaction::TYPE_NAME;
+    $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+    $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+    return $types;
+  }
+
+  protected function getCustomTransactionOldValue(
+    PhabricatorLiskDAO $object,
+    PhabricatorApplicationTransaction $xaction) {
+    switch ($xaction->getTransactionType()) {
+      case AlmanacNetworkTransaction::TYPE_NAME:
+        return $object->getName();
+    }
+
+    return parent::getCustomTransactionOldValue($object, $xaction);
+  }
+
+  protected function getCustomTransactionNewValue(
+    PhabricatorLiskDAO $object,
+    PhabricatorApplicationTransaction $xaction) {
+
+    switch ($xaction->getTransactionType()) {
+      case AlmanacNetworkTransaction::TYPE_NAME:
+        return $xaction->getNewValue();
+    }
+
+    return parent::getCustomTransactionNewValue($object, $xaction);
+  }
+
+  protected function applyCustomInternalTransaction(
+    PhabricatorLiskDAO $object,
+    PhabricatorApplicationTransaction $xaction) {
+
+    switch ($xaction->getTransactionType()) {
+      case AlmanacNetworkTransaction::TYPE_NAME:
+        $object->setName($xaction->getNewValue());
+        return;
+      case PhabricatorTransactions::TYPE_VIEW_POLICY:
+      case PhabricatorTransactions::TYPE_EDIT_POLICY:
+        return;
+    }
+
+    return parent::applyCustomInternalTransaction($object, $xaction);
+  }
+
+  protected function applyCustomExternalTransaction(
+    PhabricatorLiskDAO $object,
+    PhabricatorApplicationTransaction $xaction) {
+
+    switch ($xaction->getTransactionType()) {
+      case AlmanacNetworkTransaction::TYPE_NAME:
+      case PhabricatorTransactions::TYPE_VIEW_POLICY:
+      case PhabricatorTransactions::TYPE_EDIT_POLICY:
+        return;
+    }
+
+    return parent::applyCustomExternalTransaction($object, $xaction);
+  }
+
+  protected function validateTransaction(
+    PhabricatorLiskDAO $object,
+    $type,
+    array $xactions) {
+
+    $errors = parent::validateTransaction($object, $type, $xactions);
+
+    switch ($type) {
+      case AlmanacServiceTransaction::TYPE_NAME:
+        $missing = $this->validateIsEmptyTextField(
+          $object->getName(),
+          $xactions);
+
+        if ($missing) {
+          $error = new PhabricatorApplicationTransactionValidationError(
+            $type,
+            pht('Required'),
+            pht('Network name is required.'),
+            nonempty(last($xactions), null));
+
+          $error->setIsMissingFieldError(true);
+          $errors[] = $error;
+        }
+        break;
+    }
+
+    return $errors;
+  }
+
+
+
+}
diff --git a/src/applications/almanac/phid/AlmanacNetworkPHIDType.php b/src/applications/almanac/phid/AlmanacNetworkPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/phid/AlmanacNetworkPHIDType.php
@@ -0,0 +1,39 @@
+<?php
+
+final class AlmanacNetworkPHIDType extends PhabricatorPHIDType {
+
+  const TYPECONST = 'ANET';
+
+  public function getTypeName() {
+    return pht('Almanac Network');
+  }
+
+  public function newObject() {
+    return new AlmanacNetwork();
+  }
+
+  protected function buildQueryForObjects(
+    PhabricatorObjectQuery $query,
+    array $phids) {
+
+    return id(new AlmanacNetworkQuery())
+      ->withPHIDs($phids);
+  }
+
+  public function loadHandles(
+    PhabricatorHandleQuery $query,
+    array $handles,
+    array $objects) {
+
+    foreach ($handles as $phid => $handle) {
+      $network = $objects[$phid];
+
+      $id = $network->getID();
+      $name = $network->getName();
+
+      $handle->setObjectName(pht('Network %d', $id));
+      $handle->setName($name);
+    }
+  }
+
+}
diff --git a/src/applications/almanac/query/AlmanacDeviceSearchEngine.php b/src/applications/almanac/query/AlmanacDeviceSearchEngine.php
--- a/src/applications/almanac/query/AlmanacDeviceSearchEngine.php
+++ b/src/applications/almanac/query/AlmanacDeviceSearchEngine.php
@@ -7,6 +7,10 @@
     return pht('Almanac Devices');
   }
 
+  protected function getApplicationClassName() {
+    return 'PhabricatorAlmanacApplication';
+  }
+
   public function buildSavedQueryFromRequest(AphrontRequest $request) {
     $saved = new PhabricatorSavedQuery();
 
@@ -76,4 +80,5 @@
 
     return $list;
   }
+
 }
diff --git a/src/applications/almanac/query/AlmanacNetworkQuery.php b/src/applications/almanac/query/AlmanacNetworkQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/query/AlmanacNetworkQuery.php
@@ -0,0 +1,60 @@
+<?php
+
+final class AlmanacNetworkQuery
+  extends PhabricatorCursorPagedPolicyAwareQuery {
+
+  private $ids;
+  private $phids;
+
+  public function withIDs(array $ids) {
+    $this->ids = $ids;
+    return $this;
+  }
+
+  public function withPHIDs(array $phids) {
+    $this->phids = $phids;
+    return $this;
+  }
+
+  protected function loadPage() {
+    $table = new AlmanacNetwork();
+    $conn_r = $table->establishConnection('r');
+
+    $data = queryfx_all(
+      $conn_r,
+      'SELECT * FROM %T %Q %Q %Q',
+      $table->getTableName(),
+      $this->buildWhereClause($conn_r),
+      $this->buildOrderClause($conn_r),
+      $this->buildLimitClause($conn_r));
+
+    return $table->loadAllFromArray($data);
+  }
+
+  protected function buildWhereClause($conn_r) {
+    $where = array();
+
+    if ($this->ids !== null) {
+      $where[] = qsprintf(
+        $conn_r,
+        'id IN (%Ld)',
+        $this->ids);
+    }
+
+    if ($this->phids !== null) {
+      $where[] = qsprintf(
+        $conn_r,
+        'phid IN (%Ls)',
+        $this->phids);
+    }
+
+    $where[] = $this->buildPagingClause($conn_r);
+
+    return $this->formatWhereClause($where);
+  }
+
+  public function getQueryApplicationClass() {
+    return 'PhabricatorAlmanacApplication';
+  }
+
+}
diff --git a/src/applications/almanac/query/AlmanacDeviceSearchEngine.php b/src/applications/almanac/query/AlmanacNetworkSearchEngine.php
copy from src/applications/almanac/query/AlmanacDeviceSearchEngine.php
copy to src/applications/almanac/query/AlmanacNetworkSearchEngine.php
--- a/src/applications/almanac/query/AlmanacDeviceSearchEngine.php
+++ b/src/applications/almanac/query/AlmanacNetworkSearchEngine.php
@@ -1,10 +1,14 @@
 <?php
 
-final class AlmanacDeviceSearchEngine
+final class AlmanacNetworkSearchEngine
   extends PhabricatorApplicationSearchEngine {
 
   public function getResultTypeDescription() {
-    return pht('Almanac Devices');
+    return pht('Almanac Networks');
+  }
+
+  protected function getApplicationClassName() {
+    return 'PhabricatorAlmanacApplication';
   }
 
   public function buildSavedQueryFromRequest(AphrontRequest $request) {
@@ -14,7 +18,7 @@
   }
 
   public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
-    $query = id(new AlmanacDeviceQuery());
+    $query = id(new AlmanacNetworkQuery());
 
     return $query;
   }
@@ -24,12 +28,12 @@
     PhabricatorSavedQuery $saved_query) {}
 
   protected function getURI($path) {
-    return '/almanac/device/'.$path;
+    return '/almanac/network/'.$path;
   }
 
   public function getBuiltinQueryNames() {
     $names = array(
-      'all' => pht('All Devices'),
+      'all' => pht('All Networks'),
     );
 
     return $names;
@@ -49,27 +53,29 @@
   }
 
   protected function getRequiredHandlePHIDsForResultList(
-    array $devices,
+    array $networks,
     PhabricatorSavedQuery $query) {
     return array();
   }
 
   protected function renderResultList(
-    array $devices,
+    array $networks,
     PhabricatorSavedQuery $query,
     array $handles) {
-    assert_instances_of($devices, 'AlmanacDevice');
+    assert_instances_of($networks, 'AlmanacNetwork');
 
     $viewer = $this->requireViewer();
 
     $list = new PHUIObjectItemListView();
     $list->setUser($viewer);
-    foreach ($devices as $device) {
+    foreach ($networks as $network) {
+      $id = $network->getID();
+
       $item = id(new PHUIObjectItemView())
-        ->setObjectName(pht('Device %d', $device->getID()))
-        ->setHeader($device->getName())
-        ->setHref($device->getURI())
-        ->setObject($device);
+        ->setObjectName(pht('Network %d', $id))
+        ->setHeader($network->getName())
+        ->setHref($this->getApplicationURI("network/{$id}/"))
+        ->setObject($network);
 
       $list->addItem($item);
     }
diff --git a/src/applications/almanac/query/AlmanacNetworkTransactionQuery.php b/src/applications/almanac/query/AlmanacNetworkTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/query/AlmanacNetworkTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class AlmanacNetworkTransactionQuery
+  extends PhabricatorApplicationTransactionQuery {
+
+  public function getTemplateApplicationTransaction() {
+    return new AlmanacNetworkTransaction();
+  }
+
+}
diff --git a/src/applications/almanac/query/AlmanacServiceSearchEngine.php b/src/applications/almanac/query/AlmanacServiceSearchEngine.php
--- a/src/applications/almanac/query/AlmanacServiceSearchEngine.php
+++ b/src/applications/almanac/query/AlmanacServiceSearchEngine.php
@@ -7,6 +7,10 @@
     return pht('Almanac Services');
   }
 
+  protected function getApplicationClassName() {
+    return 'PhabricatorAlmanacApplication';
+  }
+
   public function buildSavedQueryFromRequest(AphrontRequest $request) {
     $saved = new PhabricatorSavedQuery();
 
diff --git a/src/applications/almanac/storage/AlmanacNetwork.php b/src/applications/almanac/storage/AlmanacNetwork.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/storage/AlmanacNetwork.php
@@ -0,0 +1,71 @@
+<?php
+
+final class AlmanacNetwork
+  extends AlmanacDAO
+  implements PhabricatorPolicyInterface {
+
+  protected $name;
+  protected $mailKey;
+  protected $viewPolicy;
+  protected $editPolicy;
+
+  public static function initializeNewNetwork() {
+    return id(new AlmanacNetwork())
+      ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
+      ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN);
+  }
+
+  public function getConfiguration() {
+    return array(
+      self::CONFIG_AUX_PHID => true,
+      self::CONFIG_COLUMN_SCHEMA => array(
+        'name' => 'text128',
+      ),
+    ) + parent::getConfiguration();
+  }
+
+  public function generatePHID() {
+    return PhabricatorPHID::generateNewPHID(AlmanacNetworkPHIDType::TYPECONST);
+  }
+
+  public function save() {
+    if (!$this->mailKey) {
+      $this->mailKey = Filesystem::readRandomCharacters(20);
+    }
+
+    return parent::save();
+  }
+
+  public function getURI() {
+    return '/almanac/network/view/'.$this->getName().'/';
+  }
+
+
+/* -(  PhabricatorPolicyInterface  )----------------------------------------- */
+
+
+  public function getCapabilities() {
+    return array(
+      PhabricatorPolicyCapability::CAN_VIEW,
+      PhabricatorPolicyCapability::CAN_EDIT,
+    );
+  }
+
+  public function getPolicy($capability) {
+    switch ($capability) {
+      case PhabricatorPolicyCapability::CAN_VIEW:
+        return $this->getViewPolicy();
+      case PhabricatorPolicyCapability::CAN_EDIT:
+        return $this->getEditPolicy();
+    }
+  }
+
+  public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+    return false;
+  }
+
+  public function describeAutomaticCapability($capability) {
+    return null;
+  }
+
+}
diff --git a/src/applications/almanac/storage/AlmanacNetworkTransaction.php b/src/applications/almanac/storage/AlmanacNetworkTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/storage/AlmanacNetworkTransaction.php
@@ -0,0 +1,45 @@
+<?php
+
+final class AlmanacNetworkTransaction
+  extends PhabricatorApplicationTransaction {
+
+  const TYPE_NAME = 'almanac:network:name';
+
+  public function getApplicationName() {
+    return 'almanac';
+  }
+
+  public function getApplicationTransactionType() {
+    return AlmanacNetworkPHIDType::TYPECONST;
+  }
+
+  public function getApplicationTransactionCommentObject() {
+    return null;
+  }
+
+  public function getTitle() {
+    $author_phid = $this->getAuthorPHID();
+
+    $old = $this->getOldValue();
+    $new = $this->getNewValue();
+
+    switch ($this->getTransactionType()) {
+      case self::TYPE_NAME:
+        if ($old === null) {
+          return pht(
+            '%s created this network.',
+            $this->renderHandleLink($author_phid));
+        } else {
+          return pht(
+            '%s renamed this network from "%s" to "%s".',
+            $this->renderHandleLink($author_phid),
+            $old,
+            $new);
+        }
+        break;
+    }
+
+    return parent::getTitle();
+  }
+
+}