@mmnto/cli 1.88.0 → 1.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +34 -0
  2. package/dist/author-sandbox.d.ts +32 -0
  3. package/dist/author-sandbox.d.ts.map +1 -0
  4. package/dist/author-sandbox.js +95 -0
  5. package/dist/author-sandbox.js.map +1 -0
  6. package/dist/authored-rule-intake-prewindow.test.d.ts +2 -0
  7. package/dist/authored-rule-intake-prewindow.test.d.ts.map +1 -0
  8. package/dist/authored-rule-intake-prewindow.test.js +84 -0
  9. package/dist/authored-rule-intake-prewindow.test.js.map +1 -0
  10. package/dist/authored-rule-intake.d.ts +21 -1
  11. package/dist/authored-rule-intake.d.ts.map +1 -1
  12. package/dist/authored-rule-intake.js +56 -1
  13. package/dist/authored-rule-intake.js.map +1 -1
  14. package/dist/commands/authored-whitelist.d.ts.map +1 -1
  15. package/dist/commands/authored-whitelist.js +19 -8
  16. package/dist/commands/authored-whitelist.js.map +1 -1
  17. package/dist/commands/ecl-gc.d.ts +259 -0
  18. package/dist/commands/ecl-gc.d.ts.map +1 -0
  19. package/dist/commands/ecl-gc.js +579 -0
  20. package/dist/commands/ecl-gc.js.map +1 -0
  21. package/dist/commands/ecl-gc.test.d.ts +12 -0
  22. package/dist/commands/ecl-gc.test.d.ts.map +1 -0
  23. package/dist/commands/ecl-gc.test.js +609 -0
  24. package/dist/commands/ecl-gc.test.js.map +1 -0
  25. package/dist/commands/eject.d.ts.map +1 -1
  26. package/dist/commands/eject.js +10 -6
  27. package/dist/commands/eject.js.map +1 -1
  28. package/dist/commands/eject.test.js +5 -1
  29. package/dist/commands/eject.test.js.map +1 -1
  30. package/dist/commands/init-templates.d.ts +4 -0
  31. package/dist/commands/init-templates.d.ts.map +1 -1
  32. package/dist/commands/init-templates.js +30 -2
  33. package/dist/commands/init-templates.js.map +1 -1
  34. package/dist/commands/init.test.js +26 -3
  35. package/dist/commands/init.test.js.map +1 -1
  36. package/dist/commands/mail.d.ts +11 -0
  37. package/dist/commands/mail.d.ts.map +1 -1
  38. package/dist/commands/mail.js +5 -1
  39. package/dist/commands/mail.js.map +1 -1
  40. package/dist/commands/mail.test.js +19 -0
  41. package/dist/commands/mail.test.js.map +1 -1
  42. package/dist/commands/rule-author-command.test.js +29 -2
  43. package/dist/commands/rule-author-command.test.js.map +1 -1
  44. package/dist/commands/rule-author-teardown.test.d.ts +2 -0
  45. package/dist/commands/rule-author-teardown.test.d.ts.map +1 -0
  46. package/dist/commands/rule-author-teardown.test.js +123 -0
  47. package/dist/commands/rule-author-teardown.test.js.map +1 -0
  48. package/dist/commands/rule-author.d.ts +1 -0
  49. package/dist/commands/rule-author.d.ts.map +1 -1
  50. package/dist/commands/rule-author.js +143 -2
  51. package/dist/commands/rule-author.js.map +1 -1
  52. package/dist/commands/spine-authored-cert-corpus.d.ts +15 -0
  53. package/dist/commands/spine-authored-cert-corpus.d.ts.map +1 -1
  54. package/dist/commands/spine-authored-cert-corpus.js +17 -1
  55. package/dist/commands/spine-authored-cert-corpus.js.map +1 -1
  56. package/dist/commands/spine-authored-cert-corpus.test.js +440 -4
  57. package/dist/commands/spine-authored-cert-corpus.test.js.map +1 -1
  58. package/dist/commands/spine-authored-materialize.d.ts +55 -0
  59. package/dist/commands/spine-authored-materialize.d.ts.map +1 -0
  60. package/dist/commands/spine-authored-materialize.js +315 -0
  61. package/dist/commands/spine-authored-materialize.js.map +1 -0
  62. package/dist/commands/spine-cert-materialize.d.ts.map +1 -1
  63. package/dist/commands/spine-cert-materialize.js +17 -0
  64. package/dist/commands/spine-cert-materialize.js.map +1 -1
  65. package/dist/commands/spine-cert-persist.d.ts +17 -1
  66. package/dist/commands/spine-cert-persist.d.ts.map +1 -1
  67. package/dist/commands/spine-cert-persist.js +17 -5
  68. package/dist/commands/spine-cert-persist.js.map +1 -1
  69. package/dist/commands/spine-cert-persist.test.js +60 -0
  70. package/dist/commands/spine-cert-persist.test.js.map +1 -1
  71. package/dist/commands/spine-cert-run-corpus.d.ts +18 -28
  72. package/dist/commands/spine-cert-run-corpus.d.ts.map +1 -1
  73. package/dist/commands/spine-cert-run-corpus.js +162 -21
  74. package/dist/commands/spine-cert-run-corpus.js.map +1 -1
  75. package/dist/commands/spine-derive-labels.d.ts.map +1 -1
  76. package/dist/commands/spine-derive-labels.js +9 -1
  77. package/dist/commands/spine-derive-labels.js.map +1 -1
  78. package/dist/commands/spine-freeze-orchestration.test.d.ts +2 -0
  79. package/dist/commands/spine-freeze-orchestration.test.d.ts.map +1 -0
  80. package/dist/commands/spine-freeze-orchestration.test.js +468 -0
  81. package/dist/commands/spine-freeze-orchestration.test.js.map +1 -0
  82. package/dist/commands/spine-freeze-split.d.ts +10 -0
  83. package/dist/commands/spine-freeze-split.d.ts.map +1 -0
  84. package/dist/commands/spine-freeze-split.js +131 -0
  85. package/dist/commands/spine-freeze-split.js.map +1 -0
  86. package/dist/commands/spine-windtunnel.d.ts +35 -0
  87. package/dist/commands/spine-windtunnel.d.ts.map +1 -1
  88. package/dist/commands/spine-windtunnel.js +47 -7
  89. package/dist/commands/spine-windtunnel.js.map +1 -1
  90. package/dist/index.js +93 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/spine-fixture-ancestry.d.ts +20 -0
  93. package/dist/spine-fixture-ancestry.d.ts.map +1 -0
  94. package/dist/spine-fixture-ancestry.js +46 -0
  95. package/dist/spine-fixture-ancestry.js.map +1 -0
  96. package/dist/spine-fixture-ancestry.test.d.ts +2 -0
  97. package/dist/spine-fixture-ancestry.test.d.ts.map +1 -0
  98. package/dist/spine-fixture-ancestry.test.js +62 -0
  99. package/dist/spine-fixture-ancestry.test.js.map +1 -0
  100. package/dist/spine-freeze-proof.d.ts +89 -0
  101. package/dist/spine-freeze-proof.d.ts.map +1 -0
  102. package/dist/spine-freeze-proof.js +237 -0
  103. package/dist/spine-freeze-proof.js.map +1 -0
  104. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"rule-author.js","sourceRoot":"","sources":["../../src/commands/rule-author.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,iFAAiF;AACjF,kFAAkF;AAClF,+EAA+E;AAC/E,kFAAkF;AAClF,4EAA4E;AAC5E,6EAA6E;AAC7E,uFAAuF;AAEvF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA2B;IACjE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACtE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;IAErE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,yBAAyB,CAAC;IACpE,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAErD,OAAO,CAAC,GAAG,CACT,gBAAgB,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB;QACxD,GAAG,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,SAAS,aAAa,CACvF,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CACV,2BAA2B,MAAM,CAAC,QAAQ,CAAC,MAAM,uCAAuC;YACtF,+CAA+C,CAClD,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,2FAA2F;QAC3F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"rule-author.js","sourceRoot":"","sources":["../../src/commands/rule-author.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,iFAAiF;AACjF,kFAAkF;AAClF,+EAA+E;AAC/E,kFAAkF;AAClF,4EAA4E;AAC5E,6EAA6E;AAC7E,uFAAuF;AAEvF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAGvC;IACC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACtE,MAAM,EAAE,kBAAkB,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;IACzF,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IAE5F,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEjD,8EAA8E;IAC9E,+EAA+E;IAC/E,8EAA8E;IAC9E,+EAA+E;IAC/E,8EAA8E;IAC9E,IAAI,aAAmF,CAAC;IACxF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACzD,IAAI,gBAAoC,CAAC;IACzC,IAAI,QAA4B,CAAC;IACjC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,gFAAgF;QAChF,2EAA2E;QAC3E,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,oCAAoC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9D,gBAAgB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,yBAAyB,CAAC;IACpE,IAAI,gBAAgB,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC1E,4EAA4E;QAC5E,0EAA0E;QAC1E,wEAAwE;QACxE,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,UAAU,CAClB,cAAc,EACd,iKAAiK,EACjK,kKAAkK,CACnK,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,GACxD,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;QAC5C,MAAM,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC/E,uBAAuB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,aAAa,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CACT,yCAAyC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,GAAG;YACpE,eAAe,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,iCAAiC,CAClG,CAAC;QACF,wEAAwE;QACxE,6EAA6E;QAC7E,6EAA6E;QAC7E,4EAA4E;QAC5E,0EAA0E;QAC1E,2EAA2E;QAC3E,IAAI,2BAA2B,GAAwB,IAAI,GAAG,EAAU,CAAC;QACzE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,QAAQ,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;YACvB,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ;YACnC,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU;SACtC,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,EAAE,yBAAyB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;YACnF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;YACjD,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,GACpE,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAC/B,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;YACnE,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAClF,aAAa;gBACb,cAAc;gBACd,aAAa;aACd,CAAC,CAAC;YACH,2BAA2B,GAAG,yBAAyB,CAAC;gBACtD,UAAU,EAAE,WAAW;gBACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ;gBAC1C,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU;gBAC9C,eAAe,EAAE,cAAc,CAAC,KAAK,CAAC;gBACtC,uBAAuB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC;aACzF,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CACT,0CAA0C,2BAA2B,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,GAAG;gBACjG,+DAA+D,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CACnH,CAAC;QACJ,CAAC;QACD,8EAA8E;QAC9E,2EAA2E;QAC3E,iFAAiF;QACjF,MAAM,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC3F,MAAM,OAAO,GAAG,oBAAoB,CAAC;YACnC,KAAK;YACL,QAAQ;YACR,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,QAAQ;SACT,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CACT,+DAA+D,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,yCAAyC,CAC5I,CAAC;QACF,IAAI,UAAmB,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE;gBACrC,QAAQ;gBACR,aAAa;gBACb,2BAA2B;aAC5B,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,GAAG,GAAG,CAAC;YACjB,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC;gBACH,mBAAmB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/D,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACrB,wEAAwE;gBACxE,uEAAuE;gBACvE,sEAAsE;gBACtE,IAAI,UAAU,KAAK,SAAS;oBAAE,MAAM,WAAW,CAAC;gBAChD,OAAO,CAAC,IAAI,CACV,qFAAqF,OAAO,CAAC,IAAI,MAAM,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAClL,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;IACpE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,SAAS,yBAAyB,CAAC,QAAgB,EAAE,KAA6B;IAChF,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC7C,mKAAmK;IACrK,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAI,GAAkC,EAAE,KAAK,CAAC;IACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAI,CAA2C,EAAE,gBAAgB,CAAC;QAChF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,SAAS;QACvC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,EAAE,GAAI,CAA6B,EAAE,EAAE,CAAC;YAC9C,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,MAA6D;IACrF,OAAO,CAAC,GAAG,CACT,gBAAgB,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB;QACxD,GAAG,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,SAAS,aAAa,CACvF,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CACV,2BAA2B,MAAM,CAAC,QAAQ,CAAC,MAAM,uCAAuC;YACtF,+CAA+C,CAClD,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,2FAA2F;QAC3F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { AuthoredControlsDeps, GroundTruthLabel, ResolvedPrDiff, SplitArtifact, Stage4VerifierDeps } from '@mmnto/totem';
2
+ import type { FreezeBinding } from '../spine-freeze-proof.js';
2
3
  import type { CertifyingCorpus } from './spine-windtunnel.js';
3
4
  export interface BuildAuthoredCertifyingCorpusDeps {
4
5
  /** `.totem` dir holding `spine/authored-rules.yaml` + the authoring-ledger. */
@@ -23,6 +24,20 @@ export interface BuildAuthoredCertifyingCorpusDeps {
23
24
  now: string;
24
25
  /** Optional §4 differential-evaluator injection for `deriveAuthoredControls` (defaults to the real one). */
25
26
  authoredControlsDeps?: AuthoredControlsDeps;
27
+ /**
28
+ * R1: the PROVEN freeze binding for a content-addressed `expectedSplitRef`
29
+ * (constructed ONLY by `resolveProvenFreezeBinding` at the cert-run boundary —
30
+ * this builder is git-free and never proves). Absent on a legacy free-text run;
31
+ * absent on a content-addressed run ⇒ the intake's total partition fails loud.
32
+ */
33
+ freezeBinding?: FreezeBinding;
34
+ /**
35
+ * §5.2 leakage semantics (#2294 couple, option (a)): fixture PRs the git-holding
36
+ * run boundary PROVED strictly pre-window by ancestry to the artifact's
37
+ * cutBoundarySha (`verifyPreWindowFixturePrs`). Threaded to the intake gate and
38
+ * the §6 deriver; absent/empty ⇒ strict train-only, byte-unchanged.
39
+ */
40
+ verifiedPreWindowFixturePrs?: ReadonlySet<number>;
26
41
  }
27
42
  /**
28
43
  * Assemble an AUTHORED `CertifyingCorpus` from `.totem/spine/authored-rules.yaml`.
@@ -1 +1 @@
1
- {"version":3,"file":"spine-authored-cert-corpus.d.ts","sourceRoot":"","sources":["../../src/commands/spine-authored-cert-corpus.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,oBAAoB,EAEpB,gBAAgB,EAEhB,cAAc,EACd,aAAa,EACb,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,iCAAiC;IAChD,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IAKjB;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,0FAA0F;IAC1F,KAAK,EAAE,aAAa,CAAC;IACrB,uFAAuF;IACvF,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,0EAA0E;IAC1E,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,wEAAwE;IACxE,MAAM,EAAE,kBAAkB,CAAC;IAC3B,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,4GAA4G;IAC5G,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,gBAAgB,CAAC,CAqN3B"}
1
+ {"version":3,"file":"spine-authored-cert-corpus.d.ts","sourceRoot":"","sources":["../../src/commands/spine-authored-cert-corpus.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,oBAAoB,EAEpB,gBAAgB,EAEhB,cAAc,EACd,aAAa,EACb,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,iCAAiC;IAChD,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IAKjB;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,0FAA0F;IAC1F,KAAK,EAAE,aAAa,CAAC;IACrB,uFAAuF;IACvF,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,0EAA0E;IAC1E,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,wEAAwE;IACxE,MAAM,EAAE,kBAAkB,CAAC;IAC3B,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,4GAA4G;IAC5G,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,gBAAgB,CAAC,CAqO3B"}
@@ -66,7 +66,20 @@ export async function buildAuthoredCertifyingCorpus(deps) {
66
66
  // cover (non-empty-but-stale): step-0 empty → no-mint stale → step-3 verdict/binding (Q3 layered).
67
67
  // The producer establishes eligibility/identity; NEVER construct AuthoredRuleRecord[] ad hoc or
68
68
  // read YAML→record here.
69
- const authorResult = runRuleAuthor(deps.totemDir, { judgedBy, verifyOnly: true });
69
+ // R1: a content-addressed expectedSplitRef binds the run to a FROZEN artifact — the caller
70
+ // resolves + PROVES the binding at the cert-run boundary (`resolveProvenFreezeBinding`) and
71
+ // threads it here, or the intake's own content-ref gate voids the verifyOnly re-derive
72
+ // (CR #2293 round 1: the cert re-derive ran bindingless). This builder stays git-free:
73
+ // it CONSUMES a proven binding, never constructs one (the never-unverified-binding
74
+ // invariant — proof lives with the boundary that has git).
75
+ const authorResult = runRuleAuthor(deps.totemDir, {
76
+ judgedBy,
77
+ verifyOnly: true,
78
+ ...(deps.freezeBinding !== undefined ? { freezeBinding: deps.freezeBinding } : {}),
79
+ ...(deps.verifiedPreWindowFixturePrs !== undefined
80
+ ? { verifiedPreWindowFixturePrs: deps.verifiedPreWindowFixturePrs }
81
+ : {}),
82
+ });
70
83
  // 2. rejected.length === 0 precondition: a partially-invalid authored file is broken
71
84
  // cert input — never certify the eligible subset (fail loud, not a partial corpus).
72
85
  if (authorResult.rejected.length > 0) {
@@ -165,6 +178,9 @@ export async function buildAuthoredCertifyingCorpus(deps) {
165
178
  split: deps.split,
166
179
  provenanceByRule,
167
180
  ...(deps.authoredControlsDeps ? { deps: deps.authoredControlsDeps } : {}),
181
+ ...(deps.verifiedPreWindowFixturePrs !== undefined
182
+ ? { verifiedPreWindowFixturePrs: deps.verifiedPreWindowFixturePrs }
183
+ : {}),
168
184
  });
169
185
  return {
170
186
  rules,
@@ -1 +1 @@
1
- {"version":3,"file":"spine-authored-cert-corpus.js","sourceRoot":"","sources":["../../src/commands/spine-authored-cert-corpus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spine-authored-cert-corpus.js","sourceRoot":"","sources":["../../src/commands/spine-authored-cert-corpus.ts"],"names":[],"mappings":"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"}
@@ -4,8 +4,10 @@ import * as os from 'node:os';
4
4
  import * as path from 'node:path';
5
5
  import { afterEach, beforeEach, describe, expect, it } from 'vitest';
6
6
  import { stringify } from 'yaml';
7
+ import { CertCorpusSeedSchema, firingLabelId, scoreWindtunnel, WindtunnelLockSchema, } from '@mmnto/totem';
7
8
  import { runRuleAuthor } from '../authored-rule-intake.js';
8
9
  import { buildAuthoredCertifyingCorpus, } from './spine-authored-cert-corpus.js';
10
+ import { materializeAuthored } from './spine-authored-materialize.js';
9
11
  import { assembleAuthoredCertifyingCorpus, resolveCertifyingCorpusProvider, } from './spine-cert-run-corpus.js';
10
12
  // ─── Fixtures (mirror the slice-2/3/4 + authored-controls tests) ──────────────
11
13
  const sha = (n) => String(n).padStart(40, '0');
@@ -242,9 +244,12 @@ describe('resolveCertifyingCorpusProvider — producerKind dispatch (D2 async si
242
244
  });
243
245
  /** A minimal lock cast — the resolver only reads producerKind / authored / integrity shas. */
244
246
  const lock = (overrides) => ({ controls: { integrity: {} }, ...overrides });
245
- it('a mined lock (explicit or absent) resolves to a provider with no authored block', async () => {
246
- await expect(resolveCertifyingCorpusProvider(lock({ producerKind: 'mined' }), inputs())).resolves.toBeTypeOf('function');
247
- await expect(resolveCertifyingCorpusProvider(lock({}), inputs())).resolves.toBeTypeOf('function');
247
+ it('a mined lock (explicit or absent) resolves to a { provider, score } bundle', async () => {
248
+ for (const overrides of [{ producerKind: 'mined' }, {}]) {
249
+ const resolved = await resolveCertifyingCorpusProvider(lock(overrides), inputs());
250
+ expect(resolved.provider).toBeTypeOf('function');
251
+ expect(resolved.score).toBeTypeOf('function');
252
+ }
248
253
  });
249
254
  it('an authored lock WITHOUT an `authored` block fails loud (require-when-authored)', async () => {
250
255
  await expect(resolveCertifyingCorpusProvider(lock({ producerKind: 'authored' }), inputs())).rejects.toThrow(/run-input block/);
@@ -266,7 +271,9 @@ describe('resolveCertifyingCorpusProvider — producerKind dispatch (D2 async si
266
271
  authored: { expectedSplitRef: SPLIT_REF },
267
272
  controls: { integrity: { prDiffsSha, groundTruthSha } },
268
273
  });
269
- const provider = await resolveCertifyingCorpusProvider(authoredLock, inputs({ authoredControlsDeps: diffDeps('differential-holds') }));
274
+ const { provider, score } = await resolveCertifyingCorpusProvider(authoredLock, inputs({ authoredControlsDeps: diffDeps('differential-holds') }));
275
+ // D4: the §8 single home also binds the producer-kind scorer alongside the provider.
276
+ expect(score).toBeTypeOf('function');
270
277
  const corpus = await provider(authoredLock);
271
278
  expect(corpus.authoredControls).toBeDefined();
272
279
  expect(corpus.authoredControls.positive).toHaveLength(1);
@@ -343,4 +350,433 @@ describe('assembleAuthoredCertifyingCorpus (D2.6 derive-path sibling)', () => {
343
350
  await expect(assembleAuthoredCertifyingCorpus(opts(), authoredLock)).rejects.toThrow(/pr-diffs\.json integrity/);
344
351
  });
345
352
  });
353
+ // ─── 6. Slice D4 — the reachable flip: resolved.score(base) end-to-end ─────────
354
+ //
355
+ // The whole-path couple strategy reviews (ruling 2318Z, Q4 — 4 seams): (1) authored
356
+ // corpus resolution (§8 single-home), (2) the no-mint verifyOnly gate FIRING, (3)
357
+ // scoreAuthoredWindtunnel invocation (Q1 threading guard), (4) the Gate-2 emit
358
+ // (verdict-inert, §1(k)-guarded). These rows drive a REAL resolve → real scorer
359
+ // (never a mock) → real deriveGate2Eligibility, reusing the D1–D3 fixtures.
360
+ describe('ADR-112 D4 — reachable flip: resolved.score(base) end-to-end', () => {
361
+ let gate1Dir;
362
+ beforeEach(() => {
363
+ gate1Dir = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-d4-gate1-'));
364
+ });
365
+ afterEach(() => {
366
+ fs.rmSync(gate1Dir, { recursive: true, force: true });
367
+ });
368
+ const inputs = (extra = {}) => ({
369
+ gate1Dir,
370
+ stage4: stage4(),
371
+ now: NOW,
372
+ totemDir,
373
+ ...extra,
374
+ });
375
+ const lock = (overrides) => ({ controls: { integrity: {} }, ...overrides });
376
+ /** An authored lock bound to a substrate's integrity shas. */
377
+ const authoredLock = (prDiffsSha, groundTruthSha) => lock({
378
+ producerKind: 'authored',
379
+ authored: { expectedSplitRef: SPLIT_REF },
380
+ controls: { integrity: { prDiffsSha, groundTruthSha } },
381
+ });
382
+ /** A ScorerInput `base` (exposure floors 0 so a clean run reaches PASS). The authored
383
+ * closure strips `positiveControlTargets` (Q1 guard); the mined closure keeps it. */
384
+ const baseScorerInput = (over) => ({
385
+ firings: [],
386
+ groundTruth: new Map(),
387
+ positiveControlTargets: [],
388
+ mintedRuleIds: [],
389
+ cullRateThreshold: 0.5,
390
+ exposureFloors: {
391
+ activeRulesEvaluated: 0,
392
+ filesTouchedInWindow: 0,
393
+ positiveControlsExercised: 0,
394
+ },
395
+ actualExposure: {
396
+ activeRulesEvaluated: 1,
397
+ filesTouchedInWindow: 5,
398
+ positiveControlsExercised: 1,
399
+ },
400
+ ...over,
401
+ });
402
+ const firing = (ruleId, pr, controlKind, matchedLine = 'gen();', filePath = 'src/a.ts') => ({
403
+ ruleId,
404
+ pr,
405
+ filePath,
406
+ matchedLine,
407
+ controlKind,
408
+ labelId: firingLabelId(ruleId, pr, filePath, matchedLine),
409
+ });
410
+ /** Resolve an authored run over a split with held-out prs, then read the minted ruleId
411
+ * the real corpus derived (the Gate-2 join-back key). */
412
+ const resolveAuthored = async (split) => {
413
+ writeAuthoredYaml(totemDir);
414
+ const { prDiffsSha, groundTruthSha } = writeSubstrate(gate1Dir, { split });
415
+ const alock = authoredLock(prDiffsSha, groundTruthSha);
416
+ const resolved = await resolveCertifyingCorpusProvider(alock, inputs({ authoredControlsDeps: diffDeps('differential-holds') }));
417
+ const corpus = await resolved.provider(alock);
418
+ const ruleId = corpus.authoredControls.positive[0].targetRuleId;
419
+ return { resolved, ruleId };
420
+ };
421
+ it('(i) authored happy path: resolve → real scoreAuthoredWindtunnel → PASS + Gate-2 eligible', async () => {
422
+ const split = { ...SPLIT, trainPrs: [1], heldOutPrs: [2] };
423
+ const { resolved, ruleId } = await resolveAuthored(split);
424
+ const ctrl = firing(ruleId, 1, 'positive', 'ctrl();'); // train-side positive control
425
+ const heldCorpus = firing(ruleId, 2, 'corpus', 'gen();'); // held-out generalization
426
+ const scored = resolved.score(baseScorerInput({
427
+ firings: [ctrl, heldCorpus],
428
+ groundTruth: new Map([
429
+ [ctrl.labelId, 'TP'],
430
+ [heldCorpus.labelId, 'TP'],
431
+ ]),
432
+ mintedRuleIds: [ruleId],
433
+ positiveControlTargets: [{ pr: 1, targetRuleId: ruleId }],
434
+ }));
435
+ expect(scored.kind).toBe('authored');
436
+ if (scored.kind !== 'authored')
437
+ throw new Error('unreachable');
438
+ expect(scored.verdict.verdict).toBe('PASS');
439
+ // O3 metric: the held-out corpus firing counts; the train-side control does not.
440
+ expect(scored.verdict.heldOutActivationsByRule).toEqual({ [ruleId]: 1 });
441
+ // Gate-2: a non-disqualified window's survivor with heldOut>0 is eligible (§1(k) satisfied).
442
+ expect(scored.gate2.windowDisqualified).toBe(false);
443
+ expect(scored.gate2.eligibleRuleIds).toEqual([ruleId]);
444
+ });
445
+ it('(ii) no-mint gate FIRES: a would-be-minted rule ⇒ GATE_INVALID at resolve, scorer unreachable, ledger byte-unchanged', async () => {
446
+ writeAuthoredYaml(totemDir); // seeds YAML + ledger (rule → `unchanged` on re-read)
447
+ const { prDiffsSha, groundTruthSha } = writeSubstrate(gate1Dir);
448
+ const ledgerPath = path.join(totemDir, 'spine', 'authoring-ledger.ndjson');
449
+ const ledgerBefore = fs.readFileSync(ledgerPath, 'utf-8');
450
+ // agy's dynamic in-memory mutate: rewrite ONLY the YAML to add a SECOND (unledgered)
451
+ // rule — the cert re-derive would MINT it. Do NOT re-seed the ledger (no runRuleAuthor).
452
+ fs.writeFileSync(path.join(totemDir, 'spine', 'authored-rules.yaml'), stringify({
453
+ splitRef: SPLIT_REF,
454
+ authoredAfterSplit: true,
455
+ heldOutNonInspectionAttestation: true,
456
+ rules: [
457
+ authoredRuleInput(),
458
+ authoredRuleInput({ targetDefect: 'a SECOND distinct defect' }),
459
+ ],
460
+ }), 'utf-8');
461
+ // The gate throws during the resolver's EAGER build — before `score` is returned (a
462
+ // stronger guarantee than a scorer spy: the closure never exists to be called).
463
+ await expect(resolveCertifyingCorpusProvider(authoredLock(prDiffsSha, groundTruthSha), inputs({ authoredControlsDeps: diffDeps('differential-holds') }))).rejects.toThrow(/would be authored \(minted\/revised\)/);
464
+ // §8 no-mint: the cert re-derive is read-only — the gate fired before Pass-2 append.
465
+ expect(fs.readFileSync(ledgerPath, 'utf-8')).toBe(ledgerBefore);
466
+ });
467
+ it('(v) mined path regression: producerKind absent ⇒ kind mined, NO gate2 key, verdict byte-identical to scoreWindtunnel', async () => {
468
+ const resolved = await resolveCertifyingCorpusProvider(lock({}), inputs());
469
+ const ctrl = firing('mined-rule', 1, 'positive', 'ctrl();');
470
+ const base = baseScorerInput({
471
+ firings: [ctrl],
472
+ groundTruth: new Map([[ctrl.labelId, 'TP']]),
473
+ mintedRuleIds: ['mined-rule'],
474
+ positiveControlTargets: [{ pr: 1, targetRuleId: 'mined-rule' }],
475
+ });
476
+ const scored = resolved.score(base);
477
+ expect(scored.kind).toBe('mined');
478
+ // The mined bundle carries NO Gate-2 surface at all (not an empty one).
479
+ expect('gate2' in scored).toBe(false);
480
+ // Byte-identity: the mined closure is a pass-through to the real scoreWindtunnel.
481
+ expect(scored.verdict).toEqual(scoreWindtunnel(base));
482
+ });
483
+ it('(vi) cross-partition leakage guard: a train-only-activating rule → zero held-out → excluded from Gate-2 despite PASS', async () => {
484
+ const split = { ...SPLIT, trainPrs: [1], heldOutPrs: [2] };
485
+ // Structural guard: the partitions the metric keys off are disjoint (heldOut ∩ train = ∅).
486
+ expect(split.heldOutPrs.some((pr) => split.trainPrs.includes(pr))).toBe(false);
487
+ const { resolved, ruleId } = await resolveAuthored(split);
488
+ const ctrl = firing(ruleId, 1, 'positive', 'ctrl();'); // train-side ONLY — no held-out corpus firing
489
+ const scored = resolved.score(baseScorerInput({
490
+ firings: [ctrl],
491
+ groundTruth: new Map([[ctrl.labelId, 'TP']]),
492
+ mintedRuleIds: [ruleId],
493
+ positiveControlTargets: [{ pr: 1, targetRuleId: ruleId }],
494
+ }));
495
+ expect(scored.kind).toBe('authored');
496
+ if (scored.kind !== 'authored')
497
+ throw new Error('unreachable');
498
+ // Clean rare-defect window: the verdict PASSES…
499
+ expect(scored.verdict.verdict).toBe('PASS');
500
+ expect(scored.verdict.heldOutActivationsByRule).toEqual({ [ruleId]: 0 });
501
+ // …yet Gate-2 excludes the rule (survivor recorded, ineligible at zero held-out).
502
+ expect(scored.gate2.survivors).toEqual([
503
+ { ruleId, heldOutActivations: 0, gate2Eligible: false },
504
+ ]);
505
+ expect(scored.gate2.eligibleRuleIds).toEqual([]);
506
+ });
507
+ it('(vii) unlabeled-demotion partition: held-out UNLABELED corpus firing ⇒ HONEST-NEGATIVE, no FP, metric verdict-inert', async () => {
508
+ const split = { ...SPLIT, trainPrs: [1], heldOutPrs: [2] };
509
+ const { resolved, ruleId } = await resolveAuthored(split);
510
+ const ctrl = firing(ruleId, 1, 'positive', 'ctrl();'); // train-side, TP-labeled
511
+ const unlabeled = firing(ruleId, 2, 'corpus', 'gen();'); // held-out, NO ground-truth entry
512
+ const scored = resolved.score(baseScorerInput({
513
+ firings: [ctrl, unlabeled],
514
+ groundTruth: new Map([[ctrl.labelId, 'TP']]),
515
+ mintedRuleIds: [ruleId],
516
+ positiveControlTargets: [{ pr: 1, targetRuleId: ruleId }],
517
+ }));
518
+ expect(scored.kind).toBe('authored');
519
+ if (scored.kind !== 'authored')
520
+ throw new Error('unreachable');
521
+ // Clean demotion — needs adjudication, NOT a FAIL/FP.
522
+ expect(scored.verdict.verdict).toBe('HONEST-NEGATIVE');
523
+ expect(scored.verdict.needsAdjudication).toContain(unlabeled.labelId);
524
+ expect(scored.gate2.windowDisqualified).toBe(false);
525
+ // The O3 metric is label-independent (verdict-inert): the unlabeled held-out firing still counts.
526
+ expect(scored.verdict.heldOutActivationsByRule).toEqual({ [ruleId]: 1 });
527
+ });
528
+ it('(viii) §6 cull-unbroken: a fix-shaped differential ⇒ positive:[] + illegitimate non-emission ⇒ FAIL, never a mined PASS via empty positives (codex assertion #1)', async () => {
529
+ writeAuthoredYaml(totemDir);
530
+ const split = { ...SPLIT, trainPrs: [1], heldOutPrs: [2] };
531
+ const { prDiffsSha, groundTruthSha } = writeSubstrate(gate1Dir, { split });
532
+ const alock = authoredLock(prDiffsSha, groundTruthSha);
533
+ // fix-shaped: the §4 differential culls every fixture to an illegitimate non-emission —
534
+ // NOTHING reaches positive[]. resolveAuthored is not reusable here (it reads positive[0]).
535
+ const resolved = await resolveCertifyingCorpusProvider(alock, inputs({ authoredControlsDeps: diffDeps('fix-shaped') }));
536
+ const corpus = await resolved.provider(alock);
537
+ // The §6 cull holds end-to-end: a fix-shaped fixture lands in nonEmissions, never positive[].
538
+ expect(corpus.authoredControls.positive).toEqual([]);
539
+ expect(corpus.authoredControls.nonEmissions).toHaveLength(1);
540
+ expect(corpus.authoredControls.nonEmissions[0].class).toBe('illegitimate');
541
+ const ruleId = corpus.rules[0].lessonHash;
542
+ // The hazard codex assertion #1 guards: an empty positive control MUST NOT let the run
543
+ // degenerate to a mined PASS via positiveControlTargets:[] — the illegitimate non-emission
544
+ // FAILs the whole window. (Core-altitude sibling: windtunnel-scorer-authored.test.ts codex-1.)
545
+ const scored = resolved.score(baseScorerInput({
546
+ firings: [],
547
+ groundTruth: new Map(),
548
+ mintedRuleIds: [ruleId],
549
+ positiveControlTargets: [],
550
+ }));
551
+ expect(scored.kind).toBe('authored');
552
+ if (scored.kind !== 'authored')
553
+ throw new Error('unreachable');
554
+ // NOT a silent mined PASS — a structural, no-claim FAIL (precision null, never 0).
555
+ expect(scored.verdict.verdict).toBe('FAIL');
556
+ expect(scored.verdict.precision).toBeNull();
557
+ expect(scored.verdict.authoredControlGate.illegitimate).toBe(1);
558
+ expect(scored.verdict.authoredControlGate.effect).toBe('fail-illegitimate');
559
+ // Gate-2: illegitimate > 0 ⇒ window disqualified ⇒ no survivor eligible (Q4).
560
+ expect(scored.gate2.windowDisqualified).toBe(true);
561
+ expect(scored.gate2.eligibleRuleIds).toEqual([]);
562
+ });
563
+ });
564
+ // ─── 7. Slice D5 — the authored materialize/freeze seam (producer → consumer) ──
565
+ //
566
+ // `materializeAuthored` is the sibling authored producer: it FREEZES the window-wide
567
+ // substrate + a `frozenAt` split + the `producerKind:'authored'` lock, gated by the
568
+ // §5.1/§5.3 freeze preconditions. Git is injected so the producer is exercised without
569
+ // a real clone (the mined materializer has no unit test at all). Row (i) closes the
570
+ // producer→consumer loop: the PRODUCED lock+substrate drives a real authored resolve.
571
+ describe('ADR-112 D5 — materializeAuthored (authored producer)', () => {
572
+ const AUTHORED_AT = '2026-06-15T12:00:00.000Z';
573
+ const FROZEN_AT = '2026-06-01T00:00:00.000Z'; // strictly BEFORE authoring (Q3 temporal)
574
+ let repoRoot;
575
+ let gate1Dir;
576
+ beforeEach(() => {
577
+ repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-d5-repo-'));
578
+ gate1Dir = path.join(repoRoot, 'gate-1');
579
+ });
580
+ afterEach(() => {
581
+ fs.rmSync(repoRoot, { recursive: true, force: true });
582
+ });
583
+ /** Newest-first metas for PRs 2,1 → corpus [1,2] (all code-touching non-bot). */
584
+ const metas = () => [2, 1].map((pr) => ({
585
+ pr,
586
+ mergeCommit: sha(pr),
587
+ author: 'Dev <dev@example.com>',
588
+ isBotAuthor: false,
589
+ changedFiles: ['src/a.ts'],
590
+ }));
591
+ /** An authored seed: producerKind authored, cutIndex 1 ⇒ train [1] / held-out [2] (floor 0.5). */
592
+ const authoredSeed = (over = {}) => CertCorpusSeedSchema.parse({
593
+ producerKind: 'authored',
594
+ gate: 'gate-1',
595
+ canonicalPath: 'gate-1/windtunnel.lock.json',
596
+ repo: 'mmnto-ai/liquid-city',
597
+ phase: 'certifying',
598
+ selectionRule: {
599
+ state: 'merged',
600
+ predicate: 'code-touching non-bot',
601
+ window: { type: 'all' },
602
+ asOfCommit: sha(999),
603
+ codePathClassifier: { includeGlobs: ['**'], excludeGlobs: [] },
604
+ },
605
+ split: { cutIndex: 1, excludedPrs: [], frozenAt: FROZEN_AT },
606
+ controls: {
607
+ positiveRef: 'gate-1/controls/positive',
608
+ negativeRef: 'gate-1/controls/negative',
609
+ mechanism: 'git-hash-object',
610
+ positive: [], // authored controls are train-side (derived at run), NOT seed-designated
611
+ negative: [],
612
+ },
613
+ fpDefinition: { rubricRef: 'r', groundTruthRef: 'g', adjudicator: 'disposition-derived' },
614
+ cullRateThreshold: 0.1,
615
+ exposureDenominator: {
616
+ activeRulesEvaluated: { floor: 2 },
617
+ filesTouchedInWindow: { floor: 0 },
618
+ positiveControlsExercised: { floor: 0 },
619
+ },
620
+ ...over,
621
+ });
622
+ const ctx = (seed) => ({
623
+ seed,
624
+ lcDir: '/unused-git-injected',
625
+ repoRoot,
626
+ cwd: repoRoot,
627
+ totemDir,
628
+ outDir: gate1Dir,
629
+ resolveWithinRepo: (input) => path.resolve(repoRoot, input),
630
+ safeExec: (() => {
631
+ throw new Error('git must be injected');
632
+ }),
633
+ });
634
+ /** Injected git: canned metas + non-empty diffs + a fixed fixtureSha. No `now` — `frozenAt` is
635
+ * the seed's recorded pre-authoring instant (real chronology), never a materialize clock. */
636
+ const gitDeps = (over = {}) => ({
637
+ enumerateMetas: () => metas(),
638
+ resolvePrDiff: (mergeCommit) => ({
639
+ baseSha: sha(500),
640
+ headSha: sha(600),
641
+ diff: `diff ${mergeCommit}\n+forbiddenCall()\n`,
642
+ }),
643
+ computeControlFixtureSha: () => sha(7),
644
+ ...over,
645
+ });
646
+ it('(i) produces a valid authored lock + window-wide substrate + frozenAt split', async () => {
647
+ writeAuthoredYaml(totemDir, {
648
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(1)] })],
649
+ });
650
+ await materializeAuthored(ctx(authoredSeed()), gitDeps());
651
+ // Lock: parses, producerKind authored, expectedSplitRef = the ledger's splitRef, no groundTruthSha.
652
+ const lockRaw = JSON.parse(fs.readFileSync(path.join(gate1Dir, 'windtunnel.lock.json'), 'utf-8'));
653
+ const lock = WindtunnelLockSchema.parse(lockRaw);
654
+ expect(lock.producerKind).toBe('authored');
655
+ expect(lock.authored).toEqual({ expectedSplitRef: SPLIT_REF });
656
+ expect(lock.controls.integrity.groundTruthSha).toBeUndefined(); // derive-labels stamps it
657
+ // Split: carries the mechanical frozenAt; train [1] / held-out [2].
658
+ const split = JSON.parse(fs.readFileSync(path.join(gate1Dir, 'split.json'), 'utf-8'));
659
+ expect(split.frozenAt).toBe(FROZEN_AT);
660
+ expect(split.trainPrs).toEqual([1]);
661
+ expect(split.heldOutPrs).toEqual([2]);
662
+ // pr-diffs: WINDOW-WIDE (train ∪ held-out = [1,2]), not held-out-only.
663
+ const prDiffs = JSON.parse(fs.readFileSync(path.join(gate1Dir, 'pr-diffs.json'), 'utf-8'));
664
+ expect(prDiffs.map((d) => d.pr)).toEqual([1, 2]);
665
+ // The train-side positive-control fixture diff was written for the integrity gate.
666
+ expect(fs.existsSync(path.join(repoRoot, 'gate-1/controls/positive/1.diff'))).toBe(true);
667
+ });
668
+ it('(i-consumer) the PRODUCED lock+substrate drives a real authored resolve (producer→consumer)', async () => {
669
+ writeAuthoredYaml(totemDir, {
670
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(1)] })],
671
+ });
672
+ await materializeAuthored(ctx(authoredSeed()), gitDeps());
673
+ // Simulate the `derive-labels` seal: write the answer key + stamp groundTruthSha onto the lock.
674
+ const gtJson = JSON.stringify({});
675
+ fs.writeFileSync(path.join(gate1Dir, 'ground-truth-labels.json'), gtJson, 'utf-8');
676
+ const groundTruthSha = createHash('sha256')
677
+ .update(gtJson.replace(/\r\n/g, '\n'), 'utf-8')
678
+ .digest('hex');
679
+ const lock = WindtunnelLockSchema.parse(JSON.parse(fs.readFileSync(path.join(gate1Dir, 'windtunnel.lock.json'), 'utf-8')));
680
+ const sealedLock = {
681
+ ...lock,
682
+ controls: {
683
+ ...lock.controls,
684
+ integrity: { ...lock.controls.integrity, groundTruthSha },
685
+ },
686
+ };
687
+ const { provider, score } = await resolveCertifyingCorpusProvider(sealedLock, {
688
+ gate1Dir,
689
+ stage4: stage4(),
690
+ now: NOW,
691
+ totemDir,
692
+ authoredControlsDeps: diffDeps('differential-holds'),
693
+ });
694
+ const corpus = await provider(sealedLock);
695
+ // The authored channel resolved from the PRODUCED substrate (fixture #1 is train-side positive).
696
+ expect(corpus.authoredControls).toBeDefined();
697
+ expect(corpus.authoredControls.positive).toHaveLength(1);
698
+ expect(score).toBeTypeOf('function');
699
+ });
700
+ it('(ii) temporal violation: seed frozenAt AFTER authoring ⇒ GATE_INVALID, nothing written', async () => {
701
+ // A real (undoctored) run: the seed's recorded frozenAt post-dates the rule's authoredAt, so
702
+ // the split was NOT frozen before authoring — a §5.1 leakage event the gate must reject.
703
+ writeAuthoredYaml(totemDir, {
704
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(1)] })],
705
+ });
706
+ const lateSeed = authoredSeed({
707
+ split: { cutIndex: 1, excludedPrs: [], frozenAt: '2026-06-20T00:00:00.000Z' },
708
+ });
709
+ await expect(materializeAuthored(ctx(lateSeed), gitDeps())).rejects.toThrow(/Q3 temporal/);
710
+ // Nothing written: the freeze gate throws BEFORE gate1Dir is created (CR — no partial write).
711
+ expect(fs.existsSync(gate1Dir)).toBe(false);
712
+ });
713
+ it('(vii) absent seed frozenAt ⇒ fail-loud (materialize never stamps its own clock)', async () => {
714
+ // The production-honesty guard (#2287 couple HOLD): with no recorded pre-authoring freeze
715
+ // instant, materialize MUST fail loud — never fall back to a materialize-`now()` freeze.
716
+ writeAuthoredYaml(totemDir, {
717
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(1)] })],
718
+ });
719
+ // Hand-built (not schema-parsed): the parse-time presence guard (strategy#804
720
+ // layered clauses) now rejects this shape at parse, so the materialize-time
721
+ // defense must be proven on its own for programmatic callers. No cast: the
722
+ // absence is refinement-invalid but structurally legal (`frozenAt` is
723
+ // optional), so the fixture keeps full compile-time property checking.
724
+ const noFreezeSeed = {
725
+ ...authoredSeed(),
726
+ split: { cutIndex: 1, excludedPrs: [] },
727
+ };
728
+ await expect(materializeAuthored(ctx(noFreezeSeed), gitDeps())).rejects.toThrow(/frozen BEFORE authoring/);
729
+ expect(fs.existsSync(gate1Dir)).toBe(false);
730
+ });
731
+ it('(v) Q2 floor violation: held-out < 50% of the window ⇒ GATE_INVALID', async () => {
732
+ // corpus [1,2,3], cutIndex 2 ⇒ train [1,2] / held-out [3] ⇒ 1/3 < 0.5.
733
+ const threeMetas = [3, 2, 1].map((pr) => ({
734
+ pr,
735
+ mergeCommit: sha(pr),
736
+ author: 'Dev <dev@example.com>',
737
+ isBotAuthor: false,
738
+ changedFiles: ['src/a.ts'],
739
+ }));
740
+ writeAuthoredYaml(totemDir, {
741
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(1)] })],
742
+ });
743
+ await expect(materializeAuthored(ctx(authoredSeed({ split: { cutIndex: 2, excludedPrs: [], frozenAt: FROZEN_AT } })), gitDeps({ enumerateMetas: () => threeMetas }))).rejects.toThrow(/Q2 held-out floor/);
744
+ expect(fs.existsSync(gate1Dir)).toBe(false);
745
+ });
746
+ it('(iii) membership violation: a held-out positive fixture ⇒ GATE_INVALID naming the PR', async () => {
747
+ // fixture pr=2 is the HELD-OUT slice ⇒ §5(2) leakage.
748
+ writeAuthoredYaml(totemDir, {
749
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(2)] })],
750
+ });
751
+ await expect(materializeAuthored(ctx(authoredSeed()), gitDeps())).rejects.toThrow(/Q3 membership.*#2/s);
752
+ expect(fs.existsSync(gate1Dir)).toBe(false);
753
+ });
754
+ it('(iv) vacuous effective ledger: zero positive-fixture PRs ⇒ GATE_INVALID before any git work', async () => {
755
+ // `runRuleAuthor` intake enforces ≥1 positive fixture per rule, but the ledger reader
756
+ // (`.strict()`, no `.min`) still parses a legacy/hand-edited row with `positiveFixturePrs: []`
757
+ // — the ndjson file IS the boundary the materializer trusts. Degrade the row to that shape.
758
+ writeAuthoredYaml(totemDir, {
759
+ rules: [authoredRuleInput({ authoredAt: AUTHORED_AT, positiveFixtures: [posFixture(1)] })],
760
+ });
761
+ const ledgerFile = path.join(totemDir, 'spine', 'authoring-ledger.ndjson');
762
+ const degraded = fs
763
+ .readFileSync(ledgerFile, 'utf-8')
764
+ .trim()
765
+ .split('\n')
766
+ .map((row) => JSON.stringify({ ...JSON.parse(row), positiveFixturePrs: [] }))
767
+ .join('\n');
768
+ fs.writeFileSync(ledgerFile, `${degraded}\n`, 'utf-8');
769
+ // The non-vacuity gate precedes ALL per-PR git resolution (CR round-2 hoist): a vacuous
770
+ // ledger must cost zero `resolvePrDiff` shell-outs — and, as ever, zero bytes on disk.
771
+ let gitCalls = 0;
772
+ await expect(materializeAuthored(ctx(authoredSeed()), gitDeps({
773
+ resolvePrDiff: (mergeCommit) => {
774
+ gitCalls += 1;
775
+ return { baseSha: sha(500), headSha: sha(600), diff: `diff ${mergeCommit}\n` };
776
+ },
777
+ }))).rejects.toThrow(/no positive-control fixture PRs in the effective authoring-ledger/);
778
+ expect(gitCalls).toBe(0);
779
+ expect(fs.existsSync(gate1Dir)).toBe(false);
780
+ });
781
+ });
346
782
  //# sourceMappingURL=spine-authored-cert-corpus.test.js.map