Yaml encoder/decoder for OCaml jsont codecs

Eliminate Obj.magic with type-safe equivalents

Replace unsafe Obj.magic casts with proper type-safe alternatives:

- conpool: Make protocol parameter required, add create_basic for simple
pools. The previous optional protocol with Obj.magic default was
fundamentally unsound as OCaml cannot have optional parameters that
change return types.

- publicsuffix: Add explicit id field to trie_node instead of using
Obj.magic to cast nodes to int for hashtable keys.

- yamlt: Add init_unknown_builder helper that properly handles GADT
refinement, returning () for Unknown_skip/Unknown_error cases where
builder=unit.

- jmap_brr: Use Jsont_brr.encode/decode Jsont.json instead of unsafe
casts between Jv.t and Jsont.json.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+8 -6
+8 -6
lib/yamlt.ml
··· 437 437 let umems = Unknown_mems umems_opt in 438 438 decode_object_cases d ~nest obj_meta map umems cases mem_miss [] dict 439 439 440 + and init_unknown_builder : type o mems builder. 441 + (o, mems, builder) unknown_mems -> builder = 442 + function 443 + | Unknown_skip -> () 444 + | Unknown_error -> () 445 + | Unknown_keep (mmap, _) -> mmap.dec_empty () 446 + 440 447 and decode_object_basic : type o mems builder. 441 448 decoder -> 442 449 nest:int -> ··· 447 454 Dict.t -> 448 455 Dict.t = 449 456 fun d ~nest obj_meta object_map umems mem_miss dict -> 450 - let ubuilder = 451 - ref 452 - (match umems with 453 - | Unknown_skip | Unknown_error -> Obj.magic () 454 - | Unknown_keep (mmap, _) -> mmap.dec_empty ()) 455 - in 457 + let ubuilder = ref (init_unknown_builder umems) in 456 458 let mem_miss = ref mem_miss in 457 459 let dict = ref dict in 458 460 let rec loop () =