diff --git a/extern/polymesh b/extern/polymesh
index 1d149fb8aaa0f06ca1256faffb9dea5268eaf1d5..9c176da4bd277934e58379506ce8cb01777a71ec 160000
--- a/extern/polymesh
+++ b/extern/polymesh
@@ -1 +1 @@
-Subproject commit 1d149fb8aaa0f06ca1256faffb9dea5268eaf1d5
+Subproject commit 9c176da4bd277934e58379506ce8cb01777a71ec
diff --git a/tests/algorithms/decimation.cc b/tests/algorithms/decimation.cc
new file mode 100644
index 0000000000000000000000000000000000000000..11fc0d967df036a8ad8e15aa632a391c20fd4a18
--- /dev/null
+++ b/tests/algorithms/decimation.cc
@@ -0,0 +1,36 @@
+#include <doctest.hh>
+
+#include <polymesh/Mesh.hh>
+#include <polymesh/algorithms/decimate.hh>
+#include <polymesh/algorithms/triangulate.hh>
+#include <polymesh/objects/cube.hh>
+
+#include <typed-geometry/tg.hh>
+
+#include <glow-extras/viewer/view.hh>
+
+TEST_CASE("decimate")
+{
+    pm::Mesh m;
+    auto pos = m.vertices().make_attribute<tg::pos3>();
+    pm::objects::add_cube(m, pos);
+    pm::triangulate_naive(m);
+    m.compactify();
+
+    auto fnormals = pm::triangle_normals(pos);
+    auto errors = m.vertices().map([&](pm::vertex_handle v) {
+        auto p = pos[v];
+        return v.faces().avg([&](pm::face_handle f) {
+            auto n = fnormals[f];
+            return tg::probabilistic_plane_quadric(p, n, 0.05f, 0.05f);
+        });
+    });
+
+    pm::decimate_config<tg::pos3, tg::quadric3> cfg;
+    cfg.max_error = 0.2f;
+    cfg.max_normal_dev = 0.05f;
+    pm::decimate(m, pos, errors, cfg);
+
+    auto v = view(pos);
+    view(lines(pos).line_width_world(0.01f));
+}
diff --git a/tests/algorithms/topo-fuzzer.cc b/tests/algorithms/topo-fuzzer.cc
index ec5dd179c157eec86943d63dafd2a69f991c9c8d..2580e75cc85adaf2f50821697df1886fd00bbcb7 100644
--- a/tests/algorithms/topo-fuzzer.cc
+++ b/tests/algorithms/topo-fuzzer.cc
@@ -15,8 +15,6 @@
 
 TEST_CASE("topo fuzzer")
 {
-    // return; // fails currently
-
     for (auto _ = 0; _ < 20; ++_)
     {
         tg::rng rng;