NULL is always an awkward thing to deal with - how you want to handle it depends on the specific thing you're trying to accomplish. I'd probably prefer it if NULL equaled NULL when dealing with where conditions but it actually makes join evaluations a lot cleaner - if NULL equaled NULL then joining on columns with nulls would get really weird.
At the end of the day IS NULL and IS DISTINCT FROM/IS NOT DISTINCT FROM exist so you can handle cases where it'd be weird.
unfortunately they were not invented at the time sql was created
The problem is that id = id is fundamentally incorrect for a nullable column. You should have done id is not null and id = id. And you shouldn’t have been allowed to do the first anyways, because nothing good can come of it (there is no sane semantics to stuffing a trinary logic into a boolean algebra, and SQL chooses one of the many insane options, leading to both false positive and false negative matches depending.) the only correct answer is not to do that.
It's true that you have to adopt a completely different language, but when that language saves you from potentially expensive bugs, it becomes appealing.
I think it handles all the 3VL problems I've encountered in SQL, but that doesn't mean it handles all possible 3VL problems. It also might not make any sense to anyone except me.
Also, this is an aside, but is your thing named after Snake Plissken?