{"version":3,"sources":["../registry/kind-storage-transform.ts","../core/kind-schema.types.ts","../core/fingerprint.ts","../core/ir-types.ts","../core/normalize.ts","../registry/kind-dual-gate.ts","../registry/kind-validator.ts","../registry/kind-dispositions.generated.ts"],"names":["Ajv"],"mappings":";;;;;;;;;AAiDO,IAAM,iBAAA,GAAoB;AA6D1B,IAAM,gBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,EAC1C,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AACF;AAMA,IAAM,QAAA,GAAW,GAAA;AAEjB,SAAS,KAAK,KAAA,EAAwD;AAGpE,EAAA,MAAM,GAAA,GAMF;AAAA,IACF,IAAA,EAAM;AAAA,GACR;AACA,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,GAAA,CAAI,QAAA,GAAW,IAAA;AACnC,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,GAAA,CAAI,QAAA,GAAW,IAAA;AACnC,EAAA,IAAI,KAAA,CAAM,WAAA,KAAgB,MAAA,EAAW,GAAA,CAAI,cAAc,KAAA,CAAM,WAAA;AAE7D,EAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,GAAA,CAAI,UAAU,KAAA,CAAM,OAAA;AACrD,EAAA,OAAO,GAAA;AACT;AAMA,SAAS,UAAA,CACP,IAAA,EACA,KAAA,EACA,IAAA,EACA,KAAA,EACoB;AACpB,EAAA,MAAM,IAAI,EAAE,GAAG,IAAA,CAAK,KAAK,GAAG,IAAA,EAAK;AAEjC,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,UAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,MAAA;AAAA,IACL,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,MAAM,IAAA,EAAK;AAAA,IAElC,KAAK,QAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,IAAA,EAAM,QAAA;AAAA,QACN,GAAI,MAAM,GAAA,KAAQ,MAAA,GAAY,EAAE,GAAA,EAAK,KAAA,CAAM,GAAA,EAAI,GAAI,EAAC;AAAA,QACpD,GAAI,MAAM,GAAA,KAAQ,MAAA,GAAY,EAAE,GAAA,EAAK,KAAA,CAAM,GAAA,EAAI,GAAI,EAAC;AAAA,QACpD,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,KAAA,CAAM,IAAA,EAAK,GAAI;AAAC,OACzD;AAAA,IAEF,KAAK,UAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,IAAA,EAAM,UAAA;AAAA,QACN,GAAI,KAAA,CAAM,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,CAAC,GAAG,KAAA,CAAM,MAAM,CAAA,EAAE,GAAI,EAAC;AAAA,QAClE,GAAI,KAAA,CAAM,IAAA,GAAO,EAAE,IAAA,EAAM,IAAA,KAAS;AAAC,OACrC;AAAA,IAEF,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,MAAM,QAAA,EAAU,MAAA,EAAQ,MAAM,MAAA,EAAO;AAAA,IAEtD,KAAK,MAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,IAAA,EAAM,MAAA;AAAA,QACN,MAAA,EAAQ,CAAC,GAAG,KAAA,CAAM,MAAM,CAAA;AAAA,QACxB,GAAI,KAAA,CAAM,IAAA,GAAO,EAAE,IAAA,EAAM,IAAA,KAAS;AAAC,OACrC;AAAA,IAEF,KAAK,OAAA,EAAS;AAIZ,MAAA,IAAI,KAAA,CAAM,KAAA,IAAS,KAAA,CAAM,KAAA,CAAM,SAAS,CAAA,EAAG;AACzC,QAAA,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,SAAA,EAAW,QAAA,KAAa;AAC3C,UAAA,KAAA,CAAM,KAAK,EAAE,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,UAAU,CAAA;AAAA,QACrD,CAAC,CAAA;AACD,QAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,CAAC,GAAG,KAAA,CAAM,OAAO,CAAA,EAAG,QAAA,EAAU,IAAA,EAAK;AAAA,MAC5E;AACA,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAS,SAAS,CAAC,GAAG,KAAA,CAAM,OAAO,CAAA,EAAE;AAAA,IAC5D;AAAA,IAEA,KAAK,QAAA;AAEH,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,SAAA,EAAW,IAAA,EAAM,WAAW,KAAA,CAAM,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAA;AACrE,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,QAAA,EAAS;AAAA,IAEhC,KAAK,OAAA;AAEH,MAAA,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,CAAC,SAAA,EAAW,QAAA,KAAa;AAC/C,QAAA,KAAA,CAAM,KAAK,EAAE,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,UAAU,CAAA;AAAA,MACrD,CAAC,CAAA;AACD,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAQ;AAAA,IAE/B,KAAK,eAAA,EAAiB;AAGpB,MAAA,MAAM,SAA+B,EAAC;AACtC,MAAA,KAAA,MAAW,CAAC,WAAW,UAAU,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA,EAAG;AAClE,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,UAAA;AAAA,YACE,SAAA;AAAA,YACA,UAAA;AAAA,YACA,CAAA,EAAG,IAAI,CAAA,EAAG,QAAQ,GAAG,SAAS,CAAA,CAAA;AAAA,YAC9B;AAAA;AACF,SACF;AAAA,MACF;AAGA,MAAA,OAAO,MAAM,IAAA,GACT,EAAE,GAAG,CAAA,EAAG,MAAM,eAAA,EAAiB,MAAA,EAAQ,IAAA,EAAM,IAAA,KAC7C,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,iBAAiB,MAAA,EAAO;AAAA,IAC5C;AAAA;AAEJ;AAQO,SAAS,oBAAoB,MAAA,EAAsC;AACxE,EAAA,MAAM,OAA6B,EAAC;AACpC,EAAA,MAAM,QAAwB,EAAC;AAE/B,EAAA,IAAI,OAAO,IAAA,EAAM;AAGf,IAAA,IAAI,OAAO,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAE,SAAS,CAAA,EAAG;AACzC,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,CAAA,MAAA,EAAS,OAAO,IAAI,CAAA,+DAAA;AAAA,OACtB;AAAA,IACF;AACA,IAAA,IAAA,CAAK,KAAK,UAAA,CAAW,iBAAA,EAAmB,OAAO,IAAA,EAAM,iBAAA,EAAmB,KAAK,CAAC,CAAA;AAC9E,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB;AAEA,EAAA,KAAA,MAAW,CAAC,MAAM,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,EAAG;AACzD,IAAA,IAAI,SAAS,iBAAA,EAAmB;AAC9B,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,CAAA,MAAA,EAAS,MAAA,CAAO,IAAI,CAAA,eAAA,EAAkB,iBAAiB,CAAA,2CAAA;AAAA,OACzD;AAAA,IACF;AACA,IAAA,IAAA,CAAK,KAAK,UAAA,CAAW,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,KAAK,CAAC,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AACvB;AAOA,SAAS,WAAW,KAAA,EAAoD;AACtE,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA4B;AAC/C,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA;AACtC,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AAAA,gBACZ,GAAA,CAAI,IAAA,CAAK,SAAA,EAAW,CAAC,IAAI,CAAC,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,YAAA,CACP,OAAA,EACA,IAAA,EACA,MAAA,EACa;AACb,EAAA,MAAM,IAKF,EAAC;AACL,EAAA,IAAI,OAAA,CAAQ,QAAA,EAAU,CAAA,CAAE,QAAA,GAAW,IAAA;AACnC,EAAA,IAAI,OAAA,CAAQ,QAAA,EAAU,CAAA,CAAE,QAAA,GAAW,IAAA;AACnC,EAAA,IAAI,OAAA,CAAQ,WAAA,KAAgB,MAAA,EAAW,CAAA,CAAE,cAAc,OAAA,CAAQ,WAAA;AAC/D,EAAA,IAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,EAAW,CAAA,CAAE,UAAU,OAAA,CAAQ,OAAA;AAEvD,EAAA,QAAQ,QAAQ,IAAA;AAAM,IACpB,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,UAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,MAAA;AAAA,IACL,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,IAEpC,KAAK,QAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,IAAA,EAAM,QAAA;AAAA,QACN,GAAI,QAAQ,GAAA,KAAQ,MAAA,GAAY,EAAE,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAI,GAAI,EAAC;AAAA,QACxD,GAAI,QAAQ,GAAA,KAAQ,MAAA,GAAY,EAAE,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAI,GAAI,EAAC;AAAA,QACxD,GAAI,QAAQ,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAK,GAAI;AAAC,OAC7D;AAAA,IAEF,KAAK,UAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,IAAA,EAAM,UAAA;AAAA,QACN,GAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,GACnB,EAAE,MAAA,EAAQ,CAAC,GAAG,OAAA,CAAQ,MAAM,CAAA,EAAE,GAC9B,EAAC;AAAA,QACL,GAAI,OAAA,CAAQ,IAAA,GAAO,EAAE,IAAA,EAAM,IAAA,KAAS;AAAC,OACvC;AAAA,IAEF,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,MAAM,QAAA,EAAU,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAAA,IAExD,KAAK,MAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,IAAA,EAAM,MAAA;AAAA,QACN,MAAA,EAAQ,CAAC,GAAG,OAAA,CAAQ,MAAM,CAAA;AAAA,QAC1B,GAAI,OAAA,CAAQ,IAAA,GAAO,EAAE,IAAA,EAAM,IAAA,KAAS;AAAC,OACvC;AAAA,IAEF,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,IAAI,KAAK,EAAC;AAClC,MAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,QAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,UAAA,MAAM,IAAI,gBAAA;AAAA,YACR,gBAAgB,IAAI,CAAA,oDAAA;AAAA,WACtB;AAAA,QACF;AACA,QAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,IAAI,EACnB,IAAA,CAAK,CAAC,GAAG,CAAA,KAAA,CAAO,CAAA,CAAE,YAAY,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA,CAAE,CAAA,CACpD,IAAI,CAAC,CAAA,KAAM,EAAE,SAAS,CAAA;AACzB,QAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,CAAC,GAAG,OAAA,CAAQ,OAAO,CAAA,EAAG,KAAA,EAAM;AAAA,MACrE;AACA,MAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,QAAA,MAAM,IAAI,gBAAA;AAAA,UACR,CAAA,aAAA,EAAgB,IAAI,CAAA,MAAA,EAAS,IAAA,CAAK,MAAM,CAAA,uCAAA;AAAA,SAC1C;AAAA,MACF;AACA,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAS,SAAS,CAAC,GAAG,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,IAC9D;AAAA,IAEA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,IAAI,KAAK,EAAC;AAClC,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,QAAA,MAAM,IAAI,gBAAA;AAAA,UACR,CAAA,cAAA,EAAiB,IAAI,CAAA,oCAAA,EAAuC,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,SACzE;AAAA,MACF;AACA,MAAA,MAAM,CAAC,IAAI,CAAA,GAAI,IAAA;AACf,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,IAAI,gBAAA;AAAA,UACR,iBAAiB,IAAI,CAAA,sCAAA;AAAA,SACvB;AAAA,MACF;AACA,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,MAAM,QAAA,EAAU,IAAA,EAAM,KAAK,SAAA,EAAU;AAAA,IACtD;AAAA,IAEA,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,IAAI,KAAK,EAAC;AAClC,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,QAAA,MAAM,IAAI,gBAAA;AAAA,UACR,gBAAgB,IAAI,CAAA,8BAAA;AAAA,SACtB;AAAA,MACF;AACA,MAAA,MAAM,SAAA,GAAY,CAAC,GAAG,IAAI,EACvB,IAAA,CAAK,CAAC,GAAG,CAAA,KAAA,CAAO,CAAA,CAAE,YAAY,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA,CAAE,CAAA,CACpD,IAAI,CAAC,CAAA,KAAM,EAAE,SAAS,CAAA;AACzB,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,SAAS,SAAA,EAAU;AAAA,IAC1C;AAAA,IAEA,KAAK,eAAA,EAAiB;AACpB,MAAA,MAAM,SAAsC,EAAC;AAC7C,MAAA,KAAA,MAAW,KAAA,IAAS,QAAQ,MAAA,EAAQ;AAClC,QAAA,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,YAAA;AAAA,UACnB,KAAA;AAAA,UACA,GAAG,IAAI,CAAA,EAAG,QAAQ,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA;AAAA,UAC/B;AAAA,SACF;AAAA,MACF;AACA,MAAA,OAAO,QAAQ,IAAA,GACX,EAAE,GAAG,CAAA,EAAG,MAAM,eAAA,EAAiB,MAAA,EAAQ,IAAA,EAAM,IAAA,KAC7C,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,iBAAiB,MAAA,EAAO;AAAA,IAC5C;AAAA;AAEJ;AAGO,SAAS,mBAAA,CACd,MACA,KAAA,EACY;AACZ,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,KAAA,CAAM,KAAK,CAAA;AAGrC,EAAA,MAAM,CAAC,KAAK,CAAA,GAAI,KAAA,CAAM,IAAA;AACtB,EAAA,IAAI,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,iBAAA,EAAmB;AAC7C,IAAA,IAAI,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,SAAS,IAAI,CAAA,MAAA,EAAS,iBAAiB,CAAA,+CAAA,EAAkD,KAAA,CAAM,KAAK,MAAM,CAAA,EAAA;AAAA,OAC5G;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,QAAQ,EAAC;AAAA,MACT,IAAA,EAAM,YAAA,CAAa,KAAA,EAAO,iBAAA,EAAmB,MAAM;AAAA,KACrD;AAAA,EACF;AAEA,EAAA,MAAM,SAAsC,EAAC;AAC7C,EAAA,KAAA,MAAW,OAAA,IAAW,MAAM,IAAA,EAAM;AAChC,IAAA,IAAI,OAAA,CAAQ,SAAS,iBAAA,EAAmB;AACtC,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,CAAA,MAAA,EAAS,IAAI,CAAA,IAAA,EAAO,iBAAiB,CAAA,0CAAA;AAAA,OACvC;AAAA,IACF;AACA,IAAA,MAAA,CAAO,QAAQ,IAAI,CAAA,GAAI,aAAa,OAAA,EAAS,OAAA,CAAQ,MAAM,MAAM,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,EAAE,MAAM,MAAA,EAAO;AACxB;;;ACnYO,IAAM,QAAA,GAAW,QAAA;;;ACpCxB,IAAM,MAAA,GAAS,UAAA;AACf,IAAM,MAAA,GAAS,QAAA;AAEf,SAAS,SAAA,CAAU,MAAc,KAAA,EAAuB;AACtD,EAAA,IAAI,IAAI,IAAA,KAAS,CAAA;AACjB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,CAAA,IAAK,KAAA,CAAM,WAAW,CAAC,CAAA;AAEvB,IAAA,CAAA,GAAK,CAAA,IAAA,CAAM,CAAA,IAAK,CAAA,KAAM,CAAA,IAAK,CAAA,CAAA,IAAM,KAAK,CAAA,CAAA,IAAM,CAAA,IAAK,CAAA,CAAA,IAAM,CAAA,IAAK,EAAA,CAAA,CAAA,KAAU,CAAA;AAAA,EACxE;AACA,EAAA,OAAO,CAAA,KAAM,CAAA;AACf;AAQO,SAAS,mBAAA,GAAqC;AACnD,EAAA,IAAI,CAAA,GAAI,MAAA;AACR,EAAA,IAAI,CAAA,GAAI,MAAA;AACR,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,OAAO;AAAA,IACL,KAAK,KAAA,EAAqB;AACxB,MAAA,CAAA,GAAI,SAAA,CAAU,GAAG,KAAK,CAAA;AACtB,MAAA,CAAA,GAAI,SAAA,CAAU,GAAG,KAAK,CAAA;AACtB,MAAA,MAAA,IAAU,KAAA,CAAM,MAAA;AAAA,IAClB,CAAA;AAAA,IACA,OAAA,GAAkB;AAChB,MAAA,OAAO,CAAA,EAAG,MAAA,CAAO,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,IAClE;AAAA,GACF;AACF;AAEO,SAAS,gBAAgB,MAAA,EAAwB;AACtD,EAAA,MAAM,SAAS,mBAAA,EAAoB;AACnC,EAAA,MAAA,CAAO,KAAK,MAAM,CAAA;AAClB,EAAA,OAAO,OAAO,OAAA,EAAQ;AACxB;;;ACeO,IAAM,UAAA,GAAa,CAAA;;;ACWnB,SAAS,yBAAA,CACd,KAAA,EACA,IAAA,EACA,OAAA,EACkB;AAClB,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,UAAA;AAAA,IACH,MAAA,EAAQ,gBAAA;AAAA,IACR,WAAA,EAAa,eAAA,CAAgB,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,IAClD,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,YAAA;AAAA,MACN,IAAA;AAAA,MACA,SAAA,EAAW,UAAA;AAAA,MACX,eAAe,OAAA,EAAS,aAAA,IAAiB,EAAE,MAAA,EAAQ,MAAA,EAAQ,KAAK,QAAA,EAAS;AAAA,MACzE,MAAM,EAAC;AAAA,MACP,MAAA,EAAQ,UAAA;AAAA,MACR,KAAA;AAAA,MACA,OAAA,EAAS;AAAA;AACX,GACF;AACF;;;ACPA,IAAM,8BAAA,GAAiC,oBAAA;AAevC,SAAS,UAAU,QAAA,EAAsD;AACvE,EAAA,OAAO,OAAA;AAAA,IACL,QAAA,EAAU,QAAA,IACR,QAAA,CAAS,YAAA,KAAiB;AAAA,GAC9B;AACF;AA0CA,IAAI,WAAA;AACJ,SAAS,MAAA,GAAc;AACrB,EAAA,OAAQ,WAAA,KAAgB,IAAIA,oBAAA,CAAI,EAAE,WAAW,IAAA,EAAM,MAAA,EAAQ,OAAO,CAAA;AACpE;AAmBA,SAAS,UAAU,KAAA,EAAyB;AAC1C,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,SAAS,CAAA;AACpD,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACtC,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AACrE,MAAA,IAAI,MAAM,QAAA,EAAU;AACpB,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,CAAC,CAAA;AAAA,IACtB;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,kBAAkB,MAAA,EAA8C;AACvE,EAAA,OAAA,CAAQ,MAAA,IAAU,EAAC,EAChB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,EAAE,YAAA,IAAgB,QAAQ,IAAI,CAAA,CAAE,OAAA,IAAW,EAAE,CAAA,CAAA,CAAG,IAAA,EAAM,CAAA,CACpE,KAAA,CAAM,GAAG,CAAC,CAAA;AACf;AAGA,SAAS,mBAAmB,iBAAA,EAAqC;AAC/D,EAAA,IAAI,CAAC,iBAAA,IAAqB,OAAO,iBAAA,KAAsB,UAAU,OAAO,KAAA;AACxE,EAAA,MAAM,aAAc,iBAAA,CAA8C,UAAA;AAClE,EAAA,OACE,CAAC,CAAC,UAAA,IACF,OAAO,UAAA,KAAe,YACtB,QAAA,IAAa,UAAA;AAEjB;AASO,SAAS,qBAAA,CACd,QACA,iBAAA,EACW;AACX,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAA,EAAO,CAAE,OAAA,CAAQ,iBAA2B,CAAA;AAAA,EACzD,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,MAAA,EAAQ,0CACN,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CACjD,CAAA;AAAA,KACF;AAAA,EACF;AAIA,EAAA,IAAI,SAAS,MAAM,CAAA,EAAG,OAAO,EAAE,IAAI,IAAA,EAAK;AACxC,EAAA,MAAM,YAAA,GAAe,iBAAA,CAAkB,QAAA,CAAS,MAAM,CAAA;AACtD,EAAA,IAAI,QAAA,CAAS,UAAU,MAAM,CAAC,GAAG,OAAO,EAAE,IAAI,IAAA,EAAK;AACnD,EAAA,MAAM,cAAA,GAAiB,iBAAA,CAAkB,QAAA,CAAS,MAAM,CAAA;AAIxD,EAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,iBAAiB,CAAA,GAC/C,YAAA,GACA,cAAA;AACJ,EAAA,OAAO,EAAE,IAAI,KAAA,EAAO,MAAA,EAAQ,yBAAyB,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,EAAG;AAC3E;AAsBA,IAAM,2BAAA,mBAAmD,IAAI,GAAA,CAAI,CAAC,UAAU,CAAC,CAAA;AAG7E,IAAM,qBAAA,GAAwB,CAAA;AAe9B,SAAS,kBAAA,CAAmB,KAAA,EAAgB,KAAA,GAAQ,CAAA,EAAY;AAC9D,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,KAAA;AAClD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,SAAiB,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,CAAA;AAC5D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,MAAA,CAAO,SAAS,KAAK,CAAA;AAC3D,EAAA,IAAI,OAAO,KAAA,KAAU,SAAA,EAAW,OAAO,IAAA;AAEvC,EAAA,IAAI,KAAA,IAAS,uBAAuB,OAAO,IAAA;AAC3C,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,KAAA,CAAM,KAAK,CAAC,KAAA,KAAU,mBAAmB,KAAA,EAAO,KAAA,GAAQ,CAAC,CAAC,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,KAAgC,CAAA,CAAE,IAAA;AAAA,MAAK,CAAC,KAAA,KAC3D,kBAAA,CAAmB,KAAA,EAAO,QAAQ,CAAC;AAAA,KACrC;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAaA,SAAS,iCAAiC,UAAA,EAAoC;AAC5E,EAAA,IAAI,UAAA,KAAe,MAAA,IAAa,UAAA,KAAe,IAAA,EAAM;AACnD,IAAA,OAAO,2CAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,eAAe,QAAA,EAAU;AAClC,IAAA,OAAO,CAAA,yCAAA,EAA4C,OAAO,UAAU,CAAA,CAAA,CAAA;AAAA,EACtE;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC7B,IAAA,OAAO,mDAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAS,UAAA;AACf,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAC/B,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,sCAAA;AAE9B,EAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,CAAC,QAAQ,CAAC,2BAAA,CAA4B,GAAA,CAAI,GAAG,CAAC,CAAA;AAC9E,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,IAAA,OAAO,CAAA,sCAAA,EAAyC,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,8DAAA,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,CAAC,GAAA,KAAQ,mBAAmB,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA,EAAG;AAC/D,IAAA,OAAO,CAAA,qEAAA,EAAwE,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,iDAAA,CAAA;AAAA,EACvG;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,cAAA,CACP,IAAA,EACA,MAAA,EACA,UAAA,EACA,mBACA,QAAA,EACW;AAEX,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,IAAA;AAAA,MACJ,MAAA,EACE;AAAA,KACJ;AAAA,EACF;AAYA,EAAA,MAAM,YAAA,GACJ,iBAAA,EAAmB,QAAA,IACnB,iBAAA,CAAkB,YAAA,KAAiB,8BAAA;AACrC,EAAA,MAAM,oBAAoB,YAAA,GACtB,CAAA,kDAAA,EAAqD,IAAI,CAAA,MAAA,EACrD,8BAA8B,CAAA,2LAAA,CAAA,GAIlC,IAAA;AAEJ,EAAA,IAAI,CAAC,UAAA,IAAc,CAAC,SAAA,CAAU,iBAAiB,CAAA,EAAG;AAChD,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,MAAA,EACE,iBAAA,IACA,CAAA,MAAA,EAAS,IAAI,CAAA,0HAAA;AAAA,KACjB;AAAA,EACF;AAEA,EAAA,IACE,UAAA,IACA,CAAC,UAAA,CAAW,eAAA,IACZ,CAAC,UAAA,CAAW,SAAA,IACZ,CAAC,UAAA,CAAW,kBAAA,IACZ,CAAC,SAAA,CAAU,iBAAiB,CAAA,EAC5B;AACA,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,MAAA,EACE,iBAAA,IACA,CAAA,MAAA,EAAS,IAAI,CAAA,yIAAA;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,IAAI,YAAY,kBAAA,EAAoB;AAClC,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AACF,MAAA,UAAA,GAAa,UAAA,CAAW,kBAAA;AAAA,QACtB,yBAAA,CAA0B,QAAQ,IAAI;AAAA,OACxC;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,MAAA,EAAQ,6BACN,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CACjD,CAAA;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,iCAAiC,UAAU,CAAA;AAC3D,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,MAAA,EAAQ,CAAA,EAAG,OAAO,CAAA,UAAA,EAAa,IAAI,CAAA,oBAAA;AAAA,OACrC;AAAA,IACF;AACA,IAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,EACpB;AAOA,EAAA,MAAM,SAAA,GAAY,YAAY,eAAA,GAC1B,CAAA,oBAAA,EAAuB,WAAW,eAAe,CAAA,CAAA,CAAA,GACjD,YAAY,SAAA,GACV,0BAAA,GACA,UAAU,iBAAiB,CAAA,IAAK,oBAC9B,CAAA,SAAA,EAAY,iBAAA,CAAkB,MAAM,CAAA,YAAA,EAAe,iBAAA,CAAkB,YAAY,CAAA,CAAA,CAAA,GACjF,WAAA;AACR,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,MAAA,EAAQ,0BAAqB,SAAS,CAAA,wEAAA;AAAA,GACxC;AACF;AAEO,SAAS,gBAAgB,KAAA,EAAsC;AACpE,EAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,KAAA,CAAM,MAAA,EAAQ,MAAM,iBAAiB,CAAA;AAC9E,EAAA,MAAM,MAAA,GAAS,cAAA;AAAA,IACb,KAAA,CAAM,IAAA;AAAA,IACN,KAAA,CAAM,MAAA;AAAA,IACN,KAAA,CAAM,UAAA;AAAA,IACN,KAAA,CAAM,iBAAA;AAAA,IACN,KAAA,CAAM;AAAA,GACR;AACA,EAAA,OAAO,EAAE,QAAA,EAAU,UAAA,CAAW,MAAM,MAAA,CAAO,EAAA,EAAI,YAAY,MAAA,EAAO;AACpE;AAOO,SAAS,uBAAA,CACd,MACA,MAAA,EACQ;AACR,EAAA,IAAI,MAAA,CAAO,UAAU,OAAO,EAAA;AAC5B,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,CAAC,MAAA,CAAO,UAAA,CAAW,EAAA,EAAI;AACzB,IAAA,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAA,CAAO,UAAA,CAAW,MAAA,IAAU,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC5E;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,MAAA,CAAO,EAAA,EAAI;AACrB,IAAA,KAAA,CAAM,KAAK,CAAA,YAAA,EAAe,MAAA,CAAO,MAAA,CAAO,MAAA,IAAU,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,SAAS,IAAI,CAAA,8BAAA,EAA4B,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA,CAAA;AACnE;;;AC9VA,IAAM,6BAAA,GAAgC,wCAAA;AAEtC,IAAM,oBAAA,GAAuB,GAAA;AAE7B,SAAS,kBAAA,CACP,IAAA,EACA,MAAA,EACA,MAAA,EACQ;AACR,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,qBAAA;AACH,MAAA,OAAO,SAAS,IAAI,CAAA,iDAAA,CAAA;AAAA,IACtB,KAAK,oBAAA;AACH,MAAA,OAAO,SAAS,IAAI,CAAA,+DAAA,CAAA;AAAA,IACtB,KAAK,gBAAA;AACH,MAAA,OAAO,SAAS,IAAI,CAAA,yCAAA,EAClB,SAAS,CAAA,EAAA,EAAK,MAAM,KAAK,EAC3B,CAAA,CAAA;AAAA,IACF,KAAK,qBAAA;AACH,MAAA,OAAO,yCAAyC,IAAI,CAAA,CAAA,EAClD,SAAS,CAAA,EAAA,EAAK,MAAM,KAAK,EAC3B,CAAA,CAAA;AAAA;AAEN;AAEA,SAAS,QAAA,CACP,IAAA,EACA,MAAA,EACA,MAAA,EACsB;AACtB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,OAAA,EAAS,KAAA;AAAA,IACT,EAAA,EAAI,KAAA;AAAA,IACJ,QAAQ,CAAC,kBAAA,CAAmB,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAC,CAAA;AAAA,IACjD,cAAA,EAAgB;AAAA,GAClB;AACF;AAOO,SAAS,mBAAA,CACd,MAAA,EACA,OAAA,GAAgC,EAAC,EAClB;AACf,EAAA,MAAM,GAAA,GAAM,QAAQ,UAAA,IAAc,oBAAA;AAClC,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,IAAA,CAAK,GAAA;AAChC,EAAA,MAAM,KAAA,uBAAY,GAAA,EAGhB;AAEF,EAAA,eAAe,WAAA,CACb,MACA,MAAA,EACkB;AAClB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAC7B,IAAA,IAAI,MAAA,IAAU,GAAA,EAAI,GAAI,MAAA,CAAO,aAAa,GAAA,EAAK;AAC7C,MAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA,IAC1D;AACA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAM,MAAA,CAAO,UAAA,CAAW,IAAA,EAAM,MAAM,CAAA;AAAA,IAC/C,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO;AAAA,QACL,WAAA,EAAa,qBAAA;AAAA,QACb,QAAQ,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,OACzD;AAAA,IACF;AACA,IAAA,IAAI,iBAAiB,MAAA,EAAQ,OAAO,EAAE,WAAA,EAAa,OAAO,WAAA,EAAY;AAGtE,IAAA,IAAK,MAAA,CAAO,UAAsB,IAAA,EAAM;AACtC,MAAA,OAAO,EAAE,aAAa,oBAAA,EAAqB;AAAA,IAC7C;AACA,IAAA,KAAA,CAAM,IAAI,IAAA,EAAM;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,WAAW,GAAA;AAAI,KAChB,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,SAAS,KAAA,EAAO,IAAA,EAAM,SAAS,IAAI,eAAA,GAAkB,MAAA,EAAQ;AACjE,MAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACrC,QAAA,MAAM,IAAI,SAAA;AAAA,UACR,CAAA,+DAAA,EAAkE,OAAO,IAAI,CAAA,CAAA;AAAA,SAC/E;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,IAAA,EAAM,MAAM,CAAA;AAC9C,MAAA,IAAI,iBAAiB,OAAA,EAAS;AAC5B,QAAA,OAAO,QAAA,CAAS,IAAA,EAAM,OAAA,CAAQ,WAAA,EAAa,QAAQ,MAAM,CAAA;AAAA,MAC3D;AAEA,MAAA,MAAM,GAAA,GAAM,qBAAA,CAAsB,KAAA,EAAO,OAAA,CAAQ,MAAM,CAAA;AAMvD,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,IAAI,MAAA,EAAQ,UAAA,CAAW,6BAA6B,CAAA,EAAG;AACpE,QAAA,OAAO,QAAA,CAAS,IAAA,EAAM,gBAAA,EAAkB,GAAA,CAAI,MAAM,CAAA;AAAA,MACpD;AAEA,MAAA,OAAO;AAAA,QACL,IAAA;AAAA,QACA,OAAA,EAAS,IAAA;AAAA,QACT,IAAI,GAAA,CAAI,EAAA;AAAA,QACR,MAAA,EAAQ,IAAI,EAAA,GAAK,KAAK,CAAC,GAAA,CAAI,UAAU,mBAAmB,CAAA;AAAA,QACxD,cAAA,EAAgB;AAAA,OAClB;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,YAAA,CAAa,IAAA,EAAM,SAAS,IAAI,eAAA,GAAkB,MAAA,EAAQ;AAC9D,MAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,IAAA,EAAM,MAAM,CAAA;AAC9C,MAAA,OAAO,aAAA,IAAiB,OAAA,GAAU,IAAA,GAAO,OAAA,CAAQ,MAAA;AAAA,IACnD,CAAA;AAAA,IAEA,WAAW,IAAA,EAAM;AACf,MAAA,IAAI,IAAA,EAAM,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AAAA,iBAChB,KAAA,EAAM;AAAA,IACnB;AAAA,GACF;AACF;;;AC3PO,IAAM,iBAAA,GAAoB;AAAA,EAC/B,QAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF","file":"registry.cjs","sourcesContent":["/**\n * Kind ↔ content_ir storage shape — the pure, DB-free reshaping between the\n * consumed `KindSchema` and the `content_ir.kind_definition.data` array +\n * `content_ir.kind_edge` rows.\n *\n * Two exact inverses:\n *   - `kindSchemaToStorage`  — the MIGRATION / write direction: a parsed\n *     `KindSchema` (fields Record, targets inline) → an ORDERED `data` array\n *     (targets stripped) + externalized `kind_edge` specs (targets, keyed by\n *     field PATH). This is what pours `flexible_data` (and future authored\n *     kinds) into the canonical tables.\n *   - `storageToKindSchema`  — the ADAPTER / read direction: `data` array +\n *     edges → the same `KindSchema` the parser/emitter consume, re-attaching\n *     `object.kind` / `array.itemKinds` from the edges by path.\n *\n * Design invariants (from the 2026-07-05 kind-registry storage design, since deleted):\n *   - The `data` element is `FieldSchema` + `name`, MINUS ref targets. Order is\n *     intrinsic to the array (fixes the jsonb key-reorder bug).\n *   - `kind_edge` is the SINGLE source of truth for kind→kind refs: `object`\n *     → one edge (position null); `array` → N edges (union) ordered by\n *     `position`. `field_name` is a dot-PATH so a ref nested inside an\n *     `inline_object` still gets a distinct, collision-free edge.\n *   - `inline_object` is structural: its `fields` is an ordered array, it never\n *     becomes a registry row and never carries `__kind`. Its nested refs DO get\n *     edges (path-prefixed) so cascade/pinning see every dependency. Its\n *     `open` flag persists on the element (losing it is the open-empty-object\n *     defect).\n *   - `union.kinds` refs externalize to edges exactly like `array.itemKinds`;\n *     the stored element keeps `hasKinds: true` so lost edges scream on read.\n *   - A NON-OBJECT ROOT (`KindSchema.root`) stores as ONE reserved element\n *     named `ROOT_STORAGE_NAME` (\"__root\") — the only element allowed in that\n *     kind's `data`. Real fields may never use the reserved name.\n *\n * NO imports of supabase / the DB — this is pure and unit-tested by round-trip\n * (`__tests__/kind-storage-transform.test.ts`).\n */\n\nimport type {\n  FieldSchema,\n  KindSchema,\n  RecordValueType,\n} from \"../core/kind-schema.types\";\n\n/**\n * Reserved `data[]` element name for a NON-OBJECT ROOT form (`KindSchema.root`).\n * A root-form kind stores exactly one element under this name; the read\n * direction reconstructs `{ root }` instead of a field map. The write\n * direction rejects any REAL field with this name — the name is the marker.\n */\nexport const ROOT_STORAGE_NAME = \"__root\";\n\n// ---------------------------------------------------------------------------\n// Stored shapes (mirror content_ir.kind_definition.data + content_ir.kind_edge)\n// ---------------------------------------------------------------------------\n\ntype StoredFieldBase = {\n  name: string;\n  required?: boolean;\n  nullable?: boolean;\n  /** Human guidance — mirrors FieldBase.description. */\n  description?: string;\n  /** Default VALUE (annotation-level) — mirrors FieldBase.default. */\n  default?: unknown;\n};\n\n/** One element of `kind_definition.data` — FieldSchema + name, ref targets removed. */\nexport type StoredFieldElement =\n  | (StoredFieldBase & { type: \"string\" | \"boolean\" })\n  | (StoredFieldBase & {\n      type: \"number\";\n      min?: number;\n      max?: number;\n      step?: number;\n    })\n  | (StoredFieldBase & { type: \"string[]\"; values?: string[]; open?: boolean })\n  | (StoredFieldBase & { type: \"number[]\" | \"boolean[]\" })\n  | (StoredFieldBase & { type: \"json\" })\n  | (StoredFieldBase & { type: \"json[]\" })\n  | (StoredFieldBase & { type: \"array\" }) // ref array — targets live in edges\n  | (StoredFieldBase & { type: \"object\" }) // single ref — target lives in edges\n  | (StoredFieldBase & {\n      type: \"inline_object\";\n      fields: StoredFieldElement[];\n      open?: boolean;\n    })\n  | (StoredFieldBase & { type: \"record\"; values: RecordValueType })\n  | (StoredFieldBase & { type: \"enum\"; values: string[]; open?: boolean })\n  | (StoredFieldBase & {\n      type: \"union\";\n      scalars: Array<\"string\" | \"number\" | \"boolean\">;\n      /** Marker that this union's kind refs live in edges (positions ordered). */\n      hasKinds?: boolean;\n    });\n\n/** One `content_ir.kind_edge` row (child resolved to an id at insert time). */\nexport type KindEdgeSpec = {\n  /** Field PATH in the parent's `data` (dot-notation into inline_objects). */\n  fieldPath: string;\n  /** Child kind slug — insert resolves this to `child_definition_id`. */\n  childKind: string;\n  /** Union (anyOf) ordering for array refs; null for a single object ref. */\n  position: number | null;\n};\n\n/** The full write payload for one kind: the ordered data array + its edges. */\nexport type KindStorageShape = {\n  data: StoredFieldElement[];\n  edges: KindEdgeSpec[];\n};\n\nexport class KindStorageError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = \"KindStorageError\";\n  }\n}\n\n// ---------------------------------------------------------------------------\n// WRITE direction: KindSchema → { data[], edges[] }\n// ---------------------------------------------------------------------------\n\nconst PATH_SEP = \".\";\n\nfunction base(field: FieldSchema): StoredFieldBase & { name: string } {\n  // name is filled by the caller; required/nullable copied only when true so\n  // the stored element stays minimal (matches the emitter's optional reads).\n  const out: {\n    name: string;\n    required?: boolean;\n    nullable?: boolean;\n    description?: string;\n    default?: unknown;\n  } = {\n    name: \"\",\n  };\n  if (field.required) out.required = true;\n  if (field.nullable) out.nullable = true;\n  if (field.description !== undefined) out.description = field.description;\n  // `null` is a legitimate default; only ABSENCE is absence.\n  if (field.default !== undefined) out.default = field.default;\n  return out;\n}\n\n/**\n * Reshape a field into its stored element, pushing any ref targets into `edges`\n * keyed by the field's full path. `path` is the dot-path of THIS field.\n */\nfunction storeField(\n  name: string,\n  field: FieldSchema,\n  path: string,\n  edges: KindEdgeSpec[],\n): StoredFieldElement {\n  const b = { ...base(field), name };\n\n  switch (field.type) {\n    case \"string\":\n    case \"boolean\":\n    case \"number[]\":\n    case \"boolean[]\":\n    case \"json\":\n    case \"json[]\":\n      return { ...b, type: field.type };\n\n    case \"number\":\n      return {\n        ...b,\n        type: \"number\",\n        ...(field.min !== undefined ? { min: field.min } : {}),\n        ...(field.max !== undefined ? { max: field.max } : {}),\n        ...(field.step !== undefined ? { step: field.step } : {}),\n      };\n\n    case \"string[]\":\n      return {\n        ...b,\n        type: \"string[]\",\n        ...(field.values !== undefined ? { values: [...field.values] } : {}),\n        ...(field.open ? { open: true } : {}),\n      };\n\n    case \"record\":\n      return { ...b, type: \"record\", values: field.values };\n\n    case \"enum\":\n      return {\n        ...b,\n        type: \"enum\",\n        values: [...field.values],\n        ...(field.open ? { open: true } : {}),\n      };\n\n    case \"union\": {\n      // Object-union members are refs → edges (positions ordered), exactly\n      // like array itemKinds. `hasKinds` marks the element so the read\n      // direction can scream about lost edges instead of silently narrowing.\n      if (field.kinds && field.kinds.length > 0) {\n        field.kinds.forEach((childKind, position) => {\n          edges.push({ fieldPath: path, childKind, position });\n        });\n        return { ...b, type: \"union\", scalars: [...field.scalars], hasKinds: true };\n      }\n      return { ...b, type: \"union\", scalars: [...field.scalars] };\n    }\n\n    case \"object\":\n      // Single ref → exactly one edge, no position.\n      edges.push({ fieldPath: path, childKind: field.kind, position: null });\n      return { ...b, type: \"object\" };\n\n    case \"array\":\n      // Ref array (union) → one edge per itemKind, ordered by position.\n      field.itemKinds.forEach((childKind, position) => {\n        edges.push({ fieldPath: path, childKind, position });\n      });\n      return { ...b, type: \"array\" };\n\n    case \"inline_object\": {\n      // Structural: recurse, prefixing nested paths so nested refs get their\n      // own collision-free edges. Field order preserved (Object.entries).\n      const fields: StoredFieldElement[] = [];\n      for (const [childName, childField] of Object.entries(field.fields)) {\n        fields.push(\n          storeField(\n            childName,\n            childField,\n            `${path}${PATH_SEP}${childName}`,\n            edges,\n          ),\n        );\n      }\n      // `open` persists on the element — losing it is the open-empty-object\n      // defect (an open {} materializing as CLOSED).\n      return field.open\n        ? { ...b, type: \"inline_object\", fields, open: true }\n        : { ...b, type: \"inline_object\", fields };\n    }\n  }\n}\n\n/**\n * MIGRATION / write direction. Order of `data` follows `Object.entries(fields)`\n * — the caller supplies the KindSchema whose field order is authoritative\n * (prefer the compiled `system-kinds.ts` order for system kinds during the\n * one-time flexible_data migration; jsonb order is the fallback for user kinds).\n */\nexport function kindSchemaToStorage(schema: KindSchema): KindStorageShape {\n  const data: StoredFieldElement[] = [];\n  const edges: KindEdgeSpec[] = [];\n\n  if (schema.root) {\n    // Non-object root form: exactly one reserved element carries the root\n    // field; a field map alongside it would be two contradictory shapes.\n    if (Object.keys(schema.fields).length > 0) {\n      throw new KindStorageError(\n        `kind \"${schema.kind}\": root form and a non-empty fields map are mutually exclusive.`,\n      );\n    }\n    data.push(storeField(ROOT_STORAGE_NAME, schema.root, ROOT_STORAGE_NAME, edges));\n    return { data, edges };\n  }\n\n  for (const [name, field] of Object.entries(schema.fields)) {\n    if (name === ROOT_STORAGE_NAME) {\n      throw new KindStorageError(\n        `kind \"${schema.kind}\": field name \"${ROOT_STORAGE_NAME}\" is reserved for the non-object root form.`,\n      );\n    }\n    data.push(storeField(name, field, name, edges));\n  }\n  return { data, edges };\n}\n\n// ---------------------------------------------------------------------------\n// READ direction: { data[], edges[] } → KindSchema  (the adapter's core)\n// ---------------------------------------------------------------------------\n\n/** Index edges by field path for O(1) re-attachment. */\nfunction indexEdges(edges: KindEdgeSpec[]): Map<string, KindEdgeSpec[]> {\n  const byPath = new Map<string, KindEdgeSpec[]>();\n  for (const edge of edges) {\n    const list = byPath.get(edge.fieldPath);\n    if (list) list.push(edge);\n    else byPath.set(edge.fieldPath, [edge]);\n  }\n  return byPath;\n}\n\nfunction restoreField(\n  element: StoredFieldElement,\n  path: string,\n  byPath: Map<string, KindEdgeSpec[]>,\n): FieldSchema {\n  const b: {\n    required?: boolean;\n    nullable?: boolean;\n    description?: string;\n    default?: unknown;\n  } = {};\n  if (element.required) b.required = true;\n  if (element.nullable) b.nullable = true;\n  if (element.description !== undefined) b.description = element.description;\n  if (element.default !== undefined) b.default = element.default;\n\n  switch (element.type) {\n    case \"string\":\n    case \"boolean\":\n    case \"number[]\":\n    case \"boolean[]\":\n    case \"json\":\n    case \"json[]\":\n      return { ...b, type: element.type };\n\n    case \"number\":\n      return {\n        ...b,\n        type: \"number\",\n        ...(element.min !== undefined ? { min: element.min } : {}),\n        ...(element.max !== undefined ? { max: element.max } : {}),\n        ...(element.step !== undefined ? { step: element.step } : {}),\n      };\n\n    case \"string[]\":\n      return {\n        ...b,\n        type: \"string[]\",\n        ...(element.values !== undefined\n          ? { values: [...element.values] }\n          : {}),\n        ...(element.open ? { open: true } : {}),\n      };\n\n    case \"record\":\n      return { ...b, type: \"record\", values: element.values };\n\n    case \"enum\":\n      return {\n        ...b,\n        type: \"enum\",\n        values: [...element.values],\n        ...(element.open ? { open: true } : {}),\n      };\n\n    case \"union\": {\n      const list = byPath.get(path) ?? [];\n      if (element.hasKinds) {\n        if (list.length === 0) {\n          throw new KindStorageError(\n            `union field \"${path}\" declares kind members (hasKinds) but has no edges.`,\n          );\n        }\n        const kinds = [...list]\n          .sort((a, z) => (a.position ?? 0) - (z.position ?? 0))\n          .map((e) => e.childKind);\n        return { ...b, type: \"union\", scalars: [...element.scalars], kinds };\n      }\n      if (list.length > 0) {\n        throw new KindStorageError(\n          `union field \"${path}\" has ${list.length} edge(s) but does not declare hasKinds.`,\n        );\n      }\n      return { ...b, type: \"union\", scalars: [...element.scalars] };\n    }\n\n    case \"object\": {\n      const list = byPath.get(path) ?? [];\n      if (list.length !== 1) {\n        throw new KindStorageError(\n          `object field \"${path}\" must have exactly one edge, found ${list.length}.`,\n        );\n      }\n      const [edge] = list;\n      if (!edge) {\n        throw new KindStorageError(\n          `object field \"${path}\" must have exactly one edge, found 0.`,\n        );\n      }\n      return { ...b, type: \"object\", kind: edge.childKind };\n    }\n\n    case \"array\": {\n      const list = byPath.get(path) ?? [];\n      if (list.length === 0) {\n        throw new KindStorageError(\n          `array field \"${path}\" must have at least one edge.`,\n        );\n      }\n      const itemKinds = [...list]\n        .sort((a, z) => (a.position ?? 0) - (z.position ?? 0))\n        .map((e) => e.childKind);\n      return { ...b, type: \"array\", itemKinds };\n    }\n\n    case \"inline_object\": {\n      const fields: Record<string, FieldSchema> = {};\n      for (const child of element.fields) {\n        fields[child.name] = restoreField(\n          child,\n          `${path}${PATH_SEP}${child.name}`,\n          byPath,\n        );\n      }\n      return element.open\n        ? { ...b, type: \"inline_object\", fields, open: true }\n        : { ...b, type: \"inline_object\", fields };\n    }\n  }\n}\n\n/** ADAPTER / read direction — the exact inverse of `kindSchemaToStorage`. */\nexport function storageToKindSchema(\n  kind: string,\n  shape: KindStorageShape,\n): KindSchema {\n  const byPath = indexEdges(shape.edges);\n\n  // Non-object root form: the single reserved element IS the root field.\n  const [first] = shape.data;\n  if (first && first.name === ROOT_STORAGE_NAME) {\n    if (shape.data.length !== 1) {\n      throw new KindStorageError(\n        `kind \"${kind}\": a \"${ROOT_STORAGE_NAME}\" element must be the only data element (found ${shape.data.length}).`,\n      );\n    }\n    return {\n      kind,\n      fields: {},\n      root: restoreField(first, ROOT_STORAGE_NAME, byPath),\n    };\n  }\n\n  const fields: Record<string, FieldSchema> = {};\n  for (const element of shape.data) {\n    if (element.name === ROOT_STORAGE_NAME) {\n      throw new KindStorageError(\n        `kind \"${kind}\": \"${ROOT_STORAGE_NAME}\" must be the first and only data element.`,\n      );\n    }\n    fields[element.name] = restoreField(element, element.name, byPath);\n  }\n  return { kind, fields };\n}\n","/**\n * KindSchema — the data-defined field model for a registered kind.\n *\n * `__kind` (KIND_KEY) is the carried discriminator: it is NOT part of a\n * kind's field map; the parser enforces it via `KindSchema.kind` and stamps\n * it onto every compliant snapshot.\n *\n * Moved from app/(dev)/demos/json-block-detector/kind-schemas.ts.\n *\n * 2026-07-15 expressivity extension (A2) — four constructs the Python-owned\n * pydantic schemas need that the v1 vocabulary could not express:\n *   - `{type:\"json\"}` / `{type:\"json[]\"}` — any JSON value / array of any\n *     JSON values (pydantic bare `Any` fields, `items: {}` arrays, `{}`\n *     schemas). A `json` value is implicitly nullable — `null` IS a JSON\n *     value — so `nullable` is meaningless (and ignored) on it.\n *   - `record` values widened to `\"json\"` (pydantic `dict[str, Any]` /\n *     `additionalProperties: true`).\n *   - `union` may now carry `kinds` (object unions — anyOf over kind refs,\n *     optionally mixed with scalars). Refs externalize to `kind_edge` rows\n *     exactly like `array.itemKinds`.\n *   - `KindSchema.root` — a NON-OBJECT root form: the kind's VALUE is the\n *     root field itself (scalar / array / json / open object), not a `__kind`\n *     object with fields. Root-form kinds are data-only: the streaming\n *     `__kind` parser cannot type them (a scalar cannot carry a\n *     discriminator) and refuses them loudly; validation goes through the\n *     emitted JSON Schema (ajv / Pydantic). `root` and a non-empty `fields`\n *     are mutually exclusive.\n *   - `inline_object.open` — `additionalProperties: true`; fixes the\n *     open-empty-object defect where an open `inline_object{fields:{}}`\n *     materialized as CLOSED (schema_proposal / item_presentation class).\n *\n * 2026-07-15 input-semantics extension (W3-A, agent-input bridge) — the\n * constructs the Wave-1 sufficiency survey of all 1,529 live agent variables\n * showed FieldSchema could not carry, added so `AgentVariable` ⇄ kind\n * conversion is faithful:\n *   - `FieldBase.description` — human guidance; round-trips JSON Schema\n *     `description` and VariableDefinition `helpText`.\n *   - `FieldBase.default` — the field's default VALUE (JSON Schema `default`,\n *     VariableDefinition `defaultValue`). Annotation-level: validators never\n *     apply it; emitters carry it verbatim.\n *   - `enum.open` — \"one of these options OR any string\" (the FE's\n *     `allowOther`). Emits as `anyOf: [{type:\"string\", enum}, {type:\"string\"}]`\n *     so the option set survives instead of widening to bare `string`.\n *   - `number` bounds `min`/`max`/`step` — JSON Schema\n *     `minimum`/`maximum`/`multipleOf` (number/slider components).\n *   - `string[].values` (+ `open`) — an items-enum: array of strings drawn\n *     from an option set (checkbox components), `open` meaning the set is\n *     advisory (`allowOther` on a multi-select).\n * Picklist bindings, scope bindings, and media component identity are\n * PROVENANCE, not structure — they never enter FieldSchema; the bridge\n * carries them out-of-band (see convert/kind-variable-bridge.ts sidecar).\n */\n\n/** System discriminator — hardcoded, not part of per-kind field schemas. */\nexport const KIND_KEY = \"__kind\";\n\nexport type ScalarFieldType = \"string\" | \"number\" | \"boolean\";\n\nexport type ArrayItemScalarType = \"string\" | \"number\" | \"boolean\";\n\n/** Value domain of a `record` field — typed scalars, or any JSON value. */\nexport type RecordValueType = ArrayItemScalarType | \"json\";\n\ntype FieldBase = {\n  required?: boolean;\n  nullable?: boolean;\n  /** Human guidance — JSON Schema `description` / variable `helpText`. */\n  description?: string;\n  /**\n   * Default VALUE (JSON Schema `default` / variable `defaultValue`).\n   * Annotation-level: validators never apply it; emitters carry it verbatim.\n   */\n  default?: unknown;\n};\n\nexport type FieldSchema =\n  | (FieldBase & { type: \"string\" | \"boolean\" })\n  | (FieldBase & {\n      type: \"number\";\n      /** Inclusive lower bound — JSON Schema `minimum`. */\n      min?: number;\n      /** Inclusive upper bound — JSON Schema `maximum`. */\n      max?: number;\n      /** Increment — JSON Schema `multipleOf`. Annotation-level in the parser. */\n      step?: number;\n    })\n  | (FieldBase & {\n      type: \"string[]\";\n      /** Items-enum: each item must be one of these values (checkbox option sets). */\n      values?: string[];\n      /** With `values`: the set is advisory — any string item is also legal (`allowOther`). */\n      open?: boolean;\n    })\n  | (FieldBase & { type: \"number[]\" | \"boolean[]\" })\n  | (FieldBase & { type: \"json\" })\n  | (FieldBase & { type: \"json[]\" })\n  | (FieldBase & { type: \"array\"; itemKinds: string[] })\n  | (FieldBase & { type: \"object\"; kind: string })\n  | (FieldBase & {\n      type: \"inline_object\";\n      fields: Record<string, FieldSchema>;\n      /** additionalProperties: true — unknown keys are legal, not residue-only. */\n      open?: boolean;\n    })\n  | (FieldBase & { type: \"record\"; values: RecordValueType })\n  | (FieldBase & {\n      type: \"enum\";\n      values: string[];\n      /** \"One of these OR any string\" — the option set is advisory (`allowOther`). */\n      open?: boolean;\n    })\n  | (FieldBase & {\n      type: \"union\";\n      scalars: Array<\"string\" | \"number\" | \"boolean\">;\n      /** Object union members — kind refs (anyOf of $refs), may mix with scalars. */\n      kinds?: string[];\n    });\n\n/**\n * Domain fields only — __kind is enforced by the parser via KindSchema.kind\n * (block slug). A kind with `root` set has NO field map (fields stays `{}`):\n * its value is the root field's type at the top level. See the module header.\n */\nexport type KindSchema = {\n  kind: string;\n  fields: Record<string, FieldSchema>;\n  /** Non-object root form — mutually exclusive with a non-empty `fields`. */\n  root?: FieldSchema;\n};\n\nexport function readObjectKind(value: Record<string, unknown>): string | null {\n  const kind = value[KIND_KEY];\n  return typeof kind === \"string\" ? kind : null;\n}\n\nexport function isScalarArrayType(\n  type: FieldSchema[\"type\"],\n): type is \"string[]\" | \"number[]\" | \"boolean[]\" {\n  return type === \"string[]\" || type === \"number[]\" || type === \"boolean[]\";\n}\n\nexport function scalarArrayItemType(\n  type: \"string[]\" | \"number[]\" | \"boolean[]\",\n): ArrayItemScalarType {\n  if (type === \"number[]\") return \"number\";\n  if (type === \"boolean[]\") return \"boolean\";\n  return \"string\";\n}\n\n/**\n * Does this field's value domain accept ANY JSON shape (object/array/scalar/\n * null alike)? True for `json` and `json[]` ITEMS — the parser treats the\n * subtree under such a field as opaque (no kind identification, no raw_object\n * degradation: unknown structure is the declared contract, not a failure).\n */\nexport function isJsonAnyField(field: FieldSchema): boolean {\n  return field.type === \"json\" || field.type === \"json[]\";\n}\n","/**\n * Stable, fast content fingerprint for IR envelopes.\n *\n * Used as the idempotence / cache key: a persisted CanonicalBlockIR is only\n * reused when its fingerprint matches the region source text it claims to\n * represent. Not cryptographic — collision resistance at the \"same message,\n * same block\" scale is all that's required, and it must be synchronous and\n * dependency-free (runs per region on the hot streaming path).\n *\n * FNV-1a 32-bit, applied twice with different seeds and concatenated, so a\n * single 32-bit collision doesn't alias two regions.\n *\n * `createFingerprinter` is the incremental form for live streams: feeding\n * chunks one at a time yields EXACTLY the same fingerprint as\n * `fingerprintText` over the concatenation — sessions never re-hash the\n * whole source per flush.\n */\n\nconst SEED_A = 0x811c9dc5;\nconst SEED_B = 0x01000193;\n\nfunction fnv1aStep(hash: number, input: string): number {\n  let h = hash >>> 0;\n  for (let i = 0; i < input.length; i++) {\n    h ^= input.charCodeAt(i);\n    // h *= 16777619 (FNV prime), in 32-bit space without BigInt.\n    h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;\n  }\n  return h >>> 0;\n}\n\nexport interface Fingerprinter {\n  push(chunk: string): void;\n  /** Fingerprint of everything pushed so far. */\n  current(): string;\n}\n\nexport function createFingerprinter(): Fingerprinter {\n  let a = SEED_A;\n  let b = SEED_B;\n  let length = 0;\n\n  return {\n    push(chunk: string): void {\n      a = fnv1aStep(a, chunk);\n      b = fnv1aStep(b, chunk);\n      length += chunk.length;\n    },\n    current(): string {\n      return `${length.toString(36)}-${a.toString(36)}${b.toString(36)}`;\n    },\n  };\n}\n\nexport function fingerprintText(source: string): string {\n  const hasher = createFingerprinter();\n  hasher.push(source);\n  return hasher.current();\n}\n","/**\n * The canonical IR contract for structured content.\n *\n * Every source (live agent stream, DB reload, Python-preprocessed results,\n * notes, any future surface) is normalized into these shapes exactly once.\n * Anything already carrying this IR passes through downstream layers by\n * reference — see `core/normalize.ts` for the idempotence law.\n *\n * This file is pure types + path helpers. No React, no Redux, no IO.\n */\n\n/** Path of a value inside a parsed region (object keys + array indices). */\nexport type IrPath = Array<string | number>;\n\n/**\n * How a node's kind was (or wasn't) established.\n *\n * 🚨 `unverified` IS NOT `raw`, AND THE DIFFERENCE IS LOAD-BEARING (Arman's\n * ruling, 2026-08-29). \"We checked it and it is wrong\" and \"we had nothing to\n * check it with\" are opposite facts about a payload, and collapsing them cost\n * ~221 live kinds their component overnight: a kind whose schema never loaded\n * degraded to `raw`, the render route read `raw` as \"broken instance\", and\n * perfectly valid payloads were dumped as key/value lists instead of reaching\n * the component the user built. A consumer that treats `unverified` as a\n * failure is reintroducing that outage — the data is intact and MAY be\n * entirely valid; all that is missing is the schema that would prove it.\n */\nexport type IrKindState =\n  | \"resolved\" // __kind seen + schema validated\n  | \"speculative\" // committed from parent itemKinds before __kind arrived\n  | \"pending_kind\" // object open, no __kind yet, no speculation possible\n  | \"pending_schema\" // kind known, registry cold-fetch in flight\n  | \"unverified\" // kind known, NO schema was ever available — never checked\n  | \"raw\"; // checked and FAILED, or structurally broken\n\n/**\n * System-level zero-data-loss channel. Unknown keys are NEVER merged into a\n * node's `value` (they'd be indistinguishable from schema fields); they are\n * carried here verbatim — Protobuf unknown-fields discipline. Distinct from\n * any domain-level `additionalDetails` field, which is an ordinary schema\n * field inside `value`.\n */\nexport interface IrResidue {\n  /** Keys present in the source object but absent from the kind schema. */\n  extra: Record<string, unknown> | null;\n  /** Optional schema fields the source never provided. */\n  optionalMissing: string[] | null;\n  /** Structured warnings attached during parsing (speculation backtracks, truncation, …). */\n  notices: Array<{ code: string; message: string; at?: number }> | null;\n}\n\n/** Which wire syntax carried the kind discriminator for a node. */\nexport type IrDiscriminator =\n  | { format: \"json\"; key: \"__kind\" }\n  | { format: \"xml\"; tag: string }\n  | { format: \"fence\"; language: string };\n\n/** A schema-shaped structured node. Children live inside `value` (and carry their own metadata via `nodeIndex`). */\nexport interface IrStructuredNode {\n  role: \"structured\";\n  /** Canonical kind slug. Empty string while pending. */\n  kind: string;\n  kindState: IrKindState;\n  discriminator: IrDiscriminator;\n  /** Region-relative path ([] = region root). */\n  path: IrPath;\n  status: \"streaming\" | \"complete\" | \"error\";\n  /** Compliant snapshot: schema fields + __kind ONLY. Unknown keys → residue. */\n  value: Record<string, unknown>;\n  residue: IrResidue | null;\n}\n\n/** Envelope version. Bump = migration point for persisted envelopes. */\nexport const IR_VERSION = 1 as const;\n\n/** Reserved key carrying the envelope inside RenderBlockPayload.data. */\nexport const IR_ENVELOPE_KEY = \"__ir\" as const;\n\n/**\n * One parsed region's canonical form. Serializable (plain JSON), carried on\n * render blocks (`data.__ir`), persisted on artifacts and message metadata,\n * and — with `engine: \"py-block-detector\"` — accepted pre-built from Python.\n */\nexport interface CanonicalBlockIR {\n  v: typeof IR_VERSION;\n  /** Provenance: which implementation produced this envelope. */\n  engine: \"fe-kind-parser\" | \"py-block-detector\";\n  /** Stable hash of the region source text — the idempotence / cache key. */\n  fingerprint: string;\n  root: IrStructuredNode;\n  /**\n   * pathKey → node metadata for per-path readers (child kinds under root).\n   * Carries each child node's residue — child snapshot values inside\n   * `root.value` hold schema fields only, so WITHOUT this the envelope would\n   * silently drop nested unknown keys (zero-data-loss violation).\n   */\n  nodeIndex?: Record<\n    string,\n    Pick<IrStructuredNode, \"kind\" | \"kindState\" | \"status\"> & {\n      residue?: IrResidue | null;\n    }\n  >;\n}\n\n/** Normalizer output segment: prose stays raw text; structured regions carry IR. */\nexport type CanonicalSegment =\n  | { role: \"text\"; content: string }\n  | {\n      role: \"block\";\n      blockType: string;\n      content: string;\n      ir: CanonicalBlockIR | null;\n    };\n\nexport interface CanonicalContent {\n  v: typeof IR_VERSION;\n  segments: CanonicalSegment[];\n}\n\n// ---------------------------------------------------------------------------\n// Path helpers — the ONE implementation. Consumers must not roll their own.\n// ---------------------------------------------------------------------------\n\nexport function irPathKey(path: IrPath): string {\n  return path.map((segment) => String(segment)).join(\".\");\n}\n\nexport function irPathsEqual(left: IrPath, right: IrPath): boolean {\n  if (left.length !== right.length) return false;\n  for (let i = 0; i < left.length; i++) {\n    if (left[i] !== right[i]) return false;\n  }\n  return true;\n}\n\nexport function irPathIsUnderOrEqual(path: IrPath, prefix: IrPath): boolean {\n  if (path.length < prefix.length) return false;\n  for (let i = 0; i < prefix.length; i++) {\n    if (path[i] !== prefix[i]) return false;\n  }\n  return true;\n}\n\n/** Human label for a path (\"root\", \"cards[2].front\"). */\nexport function irPathLabel(path: IrPath): string {\n  if (path.length === 0) return \"root\";\n\n  const parts: string[] = [];\n  for (const segment of path) {\n    if (typeof segment === \"number\") {\n      parts[parts.length - 1] += `[${segment}]`;\n    } else {\n      parts.push(String(segment));\n    }\n  }\n  return parts.join(\".\");\n}\n\n/** True when every residue channel is empty — normalize to null instead. */\nexport function isEmptyResidue(residue: IrResidue): boolean {\n  return (\n    (residue.extra === null || Object.keys(residue.extra).length === 0) &&\n    (residue.optionalMissing === null ||\n      residue.optionalMissing.length === 0) &&\n    (residue.notices === null || residue.notices.length === 0)\n  );\n}\n","/**\n * Idempotent normalizer — the \"recognizes its own work\" property.\n *\n * THE LAW: anything already carrying a current CanonicalBlockIR envelope is\n * returned BY REFERENCE — zero reprocessing, reference equality holds, React\n * bails out. Only raw text (a detected region's source) is ever parsed, and\n * it is parsed exactly once per fingerprint.\n *\n * `normalizeJsonRegion` is the one-shot mode: the same KindStreamParser that\n * powers live streams, run over a complete region string (DB reloads,\n * reconcile passes), assembled through the same IrTree the live session uses\n * — stream and static output are structurally identical by construction.\n */\n\nimport { fingerprintText } from \"./fingerprint\";\nimport {\n  IR_VERSION,\n  type CanonicalBlockIR,\n  type IrDiscriminator,\n  type IrStructuredNode,\n} from \"./ir-types\";\nimport { KIND_KEY, type KindSchema } from \"./kind-schema.types\";\nimport { IrTree } from \"./ir-tree\";\nimport {\n  createKindStreamParser,\n  type SchemaResolver,\n} from \"./kind-parser\";\n\nexport function isCanonicalBlockIR(value: unknown): value is CanonicalBlockIR {\n  if (typeof value !== \"object\" || value === null) return false;\n  const candidate = value as Partial<CanonicalBlockIR>;\n  return (\n    candidate.v === IR_VERSION &&\n    typeof candidate.fingerprint === \"string\" &&\n    typeof candidate.engine === \"string\" &&\n    typeof candidate.root === \"object\" &&\n    candidate.root !== null &&\n    (candidate.root as IrStructuredNode).role === \"structured\"\n  );\n}\n\n/**\n * The idempotence fast path: return the existing envelope by reference when\n * it still describes this source text; null means \"parse needed\".\n */\nexport function reuseEnvelopeIfCurrent(\n  source: string,\n  candidate: unknown,\n): CanonicalBlockIR | null {\n  if (!isCanonicalBlockIR(candidate)) return null;\n  return candidate.fingerprint === fingerprintText(source) ? candidate : null;\n}\n\nexport interface NormalizeJsonRegionOptions {\n  schemas: Record<string, KindSchema> | SchemaResolver;\n  /** Known-context root prediction (agent output schema, fence hint). */\n  expectedRootKind?: string;\n  /**\n   * Pass a previously persisted envelope (message metadata, artifact row);\n   * when its fingerprint matches, it is returned as-is and nothing parses.\n   */\n  existing?: unknown;\n}\n\nexport interface CompleteValueEnvelopeOptions {\n  /**\n   * Wire discriminator recorded on the root node — which syntax established\n   * the kind. Defaults to the JSON `__kind` key; XML surfaces converging at\n   * region finalize pass `xmlDiscriminator(tag)` so round-trip serializers\n   * know the original arrival format.\n   */\n  discriminator?: IrDiscriminator;\n}\n\n/**\n * Build a resolved, complete envelope directly from an already-structured\n * value (a persisted artifact's `content.data` object, or a completed XML\n * region's strategy output). This is the zero-reprocessing rehydration path:\n * the value IS the reconstructed region value (schema fields + residue extras\n * merged at persist time), so no tokenizer/parser run is needed — the\n * envelope wraps it verbatim. The fingerprint hashes the canonical value\n * serialization, so any two paths producing the same value produce the SAME\n * envelope (stream ≡ static by construction).\n */\nexport function envelopeFromCompleteValue(\n  value: Record<string, unknown>,\n  kind: string,\n  options?: CompleteValueEnvelopeOptions,\n): CanonicalBlockIR {\n  return {\n    v: IR_VERSION,\n    engine: \"fe-kind-parser\",\n    fingerprint: fingerprintText(JSON.stringify(value)),\n    root: {\n      role: \"structured\",\n      kind,\n      kindState: \"resolved\",\n      discriminator: options?.discriminator ?? { format: \"json\", key: KIND_KEY },\n      path: [],\n      status: \"complete\",\n      value,\n      residue: null,\n    },\n  };\n}\n\n/** One-shot: complete region text in → canonical envelope out. */\nexport function normalizeJsonRegion(\n  source: string,\n  options: NormalizeJsonRegionOptions,\n): CanonicalBlockIR {\n  const reused = reuseEnvelopeIfCurrent(source, options.existing);\n  if (reused) return reused;\n\n  const tree = new IrTree();\n  const parser = createKindStreamParser({\n    schemas: options.schemas,\n    ...(options.expectedRootKind !== undefined && {\n      expectedRootKind: options.expectedRootKind,\n    }),\n    onEvent(event) {\n      tree.applyEvent(event);\n    },\n  });\n  parser.push(source);\n  parser.end();\n\n  return tree.buildEnvelope(fingerprintText(source));\n}\n","/**\n * The dual gate — Arman's law as executable code: a kind is only `is_active`\n * when its canonical `sample_data` passes BOTH systems.\n *\n *   1. Structural (Pydantic): the sample validates against the kind's\n *      `emitted_json_schema`. Python's Pydantic is the AUTHORITATIVE owner of\n *      this leg, but it reads the SAME materialized `emitted_json_schema` — so\n *      this TS ajv check and the Python check validate the same sample against\n *      the same schema and agree by construction. A disagreement IS the\n *      screamer (a schema Pydantic can't express, or an ajv/Pydantic gap).\n *   2. Render (UI): the sample lights up the kind's real component. TS is the\n *      AUTHORITATIVE owner of this leg. It is a PROXY for a DOM render, not a\n *      DOM render. Exactly what it checks, and nothing more:\n *        · the kind has something to render with (`legacyBlockType` or\n *          `component`);\n *        · for BRIDGED kinds, `toLegacyServerData(sample)` returns a plain\n *          object that is SEMANTICALLY non-empty — see\n *          `describeUnrenderableBridgeOutput` for the exact predicate;\n *        · BRIDGELESS kinds pass with a recorded caveat — nothing is verified.\n *\n *      This catches the 2026-07-04 \"No flashcards available yet\" class: a\n *      bridge that returns `undefined`, `{}`, `{language:\"json\"}` (the raw\n *      code-region annotation), or an object whose every value is empty.\n *\n *      What it does NOT do — stated plainly, because a gate that overclaims is\n *      worse than no gate: it does not mount the component, and it cannot know\n *      WHICH key carries the payload. `{title:\"Cell Biology\", cards:[]}` passes\n *      this leg on `title` alone. Proving the payload key is populated needs\n *      per-kind knowledge the gate deliberately does not have; a DOM-level\n *      render check is the deeper leg, deferred to an RTL harness.\n *\n * Both legs necessary, neither sufficient. Fail either → `isActive: false` and\n * the caller reports it loudly (Error Inspector, `content-ir`) and holds the\n * row out of production. This module is PURE (deps injected) so it runs in the\n * harness, in CI, and in a browser author-save alike.\n *\n * Ownership split (the 2026-07-05 kind-registry storage design, since deleted; the live contract is the code below): the caller writes the outcome\n * to the LIVE `content_ir.kind_definition` row's `is_active`; the canonical\n * `_version_capture` trigger snapshots that state into `history.row_versions`\n * (never a post-hoc history mutation).\n */\n\nimport Ajv, { type ValidateFunction } from \"ajv\";\nimport type { CanonicalBlockIR } from \"../core/ir-types\";\nimport { KIND_KEY } from \"../core/kind-schema.types\";\nimport { envelopeFromCompleteValue } from \"../core/normalize\";\n\n/** The facets the render leg needs — a structural subset of KindDefinition. */\nexport interface DualGateDefinition {\n  legacyBlockType?: string;\n  toLegacyServerData?: (\n    envelope: CanonicalBlockIR,\n  ) => Record<string, unknown> | undefined;\n  component?: { load: () => Promise<unknown> };\n}\n\n/**\n * The render leg's second satisfier: an ACTIVE `role='output'` component\n * resolved from `content_ir.kind_component`. Feed this from\n * `resolveComponent(kind, \"web\", \"output\")`.\n *\n * Why this exists: the render leg originally consulted only the compiled TS\n * registry, so an agent-authored kind whose renderer is a `source='db'` row was\n * structurally unable to pass — `definition` came back null and the gate said\n * \"no component\" about a kind that had a live, working one. Six authored kinds\n * (wine_tasting, employee_card, employee_roster, employee_of_the_week,\n * flashcard_deck, arman_video_prompt) sat permanently inactive because of it.\n *\n * NOT a mirror of `content_ir.evaluate_kind_activation`. The SQL render leg is\n * presence-only — it checks that an active `role='output'` row exists, because\n * SQL cannot execute a TypeScript bridge. THIS leg is strictly stronger: for a\n * compiled kind it also runs `toLegacyServerData` and rejects semantically\n * empty output (the \"No <kind> available\" class).\n *\n * The asymmetry is deliberate and bounded: SQL is the FLOOR (necessary, and\n * sufficient for DB-authored components, which own no bridge), while this leg\n * is the CEILING for compiled kinds. Consequence to know: activating a COMPILED\n * kind whose bridge is broken would pass the RPC and fail here. Compiled kinds\n * are activated by developers through `scripts/shape/activate-kinds.ts`, which\n * runs this leg — the studio control only ever reaches owner-authored kinds.\n * If that ever stops being true, the browser control must run this gate before\n * enabling its button.\n */\nexport interface DualGateResolvedComponent {\n  componentKey: string;\n  /** The row's own render-trust verdict (R6). Inactive rows do not satisfy. */\n  isActive: boolean;\n  /** \"bundled\" | \"db\" — reported in the leg detail, never gates the verdict. */\n  source: string;\n}\n\n/**\n * THE FALLBACK IS NOT A COMPONENT (Arman, 2026-08-23). MUST equal\n * `GENERIC_STRUCTURED_COMPONENT_KEY` (../react/kind-route) and\n * `content_ir.evaluate_kind_activation`'s render leg. Duplicated rather than\n * imported: this registry module must not pull in the react layer.\n */\nconst GENERIC_FALLBACK_COMPONENT_KEY = \"generic_structured\";\n\n/**\n * A resolved component SATISFIES the render leg only when it is active AND is\n * not the generic fallback.\n *\n * `resolveComponent(kind, \"web\", \"output\")` ALWAYS answers — the platform\n * guarantees a kind can never fail to render, so it falls back to\n * `generic_structured`. Feeding that answer straight in (KindGateTab.tsx does)\n * made the render leg pass for every kind ever built, including kinds whose\n * only \"component\" is the key/value dump: an unfalsifiable green\n * (conversion-campaigns.md § Law 4b). The gate's own detail string was\n * literally printing `resolved bundled component \"generic_structured\"` as the\n * reason it passed.\n */\nfunction satisfies(resolved?: DualGateResolvedComponent | null): boolean {\n  return Boolean(\n    resolved?.isActive &&\n      resolved.componentKey !== GENERIC_FALLBACK_COMPONENT_KEY,\n  );\n}\n\nexport interface DualGateInput {\n  kind: string;\n  /** The canonical instance (kind_definition.sample_data). */\n  sample: Record<string, unknown>;\n  /** The materialized kind_definition.emitted_json_schema (plain, no __kind). */\n  emittedJsonSchema: unknown;\n  /** The registry definition for the kind (or null when unregistered). */\n  definition: DualGateDefinition | null;\n  /**\n   * The resolver's `(kind, web, output)` answer, when the caller has one.\n   * Omit (or pass null) to check the compiled registry alone.\n   */\n  resolvedComponent?: DualGateResolvedComponent | null;\n  /**\n   * True when the kind is a generated data-only contract\n   * (`metadata.family` ∈ workflow_io | tool_io | action_io | agent_io).\n   * Those are passed between nodes and never rendered, so the render leg is\n   * structurally inapplicable — the same `n/a` doctrine the shape doctor uses.\n   * Failing them would be noise, and noise erodes the gate.\n   */\n  dataOnly?: boolean;\n}\n\nexport interface LegResult {\n  ok: boolean;\n  detail?: string;\n}\n\nexport interface DualGateResult {\n  /** True only when BOTH legs pass — the value the caller writes to is_active. */\n  isActive: boolean;\n  structural: LegResult;\n  render: LegResult;\n}\n\n// ajv authoring-strictness is OFF (tolerate provider schema keywords like the\n// recursive \"#\" root ref); DATA strictness comes from the schema itself\n// (additionalProperties:false + required), which ajv enforces during validate.\n// Built on first validation, never at import: a module-level `new Ajv()` is a side effect that keeps\n// ajv (~35 kB gzip) on every importer's first screen (chat reads the root for envelopes only).\nlet ajvInstance: Ajv | undefined;\nfunction getAjv(): Ajv {\n  return (ajvInstance ??= new Ajv({ allErrors: true, strict: false }));\n}\n\n/**\n * BACKWARD-COMPATIBILITY TOLERANCE ONLY — never the contract.\n *\n * This existed because `emitted_json_schema` was the marker-free \"wire\" export:\n * the dead doctrine held that `__kind` was envelope framing injected at emit\n * time, so a sample had to be stripped to validate. That doctrine is GONE\n * (Arman, 2026-08-23): every kind schema now DECLARES `__kind` at every object\n * position — const + required where the kind is known — so a marked sample\n * validates AS-IS and stripping it is not a no-op, it is a FAILURE\n * (`must have required property '__kind'`).\n *\n * So the strip is a SECOND ATTEMPT, never the first one: the leg validates the\n * caller's value verbatim, and only if that fails retries a marker-free LOCAL\n * copy, so a row still pinned to a pre-2026-08-23 marker-free schema keeps\n * validating while it is repinned. The caller's value is never touched. Delete\n * it once no live row pins a marker-free version. KINDS_EVERYWHERE_PLAN §4.2.\n */\nfunction stripKind(value: unknown): unknown {\n  if (Array.isArray(value)) return value.map(stripKind);\n  if (value && typeof value === \"object\") {\n    const out: Record<string, unknown> = {};\n    for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n      if (k === KIND_KEY) continue;\n      out[k] = stripKind(v);\n    }\n    return out;\n  }\n  return value;\n}\n\nfunction describeAjvErrors(errors: ValidateFunction[\"errors\"]): string[] {\n  return (errors ?? [])\n    .map((e) => `${e.instancePath || \"(root)\"} ${e.message ?? \"\"}`.trim())\n    .slice(0, 8);\n}\n\n/** True when the root schema declares the `__kind` marker as a property. */\nfunction schemaDeclaresKind(emittedJsonSchema: unknown): boolean {\n  if (!emittedJsonSchema || typeof emittedJsonSchema !== \"object\") return false;\n  const properties = (emittedJsonSchema as Record<string, unknown>).properties;\n  return (\n    !!properties &&\n    typeof properties === \"object\" &&\n    KIND_KEY in (properties as Record<string, unknown>)\n  );\n}\n\n/**\n * The structural leg, exported on its own so the shape doctor\n * (`shape-doctor.ts`) RECOMPUTES gate validation with the exact same ajv\n * config + marker semantics as activation (verbatim first, marker-free retry\n * second) — never a parallel validator. `sample` is `unknown` (not `Record`) because kind examples may\n * legitimately be scalars/arrays (workflow I/O kinds like `text`/`number`).\n */\nexport function validateStructuralLeg(\n  sample: unknown,\n  emittedJsonSchema: unknown,\n): LegResult {\n  let validate: ValidateFunction;\n  try {\n    validate = getAjv().compile(emittedJsonSchema as object);\n  } catch (err) {\n    return {\n      ok: false,\n      detail: `emitted_json_schema failed to compile: ${\n        err instanceof Error ? err.message : String(err)\n      }`,\n    };\n  }\n  // The marker is DATA: validate exactly what the caller holds. Only if that\n  // fails do we retry the marker-free reduction, for a value still pinned to a\n  // pre-2026-08-23 schema that never declared `__kind` (see `stripKind`).\n  if (validate(sample)) return { ok: true };\n  const markedErrors = describeAjvErrors(validate.errors);\n  if (validate(stripKind(sample))) return { ok: true };\n  const strippedErrors = describeAjvErrors(validate.errors);\n\n  // Report the attempt that matches the schema in hand, so the message names\n  // the real defect instead of the fallback's collateral damage.\n  const errors = schemaDeclaresKind(emittedJsonSchema)\n    ? markedErrors\n    : strippedErrors;\n  return { ok: false, detail: `sample failed schema: ${errors.join(\"; \")}` };\n}\n\n/**\n * Keys a bridge may emit that carry NO kind content — pure region annotation.\n *\n * `language` is the sole member, and it is here because of a real, shipped bug.\n * `StreamBlockAccumulator.buildBlockData()` emits `data: { language: \"json\" }`\n * for an UNTYPED code region (a bare ```json fence), and\n * `render-block-to-content-block.ts` maps `rb.data` → `block.serverData`. That\n * annotation therefore arrives downstream as a TRUTHY `serverData` holding zero\n * kind data. On 2026-07-04 it reached the flashcards component in place of\n * `cards` and rendered \"No flashcards available yet\" (see `react/kind-route.ts`,\n * which now REPLACES or CLEARS it rather than forwarding it).\n *\n * This list only removes keys from the \"is anything substantive here?\" tally —\n * it never fails a bridge on its own. A kind whose serverData is\n * `{ language: \"python\", code: \"...\" }` still passes, on `code`. Only a bridge\n * whose ENTIRE output is annotation has produced nothing renderable.\n *\n * Add a key here only with evidence that the region-annotation path emits it and\n * that it can never itself be kind content.\n */\nconst SERVER_DATA_ANNOTATION_KEYS: ReadonlySet<string> = new Set([\"language\"]);\n\n/** serverData is JSON-shaped; this only guards pathological/cyclic nesting. */\nconst SUBSTANCE_DEPTH_LIMIT = 8;\n\n/**\n * Is `value` real content that a component could render?\n *\n *   string  → non-empty after trim    (\"\" and \"   \" are not content)\n *   number  → any finite number       (0 IS content: `completedItems: 0`)\n *   boolean → always                  (false IS content: `isComplete: false`)\n *   array   → ≥1 substantive ELEMENT  ([] and [\"\"] are not content)\n *   object  → ≥1 substantive VALUE    ({} and {a:\"\"} are not content)\n *   null | undefined | NaN | function | symbol | bigint → never content\n *\n * Recursive by design: `{ data: { items: [] } }` is structurally present and\n * semantically empty, and telling those two apart is this leg's entire job.\n */\nfunction isSubstantiveValue(value: unknown, depth = 0): boolean {\n  if (value === null || value === undefined) return false;\n  if (typeof value === \"string\") return value.trim().length > 0;\n  if (typeof value === \"number\") return Number.isFinite(value);\n  if (typeof value === \"boolean\") return true;\n  // Deep AND present — stop descending rather than claim it is empty.\n  if (depth >= SUBSTANCE_DEPTH_LIMIT) return true;\n  if (Array.isArray(value)) {\n    return value.some((entry) => isSubstantiveValue(entry, depth + 1));\n  }\n  if (typeof value === \"object\") {\n    return Object.values(value as Record<string, unknown>).some((entry) =>\n      isSubstantiveValue(entry, depth + 1),\n    );\n  }\n  return false;\n}\n\n/**\n * The render leg's real predicate: why is this bridge output NOT renderable?\n * Returns a specific reason, or `null` when the output is genuinely renderable.\n *\n * `serverData` is typed `unknown` on purpose — the facet's declared return type\n * is a promise the gate must not take on faith; a bridge is ordinary code that\n * can return anything at runtime.\n *\n * Renderable ⇔ a non-null, non-array object with at least one key that is not\n * pure annotation AND whose value is substantive (see `isSubstantiveValue`).\n */\nfunction describeUnrenderableBridgeOutput(serverData: unknown): string | null {\n  if (serverData === undefined || serverData === null) {\n    return \"bridge returned no serverData (undefined)\";\n  }\n  if (typeof serverData !== \"object\") {\n    return `bridge returned a non-object serverData (${typeof serverData})`;\n  }\n  if (Array.isArray(serverData)) {\n    return \"bridge returned an array, not a serverData record\";\n  }\n\n  const record = serverData as Record<string, unknown>;\n  const keys = Object.keys(record);\n  if (keys.length === 0) return \"bridge returned an empty object ({})\";\n\n  const contentKeys = keys.filter((key) => !SERVER_DATA_ANNOTATION_KEYS.has(key));\n  if (contentKeys.length === 0) {\n    return `bridge returned only annotation keys [${keys.join(\", \")}] — that is the raw code-region annotation, not kind data`;\n  }\n  if (!contentKeys.some((key) => isSubstantiveValue(record[key]))) {\n    return `bridge returned serverData whose every content value is empty (keys: ${contentKeys.join(\", \")}) — structurally present, semantically empty`;\n  }\n  return null;\n}\n\nfunction validateRender(\n  kind: string,\n  sample: Record<string, unknown>,\n  definition: DualGateDefinition | null,\n  resolvedComponent?: DualGateResolvedComponent | null,\n  dataOnly?: boolean,\n): LegResult {\n  // Data-only contract kinds are never rendered — the leg is n/a, not failed.\n  if (dataOnly) {\n    return {\n      ok: true,\n      detail:\n        \"data-only contract kind — render leg is structurally inapplicable (n/a)\",\n    };\n  }\n\n  // ORDER IS LOAD-BEARING. The compiled-bridge check below is the STRONGEST\n  // satisfier — it actually exercises the bridge and catches the\n  // \"No <kind> available\" class (the 2026-07-04 flashcards regression). Every\n  // compiled kind also owns a `source='bundled'` kind_component row, so\n  // checking `resolvedComponent` first would short-circuit past the bridge for\n  // exactly the kinds that guard protects, silently disabling it. The resolved\n  // component is therefore the LAST resort, not the first.\n  // \"Only the fallback resolved\" is a DIFFERENT repair from \"nothing resolved\"\n  // (author a component AND retire the decoy vs. just author one), so the\n  // detail says which — mirroring evaluate_kind_activation's two branches.\n  const onlyFallback =\n    resolvedComponent?.isActive &&\n    resolvedComponent.componentKey === GENERIC_FALLBACK_COMPONENT_KEY;\n  const noComponentDetail = onlyFallback\n    ? `the only active role='output' component for kind \"${kind}\" is ` +\n      `'${GENERIC_FALLBACK_COMPONENT_KEY}' — that IS the generic viewer, i.e. no ` +\n      `component. A reader would get a key/value dump. Author a real ` +\n      `source='db' component (or register a compiled one), then retire the ` +\n      `generic row.`\n    : null;\n\n  if (!definition && !satisfies(resolvedComponent)) {\n    return {\n      ok: false,\n      detail:\n        noComponentDetail ??\n        `kind \"${kind}\" has no component (not in the compiled registry, and no active role='output' kind_component row) — nothing to render`,\n    };\n  }\n\n  if (\n    definition &&\n    !definition.legacyBlockType &&\n    !definition.component &&\n    !definition.toLegacyServerData &&\n    !satisfies(resolvedComponent)\n  ) {\n    return {\n      ok: false,\n      detail:\n        noComponentDetail ??\n        `kind \"${kind}\" has no component (no compiled legacyBlockType/component facet, and no active role='output' kind_component row) — nothing to render`,\n    };\n  }\n\n  // Bridged kinds: the bridge MUST derive real serverData from the sample.\n  if (definition?.toLegacyServerData) {\n    let serverData: Record<string, unknown> | undefined;\n    try {\n      serverData = definition.toLegacyServerData(\n        envelopeFromCompleteValue(sample, kind),\n      );\n    } catch (err) {\n      return {\n        ok: false,\n        detail: `toLegacyServerData threw: ${\n          err instanceof Error ? err.message : String(err)\n        }`,\n      };\n    }\n    const problem = describeUnrenderableBridgeOutput(serverData);\n    if (problem) {\n      return {\n        ok: false,\n        detail: `${problem} (the \"No ${kind} available\" failure)`,\n      };\n    }\n    return { ok: true };\n  }\n\n  // Bridgeless kinds parse their own content — the bridge-data proxy can't\n  // verify them; a full DOM render check is the deeper leg (deferred to an RTL\n  // harness). Pass with a recorded caveat so it's never silently \"fully gated\",\n  // and name the satisfier so a reader can tell a compiled bridgeless component\n  // from a DB-authored one without re-deriving it.\n  const satisfier = definition?.legacyBlockType\n    ? `compiled component \"${definition.legacyBlockType}\"`\n    : definition?.component\n      ? \"compiled component facet\"\n      : satisfies(resolvedComponent) && resolvedComponent\n        ? `resolved ${resolvedComponent.source} component \"${resolvedComponent.componentKey}\"`\n        : \"component\";\n  return {\n    ok: true,\n    detail: `bridgeless kind — ${satisfier} parses content itself; full DOM render check deferred to an RTL harness`,\n  };\n}\n\nexport function runKindDualGate(input: DualGateInput): DualGateResult {\n  const structural = validateStructuralLeg(input.sample, input.emittedJsonSchema);\n  const render = validateRender(\n    input.kind,\n    input.sample,\n    input.definition,\n    input.resolvedComponent,\n    input.dataOnly,\n  );\n  return { isActive: structural.ok && render.ok, structural, render };\n}\n\n/**\n * One-line, Error-Inspector-ready reason for a failed gate (empty string when\n * it passed). The caller feeds this to `captureError({ source: \"content-ir\" })`\n * and sets `is_active=false`.\n */\nexport function describeDualGateFailure(\n  kind: string,\n  result: DualGateResult,\n): string {\n  if (result.isActive) return \"\";\n  const parts: string[] = [];\n  if (!result.structural.ok) {\n    parts.push(`structural(Pydantic): ${result.structural.detail ?? \"failed\"}`);\n  }\n  if (!result.render.ok) {\n    parts.push(`render(UI): ${result.render.detail ?? \"failed\"}`);\n  }\n  return `kind \"${kind}\" failed the dual gate — ${parts.join(\" | \")}`;\n}\n","/**\n * Kind validation behind a schema-source port (Matrx Alchemy ALC-13).\n *\n * `createKindValidator(source)` answers the one-call question \"is this value a\n * valid X?\" for a caller holding a kind SLUG and a payload, and nothing else —\n * an agent result, a surface write, an import. The HOST supplies the schema\n * through `SchemaSourcePort` (the browser reads `content_ir.kind_definition`\n * through Supabase; a server or a test hands in whatever it holds). This\n * package never imports a database client.\n *\n * ── A skip is never a pass ──────────────────────────────────────────────────\n *\n * `checked` is reported separately from `ok`, mirroring Python's `KindCheck`\n * (`matrx_graph/kinds.py`) and using the SAME degraded-reason vocabulary, so\n * the two runtimes describe the same failure the same way. A caller that reads\n * only `ok` gets `false` when the check could not run — the safe direction.\n *\n * Validation itself delegates to `validateStructuralLeg` — the activation\n * gate's own leg — so this is never a parallel validator. One ajv config, one\n * marker rule, one answer.\n *\n * Deliberately NOT reported here: `kind_definition.is_active`. That is a\n * RENDER-trust verdict, not a statement about the contract — an inactive\n * kind's schema is perfectly checkable.\n *\n * State: each validator owns its own short-lived schema cache (instance state,\n * never module state), so two hosts in one graph never share or poison a cache.\n */\n\nimport { validateStructuralLeg } from \"./kind-dual-gate\";\n\n/** JSON as the schema source hands it over. */\nexport type Json =\n  | null\n  | boolean\n  | number\n  | string\n  | Json[]\n  | { [key: string]: Json };\n\n/**\n * Why a schema could not be had, or could not be used. Identical to Python's\n * `KindDegradedReason` (`matrx_graph/kinds.py`) minus `kind_inactive`.\n */\nexport type SchemaUnavailableReason =\n  | \"kind_not_registered\"\n  | \"schema_unavailable\"\n  | \"schema_invalid\"\n  | \"catalog_unreachable\";\n\n/**\n * The host's schema source. Implemented ONCE per host (the browser app reads\n * the kind catalog; a test hands in a fixture).\n *\n * Contract:\n *  - `{ schema, version }` when the kind is registered and carries an emitted\n *    JSON Schema;\n *  - `{ unavailable: \"kind_not_registered\" }` when no live kind has that slug;\n *  - `{ unavailable: \"schema_unavailable\" }` when the kind has no schema;\n *  - `{ unavailable: \"catalog_unreachable\" }` when the catalog could not be\n *    read. A source that THROWS is treated the same way by the validator.\n *  - `schema_invalid` is normally decided by the validator (the schema does not\n *    compile); a source may also report it when it knows the stored schema is\n *    malformed.\n */\nexport interface SchemaSourcePort {\n  kindSchema(\n    kindKey: string,\n    signal: AbortSignal,\n  ): Promise<\n    | { schema: Json; version: string }\n    | { unavailable: SchemaUnavailableReason }\n  >;\n}\n\nexport interface KindValidationResult {\n  kind: string;\n  /** False when the check could not run at all. A skip is NEVER a pass. */\n  checked: boolean;\n  /** True only when `checked` AND the value satisfied the schema. */\n  ok: boolean;\n  /** ajv messages, or a single explanatory line when the check was skipped. */\n  errors: string[];\n  /** Non-null exactly when `checked === false`. */\n  degradedReason: SchemaUnavailableReason | null;\n}\n\nexport interface KindValidator {\n  /**\n   * Validate `value` against the live contract for `kind`. Never throws for an\n   * unknown kind, a missing schema or an unreachable catalog — those are\n   * degraded verdicts, because a thrown error at a validation boundary tends\n   * to be caught and swallowed into a silent pass. A malformed argument (an\n   * empty kind) still throws.\n   */\n  validate(\n    value: unknown,\n    kind: string,\n    signal?: AbortSignal,\n  ): Promise<KindValidationResult>;\n  /**\n   * The cached schema for `kind`, or `null` when it cannot be had. Never\n   * throws. For callers that SHOW the contract (a tool spec summarizing a\n   * target's schema) without paying a second read for a contract `validate`\n   * is about to fetch anyway. Same cache, same TTL.\n   */\n  cachedSchema(kind: string, signal?: AbortSignal): Promise<Json | null>;\n  /** Drop one kind's cached schema, or all of them. Call after a local write. */\n  invalidate(kind?: string): void;\n}\n\nexport interface KindValidatorOptions {\n  /**\n   * How long a fetched schema is reused. Schema reads are a network hop and\n   * validation runs in loops, but a definition edit bumps its version and\n   * must be picked up without a reload. Default 30 s.\n   */\n  cacheTtlMs?: number;\n  /** Clock, injectable for tests. Default `Date.now`. */\n  now?: () => number;\n}\n\n/** The exact prefix `validateStructuralLeg` uses when ajv cannot compile the\n * schema. A reword there must surface as a test failure here rather than\n * silently reclassify a registry defect as invalid user data. */\nconst SCHEMA_COMPILE_FAILURE_PREFIX = \"emitted_json_schema failed to compile:\";\n\nconst DEFAULT_CACHE_TTL_MS = 30_000;\n\nfunction unavailableMessage(\n  kind: string,\n  reason: SchemaUnavailableReason,\n  detail?: string,\n): string {\n  switch (reason) {\n    case \"kind_not_registered\":\n      return `kind \"${kind}\" is not registered in content_ir.kind_definition`;\n    case \"schema_unavailable\":\n      return `kind \"${kind}\" has no emitted_json_schema — nothing to validate against`;\n    case \"schema_invalid\":\n      return `kind \"${kind}\" has an uncompilable emitted_json_schema${\n        detail ? `: ${detail}` : \"\"\n      }`;\n    case \"catalog_unreachable\":\n      return `could not read the contract for kind \"${kind}\"${\n        detail ? `: ${detail}` : \"\"\n      }`;\n  }\n}\n\nfunction degraded(\n  kind: string,\n  reason: SchemaUnavailableReason,\n  detail?: string,\n): KindValidationResult {\n  return {\n    kind,\n    checked: false,\n    ok: false,\n    errors: [unavailableMessage(kind, reason, detail)],\n    degradedReason: reason,\n  };\n}\n\ntype Fetched =\n  | { schema: Json; version: string }\n  | { unavailable: SchemaUnavailableReason; detail?: string };\n\n/** Build a validator over one host's schema source. */\nexport function createKindValidator(\n  source: SchemaSourcePort,\n  options: KindValidatorOptions = {},\n): KindValidator {\n  const ttl = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n  const now = options.now ?? Date.now;\n  const cache = new Map<\n    string,\n    { schema: Json; version: string; fetchedAt: number }\n  >();\n\n  async function fetchSchema(\n    kind: string,\n    signal: AbortSignal,\n  ): Promise<Fetched> {\n    const cached = cache.get(kind);\n    if (cached && now() - cached.fetchedAt <= ttl) {\n      return { schema: cached.schema, version: cached.version };\n    }\n    let answer: Awaited<ReturnType<SchemaSourcePort[\"kindSchema\"]>>;\n    try {\n      answer = await source.kindSchema(kind, signal);\n    } catch (err) {\n      return {\n        unavailable: \"catalog_unreachable\",\n        detail: err instanceof Error ? err.message : String(err),\n      };\n    }\n    if (\"unavailable\" in answer) return { unavailable: answer.unavailable };\n    // A source that answers \"available\" with no schema still has nothing to\n    // check against — the same verdict as the source saying so.\n    if ((answer.schema as unknown) == null) {\n      return { unavailable: \"schema_unavailable\" };\n    }\n    cache.set(kind, {\n      schema: answer.schema,\n      version: answer.version,\n      fetchedAt: now(),\n    });\n    return answer;\n  }\n\n  return {\n    async validate(value, kind, signal = new AbortController().signal) {\n      if (!kind || typeof kind !== \"string\") {\n        throw new TypeError(\n          `validateAgainstKind: \"kind\" must be a non-empty slug (received ${typeof kind})`,\n        );\n      }\n      const fetched = await fetchSchema(kind, signal);\n      if (\"unavailable\" in fetched) {\n        return degraded(kind, fetched.unavailable, fetched.detail);\n      }\n\n      const leg = validateStructuralLeg(value, fetched.schema);\n\n      // `validateStructuralLeg` reports an uncompilable schema through the\n      // same `ok:false` channel as invalid data. Separate them: a broken\n      // schema is a registry defect the caller must not read as \"your data is\n      // wrong\".\n      if (!leg.ok && leg.detail?.startsWith(SCHEMA_COMPILE_FAILURE_PREFIX)) {\n        return degraded(kind, \"schema_invalid\", leg.detail);\n      }\n\n      return {\n        kind,\n        checked: true,\n        ok: leg.ok,\n        errors: leg.ok ? [] : [leg.detail ?? \"validation failed\"],\n        degradedReason: null,\n      };\n    },\n\n    async cachedSchema(kind, signal = new AbortController().signal) {\n      const fetched = await fetchSchema(kind, signal);\n      return \"unavailable\" in fetched ? null : fetched.schema;\n    },\n\n    invalidate(kind) {\n      if (kind) cache.delete(kind);\n      else cache.clear();\n    },\n  };\n}\n","/** Generated from matrx-graph's canonical Python KIND_DISPOSITIONS tuple. */\nexport const KIND_DISPOSITIONS = [\n  \"record\",\n  \"envelope\",\n  \"receipt\",\n  \"proposal\",\n  \"prose\",\n] as const;\n\nexport type KindDisposition = (typeof KIND_DISPOSITIONS)[number];\n"]}