diff --git a/pom.xml b/pom.xml
index 19c9e454a3889292424af69801f815b34bc084b6..9c176a047a2c63a4239b60a665efde084a13e596 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
   <artifactId>git-eca</artifactId>
   <version>0.0.1</version>
   <properties>
-		<eclipse-api-version>0.6.5-SNAPSHOT</eclipse-api-version>
+		<eclipse-api-version>0.6.6</eclipse-api-version>
     <compiler-plugin.version>3.8.1</compiler-plugin.version>
     <maven.compiler.parameters>true</maven.compiler.parameters>
 		<maven.compiler.source>11</maven.compiler.source>
@@ -14,7 +14,7 @@
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
     <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
     <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
-    <quarkus.platform.version>2.6.3.Final</quarkus.platform.version>
+    <quarkus.platform.version>2.9.2.Final</quarkus.platform.version>
     <surefire-plugin.version>2.22.1</surefire-plugin.version>
     <auto-value.version>1.8.2</auto-value.version>
   </properties>
diff --git a/src/main/java/org/eclipsefoundation/git/eca/api/ProjectsAPI.java b/src/main/java/org/eclipsefoundation/git/eca/api/ProjectsAPI.java
index d599e1f54d293480c2a79a461313446c45d0c343..9e95121240aa50c101b224e1ddff06251bd0cfa3 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/api/ProjectsAPI.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/api/ProjectsAPI.java
@@ -15,6 +15,7 @@ import javax.enterprise.context.ApplicationScoped;
 import javax.ws.rs.BeanParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 
 import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
@@ -29,7 +30,7 @@ import org.jboss.resteasy.annotations.GZIP;
  *
  */
 @ApplicationScoped
