@@ -443,6 +443,53 @@ describe('sheafify', () => {
443443 expect ( liftCalled ) . toBe ( false ) ;
444444 } ) ;
445445
446+ it ( 'extracts shared NaN metadata values into constraints' , async ( ) => {
447+ type Meta = { cost : number ; priority : number } ;
448+ let capturedGerms : EvaluatedSection < Partial < Meta > > [ ] = [ ] ;
449+ let capturedContext : LiftContext < Meta > | undefined ;
450+
451+ const sections : PresheafSection < Meta > [ ] = [
452+ {
453+ exo : makeSection (
454+ 'Wallet:0' ,
455+ M . interface ( 'Wallet:0' , {
456+ getBalance : M . call ( M . string ( ) ) . returns ( M . number ( ) ) ,
457+ } ) ,
458+ { getBalance : ( _acct : string ) => 0 } ,
459+ ) ,
460+ metadata : constant ( { cost : NaN , priority : 0 } ) ,
461+ } ,
462+ {
463+ exo : makeSection (
464+ 'Wallet:1' ,
465+ M . interface ( 'Wallet:1' , {
466+ getBalance : M . call ( M . string ( ) ) . returns ( M . number ( ) ) ,
467+ } ) ,
468+ { getBalance : ( _acct : string ) => 0 } ,
469+ ) ,
470+ metadata : constant ( { cost : NaN , priority : 1 } ) ,
471+ } ,
472+ ] ;
473+
474+ const wallet = sheafify ( { name : 'Wallet' , sections } ) . getGlobalSection ( {
475+ async * lift ( germs , context ) {
476+ capturedGerms = germs ;
477+ capturedContext = context ;
478+ yield germs [ 0 ] ! ;
479+ } ,
480+ } ) ;
481+
482+ await E ( wallet ) . getBalance ( 'alice' ) ;
483+
484+ // NaN is shared across all germs, so it should be extracted as a constraint
485+ // — not left as distinguishing metadata in each germ's options.
486+ expect ( Number . isNaN ( capturedContext ?. constraints . cost ) ) . toBe ( true ) ;
487+ expect ( capturedGerms . map ( ( germ ) => germ . metadata ) ) . toStrictEqual ( [
488+ { priority : 0 } ,
489+ { priority : 1 } ,
490+ ] ) ;
491+ } ) ;
492+
446493 it ( 'does not collapse Infinity and null metadata as equivalent' , async ( ) => {
447494 type Meta = { cost : number | null } ;
448495 let germCount = 0 ;
0 commit comments