diff a/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBot.java b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBot.java
--- a/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBot.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.skara.bots.bridgekeeper;
-
-import org.openjdk.skara.bot.*;
-import org.openjdk.skara.forge.*;
-
-import java.nio.file.Path;
-import java.util.*;
-import java.util.function.Consumer;
-import java.util.logging.Logger;
-
-class BridgekeeperWorkItem implements WorkItem {
-    private final Logger log = Logger.getLogger("org.openjdk.skara.bots");;
-    private final HostedRepository repository;
-    private final PullRequest pr;
-    private final Consumer<RuntimeException> errorHandler;
-
-    BridgekeeperWorkItem(HostedRepository repository, PullRequest pr, Consumer<RuntimeException> errorHandler) {
-        this.pr = pr;
-        this.repository = repository;
-        this.errorHandler = errorHandler;
-    }
-
-    private final String welcomeMarker = "<!-- BridgeKeeperBot welcome message -->";
-
-    private void checkWelcomeMessage() {
-        log.info("Checking welcome message of " + pr);
-
-        var comments = pr.comments();
-        var welcomePosted = comments.stream()
-                                    .anyMatch(comment -> comment.body().contains(welcomeMarker));
-
-        if (!welcomePosted) {
-            var message = "Welcome to the OpenJDK organization on GitHub!\n\n" +
-                    "This repository is currently a read-only git mirror of the official Mercurial " +
-                    "repository (located at https://hg.openjdk.java.net/). As such, we are not " +
-                    "currently accepting pull requests here. If you would like to contribute to " +
-                    "the OpenJDK project, please see http://openjdk.java.net/contribute/ on how " +
-                    "to proceed.\n\n" +
-                    "This pull request will be automatically closed.";
-
-            log.fine("Posting welcome message");
-            pr.addComment(welcomeMarker + "\n\n" + message);
-        }
-        pr.setState(PullRequest.State.CLOSED);
-    }
-
-
-    @Override
-    public boolean concurrentWith(WorkItem other) {
-        if (!(other instanceof BridgekeeperWorkItem)) {
-            return true;
-        }
-        BridgekeeperWorkItem otherItem = (BridgekeeperWorkItem)other;
-        if (!pr.id().equals(otherItem.pr.id())) {
-            return true;
-        }
-        if (!repository.name().equals(otherItem.repository.name())) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void run(Path scratchPath) {
-        checkWelcomeMessage();
-    }
-
-    @Override
-    public void handleRuntimeException(RuntimeException e) {
-        errorHandler.accept(e);
-    }
-}
-
-public class BridgekeeperBot implements Bot {
-    private final HostedRepository remoteRepo;
-    private final PullRequestUpdateCache updateCache;
-
-    BridgekeeperBot(HostedRepository repo) {
-        this.remoteRepo = repo;
-        this.updateCache = new PullRequestUpdateCache();
-    }
-
-    @Override
-    public List<WorkItem> getPeriodicItems() {
-        List<WorkItem> ret = new LinkedList<>();
-
-        for (var pr : remoteRepo.pullRequests()) {
-            if (updateCache.needsUpdate(pr)) {
-                var item = new BridgekeeperWorkItem(remoteRepo, pr, e -> updateCache.invalidate(pr));
-                ret.add(item);
-            }
-        }
-
-        return ret;
-    }
-}
diff a/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotFactory.java b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotFactory.java
--- a/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotFactory.java
+++ b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotFactory.java
@@ -22,10 +22,11 @@
  */
 package org.openjdk.skara.bots.bridgekeeper;
 
 import org.openjdk.skara.bot.*;
 
+import java.time.Duration;
 import java.util.*;
 
 public class BridgekeeperBotFactory implements BotFactory {
     @Override
     public String name() {
@@ -35,13 +36,17 @@
     @Override
     public List<Bot> create(BotConfiguration configuration) {
         var ret = new ArrayList<Bot>();
         var specific = configuration.specific();
 
-        for (var repo : specific.get("repositories").asArray()) {
-            var bot = new BridgekeeperBot(configuration.repository(repo.asString()));
+        for (var repo : specific.get("mirrors").asArray()) {
+            var bot = new PullRequestCloserBot(configuration.repository(repo.asString()));
+            ret.add(bot);
+        }
+        for (var repo : specific.get("pruned").fields()) {
+            var maxAge = Duration.parse(repo.value().get("maxage").asString());
+            var bot = new PullRequestPrunerBot(configuration.repository(repo.name()), maxAge);
             ret.add(bot);
         }
-
         return ret;
     }
 }
diff a/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/PullRequestCloserBot.java b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/PullRequestCloserBot.java
--- /dev/null
+++ b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/PullRequestCloserBot.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.skara.bots.bridgekeeper;
+
+import org.openjdk.skara.bot.*;
+import org.openjdk.skara.forge.*;
+
+import java.nio.file.Path;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.logging.Logger;
+
+class PullRequestCloserBotWorkItem implements WorkItem {
+    private final Logger log = Logger.getLogger("org.openjdk.skara.bots");;
+    private final HostedRepository repository;
+    private final PullRequest pr;
+    private final Consumer<RuntimeException> errorHandler;
+
+    PullRequestCloserBotWorkItem(HostedRepository repository, PullRequest pr, Consumer<RuntimeException> errorHandler) {
+        this.pr = pr;
+        this.repository = repository;
+        this.errorHandler = errorHandler;
+    }
+
+    private final String welcomeMarker = "<!-- PullrequestCloserBot welcome message -->";
+
+    private void checkWelcomeMessage() {
+        log.info("Checking welcome message of " + pr);
+
+        var comments = pr.comments();
+        var welcomePosted = comments.stream()
+                                    .anyMatch(comment -> comment.body().contains(welcomeMarker));
+
+        if (!welcomePosted) {
+            var message = "Welcome to the OpenJDK organization on GitHub!\n\n" +
+                    "This repository is currently a read-only git mirror of the official Mercurial " +
+                    "repository (located at https://hg.openjdk.java.net/). As such, we are not " +
+                    "currently accepting pull requests here. If you would like to contribute to " +
+                    "the OpenJDK project, please see http://openjdk.java.net/contribute/ on how " +
+                    "to proceed.\n\n" +
+                    "This pull request will be automatically closed.";
+
+            log.fine("Posting welcome message");
+            pr.addComment(welcomeMarker + "\n\n" + message);
+        }
+        pr.setState(PullRequest.State.CLOSED);
+    }
+
+
+    @Override
+    public boolean concurrentWith(WorkItem other) {
+        if (!(other instanceof PullRequestCloserBotWorkItem)) {
+            return true;
+        }
+        PullRequestCloserBotWorkItem otherItem = (PullRequestCloserBotWorkItem)other;
+        if (!pr.id().equals(otherItem.pr.id())) {
+            return true;
+        }
+        if (!repository.name().equals(otherItem.repository.name())) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void run(Path scratchPath) {
+        checkWelcomeMessage();
+    }
+
+    @Override
+    public void handleRuntimeException(RuntimeException e) {
+        errorHandler.accept(e);
+    }
+}
+
+public class PullRequestCloserBot implements Bot {
+    private final HostedRepository remoteRepo;
+    private final PullRequestUpdateCache updateCache;
+
+    PullRequestCloserBot(HostedRepository repo) {
+        this.remoteRepo = repo;
+        this.updateCache = new PullRequestUpdateCache();
+    }
+
+    @Override
+    public List<WorkItem> getPeriodicItems() {
+        List<WorkItem> ret = new LinkedList<>();
+
+        for (var pr : remoteRepo.pullRequests()) {
+            if (updateCache.needsUpdate(pr)) {
+                var item = new PullRequestCloserBotWorkItem(remoteRepo, pr, e -> updateCache.invalidate(pr));
+                ret.add(item);
+            }
+        }
+
+        return ret;
+    }
+}
diff a/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/PullRequestPrunerBot.java b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/PullRequestPrunerBot.java
--- /dev/null
+++ b/bots/bridgekeeper/src/main/java/org/openjdk/skara/bots/bridgekeeper/PullRequestPrunerBot.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.skara.bots.bridgekeeper;
+
+import org.openjdk.skara.bot.*;
+import org.openjdk.skara.forge.*;
+
+import java.nio.file.Path;
+import java.time.*;
+import java.util.*;
+import java.util.logging.Logger;
+
+class PullRequestPrunerBotWorkItem implements WorkItem {
+    private final Logger log = Logger.getLogger("org.openjdk.skara.bots");;
+    private final HostedRepository repository;
+    private final PullRequest pr;
+    private final Duration maxAge;
+
+    PullRequestPrunerBotWorkItem(HostedRepository repository, PullRequest pr, Duration maxAge) {
+        this.pr = pr;
+        this.repository = repository;
+        this.maxAge = maxAge;
+    }
+
+    @Override
+    public boolean concurrentWith(WorkItem other) {
+        if (!(other instanceof PullRequestPrunerBotWorkItem)) {
+            return true;
+        }
+        PullRequestPrunerBotWorkItem otherItem = (PullRequestPrunerBotWorkItem) other;
+        if (!pr.id().equals(otherItem.pr.id())) {
+            return true;
+        }
+        if (!repository.name().equals(otherItem.repository.name())) {
+            return true;
+        }
+        return false;
+    }
+
+    // Prune durations are on the order of days and weeks
+    private String formatDuration(Duration duration) {
+        var count = duration.toDays();
+        var unit = "day";
+
+        if (count > 14) {
+            count /= 7;
+            unit = "week";
+        }
+        if (count != 1) {
+            unit += "s";
+        }
+        return count + " " + unit;
+    }
+
+    @Override
+    public void run(Path scratchPath) {
+        var message = "@" + pr.author().userName() + " This pull request has been inactive for more than " +
+                formatDuration(maxAge) + " and will be automatically closed. If you think this is incorrect, " +
+                "feel free to reopen it!";
+
+        log.fine("Posting prune message");
+        pr.addComment(message);
+
+        pr.setState(PullRequest.State.CLOSED);
+    }
+}
+
+public class PullRequestPrunerBot implements Bot {
+    private final HostedRepository repository;
+    private final Duration maxAge;
+
+    PullRequestPrunerBot(HostedRepository repository, Duration maxAge) {
+        this.repository = repository;
+        this.maxAge = maxAge;
+    }
+
+    @Override
+    public List<WorkItem> getPeriodicItems() {
+        List<WorkItem> ret = new LinkedList<>();
+        var oldestAllowed = ZonedDateTime.now().minus(maxAge);
+
+        for (var pr : repository.pullRequests()) {
+            if (pr.updatedAt().isBefore(oldestAllowed)) {
+                var item = new PullRequestPrunerBotWorkItem(repository, pr, maxAge);
+                ret.add(item);
+            }
+        }
+
+        return ret;
+    }
+}
diff a/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotTests.java b/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotTests.java
--- a/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/BridgekeeperBotTests.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.skara.bots.bridgekeeper;
-
-import org.openjdk.skara.issuetracker.Issue;
-import org.openjdk.skara.test.*;
-
-import org.junit.jupiter.api.*;
-
-import java.io.IOException;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-class BridgekeeperBotTests {
-    @Test
-    void simple(TestInfo testInfo) throws IOException {
-        try (var credentials = new HostCredentials(testInfo);
-             var tempFolder = new TemporaryDirectory()) {
-            var author = credentials.getHostedRepository();
-            var bot = new BridgekeeperBot(author);
-
-            // Populate the projects repository
-            var localRepo = CheckableRepository.init(tempFolder.path(), author.repositoryType());
-            var masterHash = localRepo.resolve("master").orElseThrow();
-            localRepo.push(masterHash, author.url(), "master", true);
-
-            // Make a change with a corresponding PR
-            var editHash = CheckableRepository.appendAndCommit(localRepo);
-            localRepo.push(editHash, author.url(), "edit", true);
-            var pr = credentials.createPullRequest(author, "master", "edit", "This is a pull request");
-
-            // Let the bot see it
-            TestBotRunner.runPeriodicItems(bot);
-
-            // There should now be no open PRs
-            var prs = author.pullRequests();
-            assertEquals(0, prs.size());
-        }
-    }
-
-    @Test
-    void keepClosing(TestInfo testInfo) throws IOException {
-        try (var credentials = new HostCredentials(testInfo);
-             var tempFolder = new TemporaryDirectory()) {
-            var author = credentials.getHostedRepository();
-            var bot = new BridgekeeperBot(author);
-
-            // Populate the projects repository
-            var localRepo = CheckableRepository.init(tempFolder.path(), author.repositoryType());
-            var masterHash = localRepo.resolve("master").orElseThrow();
-            localRepo.push(masterHash, author.url(), "master", true);
-
-            // Make a change with a corresponding PR
-            var editHash = CheckableRepository.appendAndCommit(localRepo);
-            localRepo.push(editHash, author.url(), "edit", true);
-            var pr = credentials.createPullRequest(author, "master", "edit", "This is a pull request");
-
-            // Let the bot see it
-            TestBotRunner.runPeriodicItems(bot);
-
-            // There should now be no open PRs
-            var prs = author.pullRequests();
-            assertEquals(0, prs.size());
-
-            // The author is persistent
-            pr.setState(Issue.State.OPEN);
-            prs = author.pullRequests();
-            assertEquals(1, prs.size());
-
-            // But so is the bot
-            TestBotRunner.runPeriodicItems(bot);
-            prs = author.pullRequests();
-            assertEquals(0, prs.size());
-
-            // There should still only be one welcome comment
-            assertEquals(1, pr.comments().size());
-        }
-    }
-}
diff a/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/PullRequestCloserBotTests.java b/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/PullRequestCloserBotTests.java
--- /dev/null
+++ b/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/PullRequestCloserBotTests.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.skara.bots.bridgekeeper;
+
+import org.openjdk.skara.issuetracker.Issue;
+import org.openjdk.skara.test.*;
+
+import org.junit.jupiter.api.*;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class PullRequestCloserBotTests {
+    @Test
+    void simple(TestInfo testInfo) throws IOException {
+        try (var credentials = new HostCredentials(testInfo);
+             var tempFolder = new TemporaryDirectory()) {
+            var author = credentials.getHostedRepository();
+            var bot = new PullRequestCloserBot(author);
+
+            // Populate the projects repository
+            var localRepo = CheckableRepository.init(tempFolder.path(), author.repositoryType());
+            var masterHash = localRepo.resolve("master").orElseThrow();
+            localRepo.push(masterHash, author.url(), "master", true);
+
+            // Make a change with a corresponding PR
+            var editHash = CheckableRepository.appendAndCommit(localRepo);
+            localRepo.push(editHash, author.url(), "edit", true);
+            var pr = credentials.createPullRequest(author, "master", "edit", "This is a pull request");
+
+            // Let the bot see it
+            TestBotRunner.runPeriodicItems(bot);
+
+            // There should now be no open PRs
+            var prs = author.pullRequests();
+            assertEquals(0, prs.size());
+        }
+    }
+
+    @Test
+    void keepClosing(TestInfo testInfo) throws IOException {
+        try (var credentials = new HostCredentials(testInfo);
+             var tempFolder = new TemporaryDirectory()) {
+            var author = credentials.getHostedRepository();
+            var bot = new PullRequestCloserBot(author);
+
+            // Populate the projects repository
+            var localRepo = CheckableRepository.init(tempFolder.path(), author.repositoryType());
+            var masterHash = localRepo.resolve("master").orElseThrow();
+            localRepo.push(masterHash, author.url(), "master", true);
+
+            // Make a change with a corresponding PR
+            var editHash = CheckableRepository.appendAndCommit(localRepo);
+            localRepo.push(editHash, author.url(), "edit", true);
+            var pr = credentials.createPullRequest(author, "master", "edit", "This is a pull request");
+
+            // Let the bot see it
+            TestBotRunner.runPeriodicItems(bot);
+
+            // There should now be no open PRs
+            var prs = author.pullRequests();
+            assertEquals(0, prs.size());
+
+            // The author is persistent
+            pr.setState(Issue.State.OPEN);
+            prs = author.pullRequests();
+            assertEquals(1, prs.size());
+
+            // But so is the bot
+            TestBotRunner.runPeriodicItems(bot);
+            prs = author.pullRequests();
+            assertEquals(0, prs.size());
+
+            // There should still only be one welcome comment
+            assertEquals(1, pr.comments().size());
+        }
+    }
+}
diff a/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/PullRequestPrunerBotTests.java b/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/PullRequestPrunerBotTests.java
--- /dev/null
+++ b/bots/bridgekeeper/src/test/java/org/openjdk/skara/bots/bridgekeeper/PullRequestPrunerBotTests.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.skara.bots.bridgekeeper;
+
+import org.openjdk.skara.test.*;
+
+import org.junit.jupiter.api.*;
+
+import java.io.IOException;
+import java.time.Duration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class PullRequestPrunerBotTests {
+    @Test
+    void close(TestInfo testInfo) throws IOException {
+        try (var credentials = new HostCredentials(testInfo);
+             var tempFolder = new TemporaryDirectory()) {
+            var author = credentials.getHostedRepository();
+            var bot = new PullRequestPrunerBot(author, Duration.ofMillis(1));
+
+            // Populate the projects repository
+            var localRepo = CheckableRepository.init(tempFolder.path(), author.repositoryType());
+            var masterHash = localRepo.resolve("master").orElseThrow();
+            localRepo.push(masterHash, author.url(), "master", true);
+
+            // Make a change with a corresponding PR
+            var editHash = CheckableRepository.appendAndCommit(localRepo);
+            localRepo.push(editHash, author.url(), "edit", true);
+            var pr = credentials.createPullRequest(author, "master", "edit", "This is a pull request");
+
+            // Let the bot see it
+            TestBotRunner.runPeriodicItems(bot);
+
+            // There should now be no open PRs
+            var prs = author.pullRequests();
+            assertEquals(0, prs.size());
+        }
+    }
+
+    @Test
+    void dontClose(TestInfo testInfo) throws IOException {
+        try (var credentials = new HostCredentials(testInfo);
+             var tempFolder = new TemporaryDirectory()) {
+            var author = credentials.getHostedRepository();
+            var bot = new PullRequestPrunerBot(author, Duration.ofDays(3));
+
+            // Populate the projects repository
+            var localRepo = CheckableRepository.init(tempFolder.path(), author.repositoryType());
+            var masterHash = localRepo.resolve("master").orElseThrow();
+            localRepo.push(masterHash, author.url(), "master", true);
+
+            // Make a change with a corresponding PR
+            var editHash = CheckableRepository.appendAndCommit(localRepo);
+            localRepo.push(editHash, author.url(), "edit", true);
+            var pr = credentials.createPullRequest(author, "master", "edit", "This is a pull request");
+
+            // Let the bot see it
+            TestBotRunner.runPeriodicItems(bot);
+
+            // There should still be an open PR
+            var prs = author.pullRequests();
+            assertEquals(1, prs.size());
+        }
+    }
+}
