diff --git a/opentech/apply/funds/migrations/0059_add_community_review_workflow.py b/opentech/apply/funds/migrations/0059_add_community_review_workflow.py
new file mode 100644
index 0000000000000000000000000000000000000000..81aaae5d5646e6decc021559061a9d4874d30914
--- /dev/null
+++ b/opentech/apply/funds/migrations/0059_add_community_review_workflow.py
@@ -0,0 +1,33 @@
+# Generated by Django 2.0.10 on 2019-03-25 13:00
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('funds', '0058_add_group_toggle'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='applicationbase',
+            name='workflow_name',
+            field=models.CharField(choices=[('single', 'Request'), ('single_ext', 'Request with external review'), ('single_com', 'Request with community review'), ('double', 'Concept & Proposal')], default='single', max_length=100, verbose_name='Workflow'),
+        ),
+        migrations.AlterField(
+            model_name='applicationsubmission',
+            name='workflow_name',
+            field=models.CharField(choices=[('single', 'Request'), ('single_ext', 'Request with external review'), ('single_com', 'Request with community review'), ('double', 'Concept & Proposal')], default='single', max_length=100, verbose_name='Workflow'),
+        ),
+        migrations.AlterField(
+            model_name='labbase',
+            name='workflow_name',
+            field=models.CharField(choices=[('single', 'Request'), ('single_ext', 'Request with external review'), ('single_com', 'Request with community review'), ('double', 'Concept & Proposal')], default='single', max_length=100, verbose_name='Workflow'),
+        ),
+        migrations.AlterField(
+            model_name='roundbase',
+            name='workflow_name',
+            field=models.CharField(choices=[('single', 'Request'), ('single_ext', 'Request with external review'), ('single_com', 'Request with community review'), ('double', 'Concept & Proposal')], default='single', max_length=100, verbose_name='Workflow'),
+        ),
+    ]
diff --git a/opentech/apply/funds/models/utils.py b/opentech/apply/funds/models/utils.py
index bae4ce5fbd2768cb7dae0eace3143b956773fb58..c6c8ecb6153718edac9468dd0848c472888d23d1 100644
--- a/opentech/apply/funds/models/utils.py
+++ b/opentech/apply/funds/models/utils.py
@@ -12,7 +12,7 @@ from wagtail.contrib.forms.models import AbstractEmailForm
 
 from opentech.apply.activity.messaging import messenger, MESSAGES
 from opentech.apply.stream_forms.models import AbstractStreamForm
-from opentech.apply.users.groups import REVIEWER_GROUP_NAME, STAFF_GROUP_NAME, PARTNER_GROUP_NAME
+from opentech.apply.users.groups import REVIEWER_GROUP_NAME, STAFF_GROUP_NAME, PARTNER_GROUP_NAME, COMMUNITY_REVIEWER_GROUP_NAME
 
 from ..workflow import WORKFLOWS
 
@@ -21,6 +21,7 @@ LIMIT_TO_STAFF = {'groups__name': STAFF_GROUP_NAME}
 LIMIT_TO_REVIEWERS = {'groups__name': REVIEWER_GROUP_NAME}
 LIMIT_TO_STAFF_AND_REVIEWERS = {'groups__name__in': [STAFF_GROUP_NAME, REVIEWER_GROUP_NAME]}
 LIMIT_TO_PARTNERS = {'groups__name': PARTNER_GROUP_NAME}
+LIMIT_TO_COMMUNITY_REVIEWERS = {'groups__name': COMMUNITY_REVIEWER_GROUP_NAME}
 
 
 def admin_url(page):