-@Path("/api/projects")
+@Path("/api")
 @RegisterRestClient
 @GZIP
 public interface ProjectsAPI {
@@ -41,5 +42,11 @@ public interface ProjectsAPI {
 	 * @return a list of Eclipse Foundation projects.
 	 */
 	@GET
+	@Path("projects")
 	Response getProjects(@BeanParam BaseAPIParameters baseParams);
+
+	@GET
+	@Path("interest-groups")
+	@Produces("application/json")
+	Response getInterestGroups(@BeanParam BaseAPIParameters params);
 }
diff --git a/src/main/java/org/eclipsefoundation/git/eca/model/InterestGroupData.java b/src/main/java/org/eclipsefoundation/git/eca/model/InterestGroupData.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2fd06bd8cf50dc3194849403206a0b00885cfb2
--- /dev/null
+++ b/src/main/java/org/eclipsefoundation/git/eca/model/InterestGroupData.java
@@ -0,0 +1,64 @@
+package org.eclipsefoundation.git.eca.model;
+
+import java.util.List;
+
+import org.eclipsefoundation.git.eca.model.Project.GitlabProject;
+import org.eclipsefoundation.git.eca.model.Project.User;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+@JsonDeserialize(builder = AutoValue_InterestGroupData.Builder.class)
+public abstract class InterestGroupData {
+    public abstract String getId();
+    public abstract String getTitle();
+    public abstract String getLogo();
+    public abstract String getState();
+    public abstract String getFoundationdbProjectId();
+    public abstract Descriptor getDescription();
+    public abstract Descriptor getScope();
+    public abstract List<User> getLeads();
+    public abstract List<User> getParticipants();
+    public abstract GitlabProject getGitlab();
+
+    public static Builder builder() {
+        return new AutoValue_InterestGroupData.Builder();
+    }
+
+    @AutoValue.Builder
+    @JsonPOJOBuilder(withPrefix = "set")
+    public static abstract class Builder {
+        public abstract Builder setId(String id);
+        public abstract Builder setTitle(String title);
+        public abstract Builder setGitlab(GitlabProject gitlab);
+        public abstract Builder setLogo(String logo);
+        public abstract Builder setState(String state);
+        public abstract Builder setFoundationdbProjectId(String foundationdbProjectId);
+        public abstract Builder setDescription(Descriptor description);
+        public abstract Builder setScope(Descriptor scope);
+        public abstract Builder setLeads(List<User> leads);
+        public abstract Builder setParticipants(List<User> participants);
+        public abstract InterestGroupData build();
+    }
+
+    @AutoValue
+    @JsonDeserialize(builder = AutoValue_InterestGroupData_Descriptor.Builder.class)
+    public static abstract class Descriptor {
+        public abstract String getSummary();
+        public abstract String getFull();
+
+        public static Builder builder() {
+            return new AutoValue_InterestGroupData_Descriptor.Builder();
+        }
+
+        @AutoValue.Builder
+        @JsonPOJOBuilder(withPrefix = "set")
+        public static abstract class Builder {
+            public abstract Builder setSummary(String summary);
+            public abstract Builder setFull(String full);
+            public abstract Descriptor build();
+        }
+    }
+}
diff --git a/src/main/java/org/eclipsefoundation/git/eca/model/Project.java b/src/main/java/org/eclipsefoundation/git/eca/model/Project.java
index 452b6afaa400d2a6897b998a534e406912a9a71b..ba5be582840bfc05fcd2fd1db3f8dddcb083b7dd 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/model/Project.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/model/Project.java
@@ -38,6 +38,8 @@ public abstract class Project {
 
     public abstract List<User> getCommitters();
 
+    public abstract List<User> getProjectLeads();
+
     @Nullable
     public abstract List<Repo> getRepos();
 
@@ -80,6 +82,8 @@ public abstract class Project {
 
         public abstract Builder setName(String name);
 
+        public abstract Builder setProjectLeads(List<User> projectLeads);
+
         public abstract Builder setCommitters(List<User> committers);
 
         public abstract Builder setRepos(@Nullable List<Repo> repos);
diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java
index f2dbdd22d0c30134ce00200664b32fe7ca9e2171..718f7e8ec64df5771e22504a12591ff5d38df726 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java
@@ -45,10 +45,12 @@ import org.eclipsefoundation.git.eca.model.ValidationRequest;
 import org.eclipsefoundation.git.eca.model.ValidationResponse;
 import org.eclipsefoundation.git.eca.namespace.APIStatusCode;
 import org.eclipsefoundation.git.eca.namespace.ProviderType;
+import org.eclipsefoundation.git.eca.service.InterestGroupService;
 import org.eclipsefoundation.git.eca.service.ProjectsService;
 import org.eclipsefoundation.git.eca.service.UserService;
 import org.eclipsefoundation.git.eca.service.ValidationService;
 import org.jboss.resteasy.annotations.jaxrs.QueryParam;
+import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -88,6 +90,8 @@ public class ValidationResource {
     UserService users;
     @Inject
     ValidationService validation;
+    @Inject
+    InterestGroupService ig;
 
     // Qute templates, generates email bodies
     @Location("simple_fingerprint_ui")
@@ -115,22 +119,27 @@ public class ValidationResource {
             // filter the projects based on the repo URL. At least one repo in project must
             // match the repo URL to be valid
             List<Project> filteredProjects = retrieveProjectsForRequest(req);
-            ValidationResponse r = ValidationResponse.builder()
+            ValidationResponse r = ValidationResponse
+                    .builder()
                     .setStrictMode(req.getStrictMode() != null && req.getStrictMode() ? true : false)
-                    .setTrackedProject(!filteredProjects.isEmpty()).setFingerprint(validation.generateRequestHash(req))
+                    .setTrackedProject(!filteredProjects.isEmpty())
+                    .setFingerprint(validation.generateRequestHash(req))
                     .build();
-
-            List<CommitValidationStatus> statuses = validation.getRequestCommitValidationStatus(wrapper, req,
-                    filteredProjects.isEmpty() ? null : filteredProjects.get(0).getProjectId());
+            List<CommitValidationStatus> statuses = validation
+                    .getRequestCommitValidationStatus(wrapper, req,
+                            filteredProjects.isEmpty() ? null : filteredProjects.get(0).getProjectId());
 
             for (Commit c : req.getCommits()) {
                 // get the current status if present
-                Optional<CommitValidationStatus> status = statuses.stream()
-                        .filter(s -> c.getHash().equals(s.getCommitHash())).findFirst();
+                Optional<CommitValidationStatus> status = statuses
+                        .stream()
+                        .filter(s -> c.getHash().equals(s.getCommitHash()))
+                        .findFirst();
                 // skip the commit validation if already passed
                 if (status.isPresent() && status.get().getErrors().isEmpty()) {
-                    r.addMessage(c.getHash(), "Commit was previously validated, skipping processing",
-                            APIStatusCode.SUCCESS_SKIPPED);
+                    r
+                            .addMessage(c.getHash(), "Commit was previously validated, skipping processing",
+                                    APIStatusCode.SUCCESS_SKIPPED);
                     continue;
                 }
                 // process the request, capturing if we should continue processing
@@ -141,8 +150,9 @@ public class ValidationResource {
                     break;
                 }
             }
-            validation.updateCommitValidationStatus(wrapper, r, req, statuses,
-                    filteredProjects.isEmpty() ? null : filteredProjects.get(0));
+            validation
+                    .updateCommitValidationStatus(wrapper, r, req, statuses,
+                            filteredProjects.isEmpty() ? null : filteredProjects.get(0));
             return r.toResponse();
         } else {
             // create a stubbed response with the errors
@@ -251,13 +261,15 @@ public class ValidationResource {
         EclipseUser eclipseAuthor = getIdentifiedUser(author);
         // if the user is a bot, generate a stubbed user
         if (isAllowedUser(author.getMail()) || users.userIsABot(author.getMail(), filteredProjects)) {
-            addMessage(response, String.format("Automated user '%1$s' detected for author of commit %2$s",
-                    author.getMail(), c.getHash()), c.getHash());
+            addMessage(response, String
+                    .format("Automated user '%1$s' detected for author of commit %2$s", author.getMail(), c.getHash()),
+                    c.getHash());
             eclipseAuthor = EclipseUser.createBotStub(author);
         } else if (eclipseAuthor == null) {
             addMessage(response,
-                    String.format("Could not find an Eclipse user with mail '%1$s' for author of commit %2$s",
-                            author.getMail(), c.getHash()),
+                    String
+                            .format("Could not find an Eclipse user with mail '%1$s' for author of commit %2$s",
+                                    author.getMail(), c.getHash()),
                     c.getHash());
             addError(response, "Author must have an Eclipse Account", c.getHash(), APIStatusCode.ERROR_AUTHOR);
             return true;
@@ -267,13 +279,17 @@ public class ValidationResource {
         EclipseUser eclipseCommitter = getIdentifiedUser(committer);
         // check if whitelisted or bot
         if (isAllowedUser(committer.getMail()) || users.userIsABot(committer.getMail(), filteredProjects)) {
-            addMessage(response, String.format("Automated user '%1$s' detected for committer of commit %2$s",
-                    committer.getMail(), c.getHash()), c.getHash());
+            addMessage(response,
+                    String
+                            .format("Automated user '%1$s' detected for committer of commit %2$s", committer.getMail(),
+                                    c.getHash()),
+                    c.getHash());
             eclipseCommitter = EclipseUser.createBotStub(committer);
         } else if (eclipseCommitter == null) {
             addMessage(response,
-                    String.format("Could not find an Eclipse user with mail '%1$s' for committer of commit %2$s",
-                            committer.getMail(), c.getHash()),
+                    String
+                            .format("Could not find an Eclipse user with mail '%1$s' for committer of commit %2$s",
+                                    committer.getMail(), c.getHash()),
                     c.getHash());
             addError(response, "Committing user must have an Eclipse Account", c.getHash(),
                     APIStatusCode.ERROR_COMMITTER);
@@ -326,25 +342,32 @@ public class ValidationResource {
             userType = "committer";
         }
         if (isCommitter) {
-            addMessage(r, String.format("Eclipse user '%s'(%s) is a committer on the project.", eclipseUser.getName(),
-                    userType), c.getHash());
+            addMessage(r, String
+                    .format("Eclipse user '%s'(%s) is a committer on the project.", eclipseUser.getName(), userType),
+                    c.getHash());
         } else {
-            addMessage(r, String.format("Eclipse user '%s'(%s) is not a committer on the project.",
-                    eclipseUser.getName(), userType), c.getHash());
+            addMessage(r,
+                    String
+                            .format("Eclipse user '%s'(%s) is not a committer on the project.", eclipseUser.getName(),
+                                    userType),
+                    c.getHash());
             // check if the author is signed off if not a committer
             if (eclipseUser.getECA().getSigned()) {
-                addMessage(r,
-                        String.format(
-                                "Eclipse user '%s'(%s) has a current Eclipse Contributor Agreement (ECA) on file.",
+                addMessage(r, String
+                        .format("Eclipse user '%s'(%s) has a current Eclipse Contributor Agreement (ECA) on file.",
                                 eclipseUser.getName(), userType),
                         c.getHash());
             } else {
-                addMessage(r, String.format(
-                        "Eclipse user '%s'(%s) does not have a current Eclipse Contributor Agreement (ECA) on file.\n"
+                addMessage(r, String
+                        .format("Eclipse user '%s'(%s) does not have a current Eclipse Contributor Agreement (ECA) on file.\n"
                                 + "If there are multiple commits, please ensure that each author has a ECA.",
-                        eclipseUser.getName(), userType), c.getHash());
-                addError(r, String.format("An Eclipse Contributor Agreement is required for Eclipse user '%s'(%s).",
-                        eclipseUser.getName(), userType), c.getHash(), errorCode);
+                                eclipseUser.getName(), userType),
+                        c.getHash());
+                addError(r,
+                        String
+                                .format("An Eclipse Contributor Agreement is required for Eclipse user '%s'(%s).",
+                                        eclipseUser.getName(), userType),
+                        c.getHash(), errorCode);
             }
         }
     }
@@ -376,13 +399,16 @@ public class ValidationResource {
                 // commit to specs
                 if (p.getSpecWorkingGroup() != null && !user.getECA().getCanContributeSpecProject()) {
                     // set error + update response status
-                    r.addError(hash, String.format(
-                            "Project is a specification for the working group '%1$s', but user does not have permission to modify a specification project",
-                            p.getSpecWorkingGroup()), APIStatusCode.ERROR_SPEC_PROJECT);
+                    r
+                            .addError(hash, String
+                                    .format("Project is a specification for the working group '%1$s', but user does not have permission to modify a specification project",
+                                            p.getSpecWorkingGroup()),
+                                    APIStatusCode.ERROR_SPEC_PROJECT);
                     return false;
                 } else {
-                    LOGGER.debug("User '{}' was found to be a committer on current project repo '{}'", user.getMail(),
-                            p.getName());
+                    LOGGER
+                            .debug("User '{}' was found to be a committer on current project repo '{}'", user.getMail(),
+                                    p.getName());
                     return true;
                 }
             }
@@ -432,6 +458,11 @@ public class ValidationResource {
         }
         // check for all projects that make use of the given repo
         List<Project> availableProjects = projects.getProjects();
+        availableProjects
+                .addAll(cache
+                        .get("all", new MultivaluedMapImpl<>(), Project.class,
+                                () -> ig.adaptInterestGroups(ig.getInterestGroups()))
+                        .orElse(Collections.emptyList()));
         if (availableProjects == null || availableProjects.isEmpty()) {
             LOGGER.warn("Could not find any projects to match against");
             return Collections.emptyList();
@@ -443,22 +474,33 @@ public class ValidationResource {
         if (ProviderType.GITLAB.equals(provider)) {
             // get the path of the project, removing the leading slash
             String projectNamespace = URI.create(repoUrl).getPath().substring(1).toLowerCase();
-            return availableProjects.stream()
-                    .filter(p -> projectNamespace.startsWith(p.getGitlab().getProjectGroup() + "/") && p.getGitlab()
-                            .getIgnoredSubGroups().stream().noneMatch(sg -> projectNamespace.startsWith(sg + "/")))
+            return availableProjects
+                    .stream()
+                    .filter(p -> projectNamespace.startsWith(p.getGitlab().getProjectGroup() + "/") && p
+                            .getGitlab()
+                            .getIgnoredSubGroups()
+                            .stream()
+                            .noneMatch(sg -> projectNamespace.startsWith(sg + "/")))
                     .collect(Collectors.toList());
         } else if (ProviderType.GITHUB.equals(provider)) {
-            return availableProjects.stream()
-                    .filter(p -> p.getGithubRepos().stream()
+            return availableProjects
+                    .stream()
+                    .filter(p -> p
+                            .getGithubRepos()
+                            .stream()
                             .anyMatch(re -> re.getUrl() != null && re.getUrl().endsWith(repoUrl)))
                     .collect(Collectors.toList());
         } else if (ProviderType.GERRIT.equals(provider)) {
-            return availableProjects.stream()
-                    .filter(p -> p.getGerritRepos().stream()
+            return availableProjects
+                    .stream()
+                    .filter(p -> p
+                            .getGerritRepos()
+                            .stream()
                             .anyMatch(re -> re.getUrl() != null && re.getUrl().endsWith(repoUrl)))
                     .collect(Collectors.toList());
         } else {
-            return availableProjects.stream()
+            return availableProjects
+                    .stream()
                     .filter(p -> p.getRepos().stream().anyMatch(re -> re.getUrl().endsWith(repoUrl)))
                     .collect(Collectors.toList());
         }
diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/InterestGroupService.java b/src/main/java/org/eclipsefoundation/git/eca/service/InterestGroupService.java
new file mode 100644
index 0000000000000000000000000000000000000000..9efdc637487785aa1e7d9f9a61d97ce25f978076
--- /dev/null
+++ b/src/main/java/org/eclipsefoundation/git/eca/service/InterestGroupService.java
@@ -0,0 +1,30 @@
+package org.eclipsefoundation.git.eca.service;
+
+import java.util.List;
+
+import org.eclipsefoundation.git.eca.model.InterestGroupData;
+import org.eclipsefoundation.git.eca.model.Project;
+
+/**
+ * Service for retrieving and interacting with interest groups.
+ * 
+ * @author Martin Lowe
+ *
+ */
+public interface InterestGroupService {
+
+    /**
+     * Retrieve all available interest groups.
+     * 
+     * @return list of all available interest groups
+     */
+    List<InterestGroupData> getInterestGroups();
+
+    /**
+     * Converts interest groups into projects for processing downstream.
+     * 
+     * @param igs the interest groups to convert
+     * @return the converted interest groups
+     */
+    List<Project> adaptInterestGroups(List<InterestGroupData> igs);
+}
diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultInterestGroupService.java b/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultInterestGroupService.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fc98e656e79e59a47a9ceaacdf3af8c601fcd5e
--- /dev/null
+++ b/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultInterestGroupService.java
@@ -0,0 +1,64 @@
+package org.eclipsefoundation.git.eca.service.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+import org.eclipsefoundation.core.service.APIMiddleware;
+import org.eclipsefoundation.core.service.CachingService;
+import org.eclipsefoundation.git.eca.api.ProjectsAPI;
+import org.eclipsefoundation.git.eca.model.InterestGroupData;
+import org.eclipsefoundation.git.eca.model.Project;
+import org.eclipsefoundation.git.eca.service.InterestGroupService;
+import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
+
+/**
+ * Default implementation of interest group service.
+ * 
+ * @author Martin Lowe
+ */
+@ApplicationScoped
+public class DefaultInterestGroupService implements InterestGroupService {
+
+    @Inject
+    APIMiddleware middleware;
+    @Inject
+    CachingService cache;
+
+    @Inject
+    @RestClient
+    ProjectsAPI api;
+
+    @Override
+    public List<InterestGroupData> getInterestGroups() {
+        return cache
+                .get("all", new MultivaluedMapImpl<>(), InterestGroupData.class,
+                        () -> middleware.getAll(api::getInterestGroups, InterestGroupData.class))
+                .orElse(Collections.emptyList());
+    }
+
+    @Override
+    public List<Project> adaptInterestGroups(List<InterestGroupData> igs) {
+        return igs
+                .stream()
+                .map(ig -> Project
+                        .builder()
+                        .setProjectId(ig.getFoundationdbProjectId())
+                        .setGerritRepos(Collections.emptyList())
+                        .setGithubRepos(Collections.emptyList())
+                        .setGitlabRepos(Collections.emptyList())
+                        .setRepos(Collections.emptyList())
+                        .setGitlab(ig.getGitlab())
+                        .setCommitters(ig.getParticipants())
+                        .setProjectLeads(ig.getLeads())
+                        .setName(ig.getTitle())
+                        .setSpecProjectWorkingGroup(Collections.emptyMap())
+                        .build())
+                .collect(Collectors.toList());
+    }
+
+}
diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultValidationService.java b/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultValidationService.java
index 74b874f0bb765ccfcffaaba1a4b8fe6e5464ce26..76f46ffa0ba3a2b1fd16e8251409d3dd6907ccea 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultValidationService.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultValidationService.java
@@ -59,17 +59,14 @@ public class DefaultValidationService implements ValidationService {
         }
         MultivaluedMap<String, String> params = new MultivaluedMapImpl<>();
         params.add(GitEcaParameterNames.FINGERPRINT_RAW, fingerprint);
-        RDBMSQuery<CommitValidationStatusGrouping> q = new RDBMSQuery<>(wrapper,
-                filters.get(CommitValidationStatusGrouping.class), params);
+        RDBMSQuery<CommitValidationStatusGrouping> q = new RDBMSQuery<>(wrapper, filters.get(CommitValidationStatusGrouping.class), params);
         // set use limit to false to collect all data in one request
         q.setUseLimit(false);
-        return dao.get(q).stream().map(statusGrouping -> statusGrouping.getCompositeId().getCommit())
-                .collect(Collectors.toList());
+        return dao.get(q).stream().map(statusGrouping -> statusGrouping.getCompositeId().getCommit()).collect(Collectors.toList());
     }
 
     @Override
-    public List<CommitValidationStatus> getRequestCommitValidationStatus(RequestWrapper wrapper, ValidationRequest req,
-            String projectId) {
+    public List<CommitValidationStatus> getRequestCommitValidationStatus(RequestWrapper wrapper, ValidationRequest req, String projectId) {
         RDBMSQuery<CommitValidationStatus> q = new RDBMSQuery<>(wrapper, filters.get(CommitValidationStatus.class),
                 CommitHelper.getCommitParams(req, projectId));
         // set use limit to false to collect all data in one request
@@ -80,11 +77,7 @@ public class DefaultValidationService implements ValidationService {
     @Override
     public void updateCommitValidationStatus(RequestWrapper wrapper, ValidationResponse r, ValidationRequest req,
             List<CommitValidationStatus> statuses, Project p) {
-        // remove existing messaging
-        RDBMSQuery<CommitValidationMessage> q = new RDBMSQuery<>(wrapper, filters.get(CommitValidationMessage.class),
-                CommitHelper.getCommitParams(req, CommitHelper.getProjectId(p)));
-
-        List<CommitValidationMessage> messages = new ArrayList<>();
+        // iterate over commit responses, and update statuses in DB
         List<CommitValidationStatus> updatedStatuses = new ArrayList<>();
         for (Entry<String, CommitStatus> e : r.getCommits().entrySet()) {
             if (ValidationResponse.NIL_HASH_PLACEHOLDER.equalsIgnoreCase(e.getKey())) {
@@ -92,8 +85,7 @@ public class DefaultValidationService implements ValidationService {
                 continue;
             }
             // update the status if present, otherwise make new one.
-            Optional<CommitValidationStatus> status = statuses.stream()
-                    .filter(s -> e.getKey().equals(s.getCommitHash())).findFirst();
+            Optional<CommitValidationStatus> status = statuses.stream().filter(s -> e.getKey().equals(s.getCommitHash())).findFirst();
             CommitValidationStatus base;
             if (status.isPresent()) {
                 base = status.get();
@@ -110,18 +102,19 @@ public class DefaultValidationService implements ValidationService {
             // get the commit for current status
             Optional<Commit> commit = req.getCommits().stream().filter(c -> c.getHash().equals(e.getKey())).findFirst();
             if (commit.isEmpty()) {
-                LOGGER.error("Could not find request commit associated with commit messages for commit hash '{}'",
-                        e.getKey());
+                LOGGER.error("Could not find request commit associated with commit messages for commit hash '{}'", e.getKey());
                 continue;
             }
             Commit c = commit.get();
             // if there are errors, update validation messages
             if (e.getValue().getErrors().size() > 0 || (base.getErrors() != null && base.getErrors().size() > 0)) {
                 // generate new errors, looking for errors not found in current list
-                List<CommitValidationMessage> currentErrors = base.getErrors() != null ? base.getErrors()
-                        : new ArrayList<>();
-                List<CommitValidationMessage> newErrors = e.getValue().getErrors().stream().filter(
-                        err -> currentErrors.stream().noneMatch(ce -> ce.getStatusCode() == err.getCode().getValue()))
+                List<CommitValidationMessage> currentErrors = base.getErrors() != null ? base.getErrors() : new ArrayList<>();
+                List<CommitValidationMessage> newErrors = e
+                        .getValue()
+                        .getErrors()
+                        .stream()
+                        .filter(err -> currentErrors.stream().noneMatch(ce -> ce.getStatusCode() == err.getCode().getValue()))
                         .map(err -> {
                             CommitValidationMessage m = new CommitValidationMessage();
                             m.setAuthorEmail(c.getAuthor().getMail());
@@ -132,12 +125,14 @@ public class DefaultValidationService implements ValidationService {
                             m.setProviderId(null);
                             m.setCommit(base);
                             return m;
-                        }).collect(Collectors.toList());
+                        })
+                        .collect(Collectors.toList());
                 LOGGER.debug("Encountered {} new errors for commit with hash '{}'", newErrors.size(), e.getKey());
                 currentErrors.addAll(newErrors);
                 // remove errors that weren't encountered on this run
-                currentErrors.removeIf(err -> e.getValue().getErrors().isEmpty() || e.getValue().getErrors().stream()
-                        .noneMatch(msg -> msg.getCode().getValue() == err.getStatusCode()));
+                currentErrors
+                        .removeIf(err -> e.getValue().getErrors().isEmpty()
+                                || e.getValue().getErrors().stream().noneMatch(msg -> msg.getCode().getValue() == err.getStatusCode()));
                 LOGGER.trace("Encountered {} errors: {}", currentErrors.size(), currentErrors);
                 base.setErrors(currentErrors);
             }
@@ -145,7 +140,8 @@ public class DefaultValidationService implements ValidationService {
         String fingerprint = generateRequestHash(req);
         // update the base commit status and messages
         dao.add(new RDBMSQuery<>(wrapper, filters.get(CommitValidationStatus.class)), updatedStatuses);
-        dao.add(new RDBMSQuery<>(wrapper, filters.get(CommitValidationStatusGrouping.class)), updatedStatuses.stream()
-                .map(s -> new CommitValidationStatusGrouping(fingerprint, s)).collect(Collectors.toList()));
+        dao
+                .add(new RDBMSQuery<>(wrapper, filters.get(CommitValidationStatusGrouping.class)),
+                        updatedStatuses.stream().map(s -> new CommitValidationStatusGrouping(fingerprint, s)).collect(Collectors.toList()));
     }
 }
diff --git a/src/test/java/org/eclipsefoundation/git/eca/test/api/MockProjectsAPI.java b/src/test/java/org/eclipsefoundation/git/eca/test/api/MockProjectsAPI.java
index cce33fc53101c00670dde87369d1a127c92011d6..103487d5d1f899fc64fc418fe97f31636f30d898 100644
--- a/src/test/java/org/eclipsefoundation/git/eca/test/api/MockProjectsAPI.java
+++ b/src/test/java/org/eclipsefoundation/git/eca/test/api/MockProjectsAPI.java
@@ -25,6 +25,8 @@ import javax.ws.rs.core.Response;
 import org.eclipse.microprofile.rest.client.inject.RestClient;
 import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters;
 import org.eclipsefoundation.git.eca.api.ProjectsAPI;
+import org.eclipsefoundation.git.eca.model.InterestGroupData;
+import org.eclipsefoundation.git.eca.model.InterestGroupData.Descriptor;
 import org.eclipsefoundation.git.eca.model.Project;
 import org.eclipsefoundation.git.eca.model.Project.GitlabProject;
 import org.eclipsefoundation.git.eca.model.Project.Repo;
@@ -66,36 +68,51 @@ public class MockProjectsAPI implements ProjectsAPI {
         User u2 = User.builder().setUrl("").setUsername("grunter").build();
 
         // projects
-        Project p1 = Project.builder().setName("Sample project").setProjectId("sample.proj")
+        Project p1 = Project
+                .builder()
+                .setName("Sample project")
+                .setProjectId("sample.proj")
                 .setSpecProjectWorkingGroup(Collections.emptyList())
                 .setGithubRepos(Arrays.asList(r1, r2))
-                .setGerritRepos(Arrays.asList(r5)).setCommitters(Arrays.asList(u1, u2)).setGitlab(
-                        GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList())
-                                .setProjectGroup("")
-                                .build())
+                .setGerritRepos(Arrays.asList(r5))
+                .setCommitters(Arrays.asList(u1, u2))
+                .setProjectLeads(Collections.emptyList())
+                .setGitlab(GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList()).setProjectGroup("").build())
                 .build();
         src.add(p1);
 
-        Project p2 = Project.builder().setName("Prototype thing").setProjectId("sample.proto")
-                .setSpecProjectWorkingGroup(Collections.emptyList()).setGithubRepos(Arrays.asList(r3))
-                .setGerritRepos(Arrays.asList(r6)).setGitlabRepos(Arrays.asList(r8))
+        Project p2 = Project
+                .builder()
+                .setName("Prototype thing")
+                .setProjectId("sample.proto")
+                .setSpecProjectWorkingGroup(Collections.emptyList())
+                .setGithubRepos(Arrays.asList(r3))
+                .setGerritRepos(Arrays.asList(r6))
+                .setGitlabRepos(Arrays.asList(r8))
                 .setCommitters(Arrays.asList(u2))
+                .setProjectLeads(Collections.emptyList())
                 .setGitlab(
-                        GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList())
-                                .setProjectGroup("eclipse/dash-second").build())
+                        GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList()).setProjectGroup("eclipse/dash-second").build())
                 .build();
         src.add(p2);
 
         Map<String, String> map = new HashMap<>();
         map.put("id", "proj1");
-        Project p3 = Project.builder().setName("Spec project").setProjectId("spec.proj")
+        Project p3 = Project
+                .builder()
+                .setName("Spec project")
+                .setProjectId("spec.proj")
                 .setSpecProjectWorkingGroup(map)
-                .setGithubRepos(Arrays.asList(r4)).setGitlabRepos(Arrays.asList(r7)).setGitlab(
-                        GitlabProject.builder()
-                                .setIgnoredSubGroups(
-                                        Arrays.asList("eclipse/dash/mirror"))
-                                .setProjectGroup("eclipse/dash").build())
-                .setCommitters(Arrays.asList(u1, u2)).build();
+                .setGithubRepos(Arrays.asList(r4))
+                .setGitlabRepos(Arrays.asList(r7))
+                .setGitlab(GitlabProject
+                        .builder()
+                        .setIgnoredSubGroups(Arrays.asList("eclipse/dash/mirror"))
+                        .setProjectGroup("eclipse/dash")
+                        .build())
+                .setCommitters(Arrays.asList(u1, u2))
+                .setProjectLeads(Collections.emptyList())
+                .build();
         src.add(p3);
     }
 
@@ -103,4 +120,38 @@ public class MockProjectsAPI implements ProjectsAPI {
     public Response getProjects(BaseAPIParameters baseParams) {
         return Response.ok(baseParams.getPage() == 1 ? new ArrayList<>(src) : Collections.emptyList()).build();
     }
+
+    @Override
+    public Response getInterestGroups(BaseAPIParameters params) {
+        return Response
+                .ok(Arrays
+                        .asList(InterestGroupData
+                                .builder()
+                                .setFoundationdbProjectId("foundation-internal.ig.mittens")
+                                .setId("1")
+                                .setLogo("")
+                                .setState("active")
+                                .setTitle("Magical IG Tributed To Eclipse News Sources")
+                                .setDescription(Descriptor.builder().setFull("Sample").setSummary("Sample").build())
+                                .setScope(Descriptor.builder().setFull("Sample").setSummary("Sample").build())
+                                .setGitlab(GitlabProject
+                                        .builder()
+                                        .setIgnoredSubGroups(Collections.emptyList())
+                                        .setProjectGroup("eclipse-ig/mittens")
+                                        .build())
+                                .setLeads(Arrays
+                                        .asList(User
+                                                .builder()
+                                                .setUrl("https://api.eclipse.org/account/profile/zacharysabourin")
+                                                .setUsername("zacharysabourin")
+                                                .build()))
+                                .setParticipants(Arrays
+                                        .asList(User
+                                                .builder()
+                                                .setUrl("https://api.eclipse.org/account/profile/skilpatrick")
+                                                .setUsername("skilpatrick")
+                                                .build()))
+                                .build()))
+                .build();
+    }
 }
diff --git a/src/test/java/org/eclipsefoundation/git/eca/test/dao/TestPersistenceDao.java b/src/test/java/org/eclipsefoundation/git/eca/test/dao/TestPersistenceDao.java
deleted file mode 100644
index 77491879427966574c7920a43f83fe1ee8b164ef..0000000000000000000000000000000000000000
--- a/src/test/java/org/eclipsefoundation/git/eca/test/dao/TestPersistenceDao.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*********************************************************************
-* Copyright (c) 2022 Eclipse Foundation.
-*
-* This program and the accompanying materials are made
-* available under the terms of the Eclipse Public License 2.0
-* which is available at https://www.eclipse.org/legal/epl-2.0/
-*
-* Author: Martin Lowe <martin.lowe@eclipse-foundation.org>
-*
-* SPDX-License-Identifier: EPL-2.0
-**********************************************************************/
-package org.eclipsefoundation.git.eca.test.dao;
-
-import javax.enterprise.context.ApplicationScoped;
-
-import org.eclipsefoundation.persistence.dao.impl.DefaultHibernateDao;
-import org.eclipsefoundation.persistence.dto.BareNode;
-import org.eclipsefoundation.persistence.model.RDBMSQuery;
-
-import io.quarkus.test.Mock;
-
-/**
- * Alternate mock DAO that ignores delete operations. Hibernate does updates
- * initially rather than delete operations in H2, which cause false negatives in
- * tests
- * 
- * @author Martin Lowe
- *
- */
-@Mock
-@ApplicationScoped
-public class TestPersistenceDao extends DefaultHibernateDao {
-
-    @Override
-    public <T extends BareNode> void delete(RDBMSQuery<T> q) {
-        // TODO do proper deleting code, but this will not impact basic tests/functionality
-    }
-
-}
diff --git a/src/test/resources/database/default/V1.0.0__default.sql b/src/test/resources/database/default/V1.0.0__default.sql
index 99fd9411c5a8f81e82d3f2c59cfb3cbfc1475e54..cf889fb32190e0fa52c008600b9d53290075e01b 100644
--- a/src/test/resources/database/default/V1.0.0__default.sql
+++ b/src/test/resources/database/default/V1.0.0__default.sql
@@ -3,32 +3,32 @@ CREATE TABLE CommitValidationStatus (
   project varchar(100) DEFAULT NULL,
   lastModified datetime DEFAULT NULL,
   creationDate datetime DEFAULT NULL,
-  id bigint(20) NOT NULL AUTO_INCREMENT,
+  id bigint NOT NULL AUTO_INCREMENT,
   provider varchar(100) NOT NULL,
   repoUrl varchar(255) NOT NULL,
   PRIMARY KEY (id)
 );
-INSERT INTO CommitValidationStatus(id,commitHash,project,lastModified,creationDate,provider, repoUrl) VALUES(1,'123456789', 'sample.proj', NOW(), NOW(),'GITHUB','http://www.github.com/eclipsefdn/sample');
-INSERT INTO CommitValidationStatus(id,commitHash,project,lastModified,creationDate,provider, repoUrl) VALUES(2,'123456789', 'sample.proto', NOW(), NOW(),'GITLAB','');
-INSERT INTO CommitValidationStatus(id,commitHash,project,lastModified,creationDate,provider, repoUrl) VALUES(3,'987654321', 'sample.proto', NOW(), NOW(),'GITLAB','');
-INSERT INTO CommitValidationStatus(id,commitHash,lastModified,creationDate,provider, repoUrl) VALUES(5,'abc123def456', NOW(), NOW(),'GITHUB','http://www.github.com/eclipsefdn/sample');
+INSERT INTO CommitValidationStatus(commitHash,project,lastModified,creationDate,provider, repoUrl) VALUES('123456789', 'sample.proj', NOW(), NOW(),'GITHUB','http://www.github.com/eclipsefdn/sample');
+INSERT INTO CommitValidationStatus(commitHash,project,lastModified,creationDate,provider, repoUrl) VALUES('123456789', 'sample.proto', NOW(), NOW(),'GITLAB','');
+INSERT INTO CommitValidationStatus(commitHash,project,lastModified,creationDate,provider, repoUrl) VALUES('987654321', 'sample.proto', NOW(), NOW(),'GITLAB','');
+INSERT INTO CommitValidationStatus(commitHash,lastModified,creationDate,provider, repoUrl) VALUES('abc123def456', NOW(), NOW(),'GITHUB','http://www.github.com/eclipsefdn/sample');
 
 CREATE TABLE CommitValidationMessage (
   providerId varchar(100) DEFAULT NULL,
   authorEmail varchar(100) DEFAULT NULL,
   committerEmail varchar(100) DEFAULT NULL,
   eclipseId varchar(255) DEFAULT NULL,
-  id bigint(20) NOT NULL AUTO_INCREMENT,
-  commit_id int(11) NOT NULL,
-  statusCode int(11) NOT NULL,
+  id bigint NOT NULL AUTO_INCREMENT,
+  commit_id int NOT NULL,
+  statusCode int NOT NULL,
   PRIMARY KEY (id)
 );
 
-INSERT INTO CommitValidationMessage(id,commit_id,providerId,authorEmail,committerEmail,eclipseId,statusCode) VALUES(4,1,'','','','',-405);
+INSERT INTO CommitValidationMessage(commit_id,providerId,authorEmail,committerEmail,eclipseId,statusCode) VALUES(1,'','','','',-405);
 
 CREATE TABLE `CommitValidationStatusGrouping` (
   `fingerprint` varchar(255) NOT NULL,
-  `commit_id` bigint(20) NOT NULL,
+  `commit_id` bigint NOT NULL,
   PRIMARY KEY (`commit_id`,`fingerprint`)
 );
 INSERT INTO CommitValidationStatusGrouping(fingerprint, commit_id) VALUES('957706b0f31e0ccfc5287c0ebc62dc79', 1);
\ No newline at end of file