diff --git a/.travis.yml b/.travis.yml
index e19536f9688a91b01a2d6a7a198680d6728a8b13..f45e51808eddfeb6f62408da15c46005907098e6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,8 +43,8 @@ script:
   # Type check the project
   - mypy .
 
-  # Type check the apply module
-  - mypy opentech/apply --check-untyped-defs --ignore-missing-imports
+  # Type check the project
+  - mypy .
 
   # Run system checks
   - python manage.py check
diff --git a/mypy.ini b/mypy.ini
new file mode 100644
index 0000000000000000000000000000000000000000..6241fe330bb35fb5105434739d2940681c363ae3
--- /dev/null
+++ b/mypy.ini
@@ -0,0 +1,13 @@
+[mypy]
+show_column_numbers = True
+ignore_missing_imports = True
+
+[mypy-opentech.*]
+ignore_errors = True
+
+[mypy-opentech.apply.*]
+check_untyped_defs = True
+ignore_errors = False
+
+[mypy-opentech.apply.tests.*]
+# ignore_errors = True
\ No newline at end of file
diff --git a/opentech/apply/tests/test_workflow.py b/opentech/apply/tests/test_workflow.py
index 79d090c861c248c804bfcab6310374bfe15bc6bf..6548e295d7a5531d6f7947048a828c23eefe3722 100644
--- a/opentech/apply/tests/test_workflow.py
+++ b/opentech/apply/tests/test_workflow.py
@@ -44,7 +44,7 @@ class TestStageCreation(SimpleTestCase):
 
     def test_can_iterate_through_phases(self):
         stage = StageFactory()
-        for phase, check in zip(stage, stage.phases):
+        for phase, check in zip(stage, stage.phases):  # type: ignore # spurious error
             self.assertEqual(phase, check)
 
 
diff --git a/opentech/apply/workflow.py b/opentech/apply/workflow.py
index 6476941d31896caeb62c2321cbd524c00b8a5cd1..adabfc81cfa61500af62eae097cc5e7d2fc5eb62 100644
--- a/opentech/apply/workflow.py
+++ b/opentech/apply/workflow.py
@@ -1,4 +1,4 @@
-from typing import Iterator, Iterable, Sequence, Union
+from typing import Dict, Iterator, Iterable, Sequence, Tuple, Union
 
 from django.forms import Form
 
@@ -9,8 +9,8 @@ class Workflow:
         self.stages = stages
         self.mapping = self.build_mapping(stages)
 
-    def build_mapping(self, stages):
-        mapping = {}
+    def build_mapping(self, stages: Sequence['Stage']) -> Dict[str, Tuple[int, int]]:
+        mapping:  Dict[str, Tuple[int, int]] = {}
         for i, stage in enumerate(stages):
             for j, phase in enumerate(stage):
                 while str(phase) in mapping:
@@ -26,7 +26,7 @@ class Workflow:
         except KeyError:
             return 0, -1
 
-    def next(self, current_phase: Union['Phase', str, None]=None) -> Union['Phase', None]:
+    def next(self, current_phase: Union['Phase', str]=None) -> Union['Phase', None]:
         stage_idx, phase_idx = self.current_index(current_phase)
         try:
             return self.stages[stage_idx].phases[phase_idx + 1]
@@ -57,6 +57,7 @@ class Stage(Iterable['Phase']):
 class Phase:
     def __init__(self, name: str) -> None:
         self.name = name
+        self.stage: Union['Stage', None] = None
         self.occurance = 0
 
     def __str__(self):
diff --git a/vagrant/provision.sh b/vagrant/provision.sh
index ac208e58ff68148ff1cde25c20357cc89614b113..77866f4b201720c13e624d15e2813e5d6635835b 100755
--- a/vagrant/provision.sh
+++ b/vagrant/provision.sh
@@ -51,6 +51,6 @@ source $VIRTUALENV_DIR/bin/activate
 export PS1="[$PROJECT_NAME \W]\\$ "
 cd $PROJECT_DIR
 
-alias djtestapply="dj test opentech.apply --keepdb; mypy opentech/apply --check-untyped-defs --ignore-missing-imports"
+alias djtestapply="dj test opentech.apply --keepdb; mypy ."
 
 EOF