diff --git a/opentech/apply/funds/workflow.py b/opentech/apply/funds/workflow.py
index 6380e1b5437d74252fbaacc56fdbb71501fee910..c28f764fd933c8997c73ed14df204c1745873bcb 100644
--- a/opentech/apply/funds/workflow.py
+++ b/opentech/apply/funds/workflow.py
@@ -70,6 +70,7 @@ class Phase:
     public_name = phase name displayed to applicants in the system
     future_name = phase_name displayed to applicants if they haven't passed this stage
     """
+
     def __init__(self, name, display, stage, permissions, step, public=None, future=None, transitions=dict()):
         self.name = name
         self.display_name = display
@@ -142,7 +143,9 @@ applicant_can = lambda user: user.is_applicant  # NOQA
 
 reviewer_can = lambda user: user.is_reviewer  # NOQA
 
-partner_can = lambda user: user.is_partner # NOQA
+partner_can = lambda user: user.is_partner  # NOQA
+
+community_can = lambda user: user.is_community_reviewer  # NOQA
 
 
 def make_permissions(edit=list(), review=list(), view=[staff_can, applicant_can, reviewer_can]):
@@ -161,6 +164,8 @@ hidden_from_applicant_permissions = make_permissions(edit=[staff_can], review=[s
 
 reviewer_review_permissions = make_permissions(edit=[staff_can, partner_can], review=[staff_can, reviewer_can, partner_can])
 
+community_review_permissions = make_permissions(edit=[staff_can], review=[staff_can, reviewer_can, community_can])
+
 applicant_edit_permissions = make_permissions(edit=[applicant_can], review=[staff_can])
 
 staff_applicant_edit_permissions = make_permissions(edit=[staff_can, applicant_can])
@@ -172,6 +177,8 @@ Request = Stage('Request', False)
 
 RequestExt = Stage('RequestExt', True)
 
+RequestCom = Stage('RequestCom', True)
+
 Concept = Stage('Concept', False)
 
 Proposal = Stage('Proposal', True)
@@ -400,6 +407,154 @@ SingleStageExternalDefinition = [
 ]
 
 
+SingleStageCommunityDefinition = [
+    {
+        INITIAL_STATE: {
+            'transitions': {
+                'com_internal_review': 'Open Review',
+                'com_open_call': 'Open Call (public)',
+                'com_community_review': 'Open Community Review',
+                'com_rejected': 'Dismiss',
+                'com_more_info': 'Request More Information',
+                'com_determination': 'Ready For Determination',
+            },
+            'display': 'Screening',
+            'public': 'Application Received',
+            'stage': RequestCom,
+            'permissions': default_permissions,
+        },
+        'com_more_info': {
+            'transitions': {
+                INITIAL_STATE: {
+                    'display': 'Submit',
+                    'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN},
+                    'method': 'create_revision',
+                },
+            },
+            'display': 'More information required',
+            'stage': RequestCom,
+            'permissions': applicant_edit_permissions,
+        },
+        'com_open_call': {
+            'transitions': {
+                'com_rejected': 'Dismiss',
+                'com_more_info': 'Request More Information',
+            },
+            'display': 'Open Call (public)',
+            'stage': RequestCom,
+            'permissions': staff_edit_permissions,
+        },
+    },
+    {
+        'com_community_review': {
+            'transitions': {
+                'com_internal_review': 'Open Review',
+                'com_rejected': 'Dismiss',
+            },
+            'display': 'Community Review',
+            'public': 'OTF Review',
+            'stage': RequestCom,
+            'permissions': community_review_permissions,
+        },
+    },
+    {
+        'com_internal_review': {
+            'transitions': {
+                'com_post_review_discussion': 'Close Review',
+            },
+            'display': 'Internal Review',
+            'public': 'OTF Review',
+            'stage': RequestCom,
+            'permissions': default_permissions,
+        },
+    },
+    {
+        'com_post_review_discussion': {
+            'transitions': {
+                'com_external_review': 'Open AC review',
+                'com_rejected': 'Dismiss',
+                'com_post_review_more_info': 'Request More Information',
+                'com_determination': 'Ready For Determination',
+            },
+            'display': 'Ready For Discussion',
+            'stage': RequestCom,
+            'permissions': hidden_from_applicant_permissions,
+        },
+        'com_post_review_more_info': {
+            'transitions': {
+                'com_post_review_discussion': {
+                    'display': 'Submit',
+                    'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN},
+                    'method': 'create_revision',
+                },
+            },
+            'display': 'More information required',
+            'stage': RequestCom,
+            'permissions': applicant_edit_permissions,
+        },
+    },
+    {
+        'com_external_review': {
+            'transitions': {
+                'com_post_external_review_discussion': 'Close Review',
+            },
+            'display': 'Advisory Council Review',
+            'stage': RequestCom,
+            'permissions': reviewer_review_permissions,
+        },
+    },
+    {
+        'com_post_external_review_discussion': {
+            'transitions': {
+                'com_accepted': 'Accept',
+                'com_rejected': 'Dismiss',
+                'com_post_external_review_more_info': 'Request More Information',
+                'com_determination': 'Ready For Determination',
+            },
+            'display': 'Ready For Discussion',
+            'stage': RequestCom,
+            'permissions': hidden_from_applicant_permissions,
+        },
+        'com_post_external_review_more_info': {
+            'transitions': {
+                'com_post_external_review_discussion': {
+                    'display': 'Submit',
+                    'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN},
+                    'method': 'create_revision',
+                },
+            },
+            'display': 'More information required',
+            'stage': RequestCom,
+            'permissions': applicant_edit_permissions,
+        },
+    },
+    {
+        'com_determination': {
+            'transitions': {
+                'com_accepted': 'Accept',
+                'com_rejected': 'Dismiss',
+            },
+            'display': 'Ready for Determination',
+            'permissions': hidden_from_applicant_permissions,
+            'stage': RequestCom,
+        },
+    },
+    {
+        'com_accepted': {
+            'display': 'Accepted',
+            'future': 'Application Outcome',
+            'stage': RequestCom,
+            'permissions': staff_applicant_edit_permissions,
+        },
+        'com_rejected': {
+            'display': 'Dismissed',
+            'stage': RequestCom,
+            'permissions': no_permissions,
+        },
+    },
+]
+
+
 DoubleStageDefinition = [
     {
         INITIAL_STATE: {
@@ -660,12 +815,15 @@ Request = Workflow('Request', 'single', **phase_data(SingleStageDefinition))
 
 RequestExternal = Workflow('Request with external review', 'single_ext', **phase_data(SingleStageExternalDefinition))
 
+RequestCommunity = Workflow('Request with community review', 'single_com', **phase_data(SingleStageCommunityDefinition))
+
 ConceptProposal = Workflow('Concept & Proposal', 'double', **phase_data(DoubleStageDefinition))
 
 
 WORKFLOWS = {
     Request.admin_name: Request,
     RequestExternal.admin_name: RequestExternal,
+    RequestCommunity.admin_name: RequestCommunity,
     ConceptProposal.admin_name: ConceptProposal,
 }
 
@@ -733,6 +891,7 @@ DETERMINATION_RESPONSE_PHASES = [
     'concept_review_discussion',
     'post_external_review_discussion',
     'ext_post_external_review_discussion',
+    'com_post_external_review_discussion',
 ]
 
 
@@ -817,3 +976,7 @@ PHASES_MAPPING = {
         'statuses': phases_matching('rejected'),
     },
 }
+
+OPEN_CALL_PHASES = [
+    'com_open_call',
+]
diff --git a/opentech/apply/users/groups.py b/opentech/apply/users/groups.py
index a3e7bbe881d062c04a225103d1446362cc84cdc9..31887461c21ed6b096231790b4d80c21d0c7aad1 100644
--- a/opentech/apply/users/groups.py
+++ b/opentech/apply/users/groups.py
@@ -2,6 +2,7 @@ STAFF_GROUP_NAME = 'Staff'
 REVIEWER_GROUP_NAME = 'Reviewer'
 TEAMADMIN_GROUP_NAME = 'Team Admin'
 PARTNER_GROUP_NAME = 'Partner'
+COMMUNITY_REVIEWER_GROUP_NAME = 'Community reviewer'
 
 GROUPS = [
     {
@@ -20,4 +21,8 @@ GROUPS = [
         'name': PARTNER_GROUP_NAME,
         'permissions': [],
     },
+    {
+        'name': COMMUNITY_REVIEWER_GROUP_NAME,
+        'permissions': [],
+    },
 ]
diff --git a/opentech/apply/users/migrations/0010_add_community_reviewer_group.py b/opentech/apply/users/migrations/0010_add_community_reviewer_group.py
new file mode 100644
index 0000000000000000000000000000000000000000..a105e64e80b867eae4fec7f91b0bde6864e84466
--- /dev/null
+++ b/opentech/apply/users/migrations/0010_add_community_reviewer_group.py
@@ -0,0 +1,42 @@
+
+# Generated by Django 2.0.9 on 2018-12-19 13:21
+from __future__ import unicode_literals
+
+from django.core.exceptions import ObjectDoesNotExist
+from django.core.management.sql import emit_post_migrate_signal
+from django.db import migrations
+
+from opentech.apply.users.groups import GROUPS, COMMUNITY_REVIEWER_GROUP_NAME
+
+
+def add_groups(apps, schema_editor):
+    # Workaround for https://code.djangoproject.com/ticket/23422
+    db_alias = schema_editor.connection.alias
+    emit_post_migrate_signal(2, False, db_alias)
+
+    Group = apps.get_model('auth.Group')
+    Permission = apps.get_model('auth.Permission')
+
+    for group_data in GROUPS:
+        group, created = Group.objects.get_or_create(name=group_data['name'])
+        for permission in group_data['permissions']:
+            try:
+                group.permissions.add(Permission.objects.get(codename=permission))
+            except ObjectDoesNotExist:
+                print("Could not find the '%s' permission" % permission)
+
+
+def remove_groups(apps, schema_editor):
+    Group = apps.get_model('auth.Group')
+    Group.objects.filter(name__in=[COMMUNITY_REVIEWER_GROUP_NAME]).delete()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('users', '0009_add_partner_group'),
+    ]
+
+    operations = [
+        migrations.RunPython(add_groups, remove_groups)
+    ]
diff --git a/opentech/apply/users/models.py b/opentech/apply/users/models.py
index 3d819bd2885b47b06d50d651d5742b222376f400..3752a5761040f3ce1fc3e66ce5cab329e592e653 100644
--- a/opentech/apply/users/models.py
+++ b/opentech/apply/users/models.py
@@ -4,7 +4,7 @@ from django.contrib.auth.models import AbstractUser, BaseUserManager
 from django.utils.functional import cached_property
 from django.utils.translation import gettext_lazy as _
 
-from .groups import REVIEWER_GROUP_NAME, STAFF_GROUP_NAME, PARTNER_GROUP_NAME
+from .groups import REVIEWER_GROUP_NAME, STAFF_GROUP_NAME, PARTNER_GROUP_NAME, COMMUNITY_REVIEWER_GROUP_NAME
 from .utils import send_activation_email
 
 
@@ -20,6 +20,9 @@ class UserQuerySet(models.QuerySet):
     def partners(self):
         return self.filter(groups__name=PARTNER_GROUP_NAME)
 
+    def community_reviewers(self):
+        return self.filter(groups__name=COMMUNITY_REVIEWER_GROUP_NAME)
+
 
 class UserManager(BaseUserManager.from_queryset(UserQuerySet)):
     use_in_migrations = True
@@ -104,6 +107,10 @@ class User(AbstractUser):
     def is_partner(self):
         return self.groups.filter(name=PARTNER_GROUP_NAME).exists()
 
+    @cached_property
+    def is_community_reviewer(self):
+        return self.groups.filter(name=COMMUNITY_REVIEWER_GROUP_NAME).exists()
+
     @cached_property
     def is_applicant(self):
         return not self.is_apply_staff and not self.is_reviewer and not self.is_partner