diff --git a/scipost_django/tasks/tasks/task_kinds.py b/scipost_django/tasks/tasks/task_kinds.py
index ba79a922ed8d25d1fc42a0643ec33d27a1b960df..3f6a40a8cc7595c40bbce014df6cb75c21cf9f59 100644
--- a/scipost_django/tasks/tasks/task_kinds.py
+++ b/scipost_django/tasks/tasks/task_kinds.py
@@ -16,7 +16,12 @@ from django.db.models import (
 from django.db.models.functions import Cast, Coalesce
 from django.urls import reverse_lazy
 from django.utils import timezone
-from scipost.templatetags.user_groups import is_financial_admin
+from scipost.templatetags.user_groups import (
+    is_active_fellow,
+    is_ed_admin,
+    is_financial_admin,
+)
+from guardian.shortcuts import get_objects_for_user
 from tasks.tasks.task import TaskKind
 from tasks.tasks.task_action import ViewAction
 
@@ -41,6 +46,11 @@ def get_all_task_kinds(user: "User | None" = None) -> Collection[type[TaskKind]]
     return classes
 
 
+##########################
+## Financial Admin Tasks
+##########################
+
+
 class ScheduleSubsidyPayments(TaskKind):
     name = "Schedule Subsidy Payments"
     task_title = "Schedule Payments for {object}"
@@ -207,3 +217,149 @@ class CheckSubsidyPaymentTask(TaskKind):
             )
             .filter(Q(status=SUBSIDY_INVOICED))
         )
+
+
+#####################
+## Fellow Tasks
+#####################
+
+
+class TreatOngoingAssignmentsTask(TaskKind):
+    name = "Treat Ongoing Assignments"
+    task_title = "{object}"
+    description = "Continue your work for your ongoing editorial assignments."
+    template_name = "tasks/kinds/editorial_assignment.html"
+    actions = [
+        lambda task: ViewAction(
+            url=reverse_lazy(
+                "submissions:editorial_page",
+                kwargs={
+                    "identifier_w_vn_nr": task.data[
+                        "object"
+                    ].submission.preprint.identifier_w_vn_nr
+                },
+            ),
+            content="Editorial page",
+        ),
+    ]
+
+    @staticmethod
+    def is_user_eligible(user):
+        return is_active_fellow(user) if user is not None else False
+
+    @classmethod
+    def get_queryset(cls) -> "QuerySet":
+        from submissions.models.assignment import EditorialAssignment
+
+        if cls.user is None:
+            return EditorialAssignment.objects.none()
+
+        return (
+            EditorialAssignment.objects.ongoing()
+            .filter(to=cls.user.contributor)
+            .prefetch_related("submission")
+        )
+
+
+class VetCommentTask(TaskKind):
+    name = "Vet Comment"
+    task_title = "Vet {object}"
+    description = "Vet a comment that has been submitted for approval."
+    actions = [
+        lambda task: ViewAction(
+            url=reverse_lazy(
+                "comments:vet_submitted_comment",
+                kwargs={"comment_id": task.data["object"].pk},
+            ),
+            content="Vet",
+        ),
+    ]
+
+    @staticmethod
+    def is_user_eligible(user):
+        return (
+            is_active_fellow(user) or is_ed_admin(user) if user is not None else False
+        )
+
+    @classmethod
+    def get_queryset(cls) -> "QuerySet":
+        return get_objects_for_user(
+            cls.user, "comments.can_vet_comments"
+        ).awaiting_vetting()
+
+
+class VetReportTask(TaskKind):
+    name = "Vet Report"
+    task_title = "Vet {object}"
+    description = "Vet a report that has been submitted for approval."
+    actions = [
+        lambda task: ViewAction(
+            url=reverse_lazy(
+                "submissions:vet_submitted_report",
+                kwargs={"report_id": task.data["object"].pk},
+            ),
+            content="Vet",
+        ),
+    ]
+
+    @staticmethod
+    def is_user_eligible(user):
+        return (
+            is_active_fellow(user)
+            or is_ed_admin(user)
+            or user.has_perm("scipost.can_vet_submitted_reports")
+            if user is not None
+            else False
+        )
+
+    @classmethod
+    def get_queryset(cls) -> "QuerySet":
+        from submissions.models.report import Report
+        from submissions.models.submission import Submission
+
+        if cls.user is None:
+            return Report.objects.none()
+
+        if cls.user.has_perm("scipost.can_vet_submitted_reports"):
+            return Report.objects.awaiting_vetting()
+
+        return Report.objects.filter(
+            submission__in=Submission.objects.in_pool_filter_for_eic(
+                cls.user, latest=False, historical=True
+            )
+        ).awaiting_vetting()
+
+
+class SelectRefereeingCycleTask(TaskKind):
+    name = "Select Refereeing Cycle"
+    task_title = "Select Refereeing Cycle for {object}"
+    description = "Select the refereeing cycle for a submission."
+    actions = [
+        lambda task: ViewAction(
+            url=reverse_lazy(
+                "submissions:editorial_page",
+                kwargs={
+                    "identifier_w_vn_nr": task.data[
+                        "object"
+                    ].preprint.identifier_w_vn_nr
+                },
+            ),
+            content="Editorial page",
+        ),
+    ]
+
+    @staticmethod
+    def is_user_eligible(user):
+        return is_active_fellow(user) if user is not None else False
+
+    @classmethod
+    def get_queryset(cls) -> "QuerySet":
+        from submissions.models.submission import Submission
+
+        if cls.user is None:
+            return Submission.objects.none()
+
+        return Submission.objects.filter(
+            editor_in_charge=cls.user.contributor,
+            refereeing_cycle__isnull=True,
+        )
diff --git a/scipost_django/tasks/templates/tasks/kinds/editorial_assignment.html b/scipost_django/tasks/templates/tasks/kinds/editorial_assignment.html
new file mode 100644
index 0000000000000000000000000000000000000000..b5137d05b1c75486c84b1d04af5ef8794444d322
--- /dev/null
+++ b/scipost_django/tasks/templates/tasks/kinds/editorial_assignment.html
@@ -0,0 +1,36 @@
+<div class="d-flex">
+  <div class="flex-grow-1">
+    <h3 class="fs-5">{{ task.data.object.submission.title }}</h3>
+    <span>by {{ task.data.object.submission.author_list|truncatechars:150 }}</span>
+
+  </div>
+
+  <div class="btn-group"
+       role="group"
+       aria-label="Button group with nested dropdown">
+
+    {% for action in task.actions|slice:":2" %}{{ action.as_html|safe }}{% endfor %}
+
+
+    {% if task.actions|length > 2 %}
+      <div class="btn-group" role="group">
+        <button class="btn btn-sm btn-light dropdown-toggle"
+                type="button"
+                data-bs-toggle="dropdown"
+                aria-expanded="false">
+          <span>More</span>
+        </button>
+        <ul class="dropdown-menu dropdown-menu-end">
+
+          {% for action in task.actions|slice:"2:" %}
+            <li class="dropdown-item">{{ action.element|safe }}</li>
+          {% endfor %}
+
+
+        </ul>
+      </div>
+    {% endif %}
+
+  </div>
+
+</div>