BRepAlgoAPI_Common between custom solid and box loses triangles

A bit of context

I am trying to do a common operation between a solid that I constructed from a list of triangles and a box. The solid represents a staircase. It is generated in another app, meaning I only have access to its list of triangles. The following c++ code generates the staircase as an OCCT solid from its list of triangles :

const CsgNodeMsg_CsgPrimitiveMsg_CsgMeshMsg &meshMsg = csgNodeTypeData.mesh();
    const GeometryMsg &geometry = meshMsg.geometry();

    auto convertPointFromMessage = [](const Vector3fMsg &v) -> gp_Pnt { return gp_Pnt(v.x(), v.y(), v.z()); };
    auto convertVectorFromMessage = [](const Vector3fMsg &v) -> gp_Vec { return gp_Vec(v.x(), v.y(), v.z()); };

    // Checks if the face (triangle) defined by the vertices p1, p2, p3 is reversed given its normal
    auto isReverse = [](const gp_Vec &normal, const gp_Pnt &p1, const gp_Pnt &p2, const gp_Pnt &p3) -> bool
    {
        return gp_Vec(p1, p2).Crossed(gp_Vec(p1, p3)).Dot(normal) < 0;
    };

    constexpr BRep_Builder shellBuilder;
    TopoDS_Shell shell;
    shellBuilder.MakeShell(shell);

    for (const Face3Msg &triangle: geometry.triangles())
    {
        // Create edges for the triangle
        gp_Pnt p1 = convertPointFromMessage(geometry.vertices(triangle.a()));
        gp_Pnt p2 = convertPointFromMessage(geometry.vertices(triangle.b()));
        gp_Pnt p3 = convertPointFromMessage(geometry.vertices(triangle.c()));

        // If face is reversed, swap vertices
        if (isReverse(convertVectorFromMessage(triangle.normal()), p1, p2, p3)) std::swap(p1, p3);

        // Create a polygon with the vertices and create a face from it
        TopoDS_Face face = BRepBuilderAPI_MakeFace(BRepBuilderAPI_MakePolygon(p1, p2, p3, Standard_True), Standard_True);

        shellBuilder.Add(shell, face);
    }

    outShape = BRepBuilderAPI_MakeSolid(shell).Shape();
    ApplyTransform(outShape, transformMsg);

I am suspecting the construction of the solid to be erroneous somehow. This is why I uploaded it.

The box is created with a classic BRepPrimAPI_MakeBox(). It is exactly the size of the staircase. The goal is then to to a common operation (using the BRepAlgoAPI_Common()) to trim the staircase, making it perfectly straight on the sides. The common operation is implemented as such:

    // left is the staircase and right is the box
    BRepAlgoAPI_Common commonFunction = BRepAlgoAPI_Common(left, right);
    commonFunction.SetFuzzyValue(0.0005);
    commonFunction.Build();
    outShape = commonFunction.Shape();

 The expected result

Using another rendering engine, I am able to get the expected result, where the staircase is trimmed perfectly. It does not used OCCT at all in this case. See the 'expected_staircase.png' image.

The actual result

The returned staircase is missing a lot of triangles. It's like the faces cut during the common operation weren't replaced after the operation. See the 'actual_staircase.png' image. I also tried to translate the box for the sake of the tests, it actually makes it worse. See the 'actual_staircase_translation.png'.

This post mentioned the fuzzy value parameter, I tried using it in the code shown above but it doesn't affect the result at all. Maybe I am using it wrong?

Feel free to ask questions if something is missing

Edit

I tried to use the BRepCheck_Analyzer() object on the generated solid from the list of triangles. The IsValid() methods returns false. The documentation specifies what the method checks, but I don't see any way to see which check failed.