Implementing the Newton Method per hand

I know you’ve already gone through all this work, but why not just use the inbuilt NewtonSolver (or PETScSNESSolver) and attach the nullspace to the matrices using petsc4py?

See, for example, here. You can attach the nullspaces at the CustomSolver.solver_setup() stage.