> json_extract returns native types. json_extract(data, '$.id') returns an integer if the value was stored as a number. Comparing it to a string silently fails. Always CAST(json_extract(...) AS TEXT) when you need string comparison.
More simply:
sqlite> select typeof('{a:1}'->>'a') ;
╭──────────────────────╮
│ typeof('{a:1}'->>... │
╞══════════════════════╡
│ integer │
╰──────────────────────╯
vs: sqlite> select typeof('{a:1}'->'a') ;
╭──────────────────────╮
│ typeof('{a:1}'->'a') │
╞══════════════════════╡
│ text │
╰──────────────────────╯