Figured it out. The problem was my input data, not the actual dual contouring code. I was passing density values into each leaf node, rather than grid signs for the corners. I should have followed the reference in the notes linking to the documentation for PolyMender, which says this:
is a 4-bytes integer that equals 2 ^ octree_depth. The first
byte of a is either 0 (denoting an intermediate node) or 1
(denoting an empty node) or 2 (denoting a leaf node). After the first
byte, an intermediate node contains eight structures for
its eight children; an empty node contains one byte of value 0
or 1 denoting if it is inside or outside; and a leaf node contains
one byte whose eight bits correspond to the signs at its eight corners
(0 for inside and 1 for outside). The order of enumeration of the
eight children nodes in an intermediate nodeis the following
(expressed in coordinates ):
<0,0,0>,<0,0,1>,<0,1,0>,<0,1,1>,<1,0,0>,<1,0,1>,<1,1,0>,<1,1,1>. The
enumeration of the eight corners in a leaf node follows the same order
(e.g., the lowest bit records the sign at <0,0,0>).