@descent-vtt/spec-graph 0.4.0 → 0.5.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.
package/dist/rules.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,cAAc,EAAoB,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAkB,MAAM,aAAa,CAAC;AAelE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,MAAM,CAAC,MAAM,kBAAkB,GAAuC,MAAM,CAAC,MAAM,CAAC;IAClF,gBAAgB,EAAE,OAAO;IACzB,eAAe,EAAE,OAAO;IACxB,kBAAkB,EAAE,OAAO;IAC3B,0BAA0B,EAAE,MAAM;IAClC,qBAAqB,EAAE,MAAM;IAC7B,qBAAqB,EAAE,OAAO;IAC9B,qBAAqB,EAAE,OAAO;IAC9B,mBAAmB,EAAE,OAAO;IAC5B,6BAA6B,EAAE,MAAM;IACrC,gBAAgB,EAAE,MAAM;IACxB,gBAAgB,EAAE,MAAM;IACxB,sBAAsB,EAAE,MAAM;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAsB,CAAC;AAE7E,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAqC,MAAM,CAAC,MAAM,CAAC;IAC/E,gBAAgB,EAAE,yEAAyE;IAC3F,eAAe,EAAE,uEAAuE;IACxF,kBAAkB,EAAE,2DAA2D;IAC/E,0BAA0B,EAAE,qEAAqE;IACjG,qBAAqB,EAAE,2CAA2C;IAClE,qBAAqB,EAAE,0EAA0E;IACjG,qBAAqB,EAAE,2DAA2D;IAClF,mBAAmB,EAAE,qEAAqE;IAC1F,6BAA6B,EAAE,kDAAkD;IACjF,gBAAgB,EAAE,sEAAsE;IACxF,gBAAgB,EAAE,8CAA8C;IAChE,sBAAsB,EAAE,0DAA0D;CACnF,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAS,GAAyC,EAAE,EACpD,MAAM,GAAG,KAAK,EACd,YAAY,GAA2B,EAAE;IAEzC,MAAM,UAAU,GAAyC,EAAE,GAAG,SAAS,EAAE,CAAC;IAC1E,MAAM,SAAS,GAAG,IAAI,GAAG,EAAa,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IAE9C,2EAA2E;IAC3E,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,QAAQ,GAA4B;QACxC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAyB,EAAE,CAAC,CAAC,EAAE,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5E,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAyB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;KAC/E,CAAC;IAEF,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,SAAS;YAAE,SAAS;QAC1C,IAAI,KAAK,KAAK,MAAM;YAAE,SAAS;QAC/B,UAAU,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;QACzB,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC;AAUD,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,oEAAoE;AACpE,MAAM,UAAU,QAAQ,CAAC,KAAgB,EAAE,MAAsB,EAAE,OAAO,GAAgB,EAAE;IAC1F,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAChD,MAAM,UAAU,GAAyC,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACnF,0EAA0E;IAC1E,6EAA6E;IAC7E,6CAA6C;IAC7C,KAAK,MAAM,IAAI,IAAI,YAAY;QAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;IACrE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;IAC7D,MAAM,GAAG,GAAiB,EAAE,CAAC;IAE7B,MAAM,IAAI,GAAG,CAAC,IAAe,EAAE,KAAkB,EAAQ,EAAE;QACzD,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,2EAA2E;QAC3E,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK;YAAE,OAAO;QACzD,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;QACrB,IAAI,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO;QAC5C,6EAA6E;QAC7E,uDAAuD;QACvD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC,CAAC;IAEF,oEAAoE;IACpE,+EAA+E;IAC/E,sEAAsE;IACtE,qEAAqE;IACrE,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7C,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5B,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1B,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5B,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;IAE3C,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAOD;;;;;GAKG;AACH,MAAM,eAAe,GAA2B,IAAI,GAAG,CAAY;IACjE,kBAAkB;IAClB,0BAA0B;IAC1B,qBAAqB;IACrB,6EAA6E;IAC7E,8EAA8E;IAC9E,gEAAgE;IAChE,sBAAsB;CACvB,CAAC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,SAAS,MAAM,CAAC,KAAgB,EAAE,IAAe,EAAE,KAAwB;IACzE,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,KAAK,KAAK,QAAQ,CAAC;AAC3D,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,cAAc,GAAc,UAAU,CAC1C,sFAAsF,CACvF,CAAC;AAEF,4EAA4E;AAC5E,SAAS,cAAc,CAAC,KAAgB,EAAE,IAAU;IAClD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAS,CAAC;QACpC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,cAAc;YAAE,SAAS;QAE9B,MAAM,MAAM,GAAG,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC;QACvE,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAE3B,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5B,OAAO,EAAE,GAAG,IAAI,IAAI,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc,MAAM,EAAE;YAClE,EAAE,EAAE,IAAI,CAAC,UAAU;YACnB,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE;gBACP,OAAO,CAAC,cAAc,CAAC,QAAQ,IAAI,cAAc,CAAC,EAAE,EAAE,GAAG,cAAc,CAAC,EAAE,OAAO,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;gBACzH,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,mBAAmB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1F;YACD,IAAI,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;SACjG,CAAC,CAAC,CAAC;IACN,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,oEAAoE;AACpE,MAAM,WAAW,GAA8C;IAC7D,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,qBAAqB;CAC9B,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,EAAU,EAAU,EAAE,CACzC,GAAG,EAAE,gFAAgF,CAAC;AAExF,sEAAsE;AACtE,MAAM,aAAa,GAA8D;IAC/E,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,6BAA6B,EAAE,4DAA4D;IAC5G,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,iFAAiF;CACvG,CAAC;AAEF,0EAA0E;AAC1E,SAAS,OAAO,CAAC,IAAU;IACzB,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;AAChD,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,sBAAsB,GAAc,UAAU,CAClD,mFAAmF,CACpF,CAAC;AACF,MAAM,kBAAkB,GAAc,UAAU,CAC9C,gFAAgF,CACjF,CAAC;AAEF,SAAS,aAAa,CAAC,KAAgB,EAAE,IAAU,EAAE,OAA4B;IAC/E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,EAAE,CAAC;QAChE,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;YAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAS,CAAC;YACpC,yEAAyE;YACzE,0BAA0B;YAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS;YACzC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAEd,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvD,MAAM,OAAO,GACX,MAAM,CAAC,IAAI,KAAK,MAAM;gBACpB,CAAC,CAAC,0DAA0D;gBAC5D,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,cAAc,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;YAE/D,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC3B,OAAO,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,yBAAyB;gBAC1G,EAAE,EAAE,IAAI,CAAC,UAAU;gBACnB,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC7B,wEAAwE;gBACxE,mEAAmE;gBACnE,8BAA8B;gBAC9B,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC7G,IAAI,EAAE,iFAAiF,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,cAAc,EAAE;aACrK,CAAC,CAAC,CAAC;QACN,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,MAAsB,EAAE,IAAU;IACrD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;YAClC,OAAO,EAAE,IAAI,OAAO,CAAC,GAAG,wBAAwB;YAChD,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;YACrB,uEAAuE;YACvE,wEAAwE;YACxE,6BAA6B;YAC7B,MAAM,EAAE,OAAO,CAAC,GAAG;YACnB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,YAAY,OAAO,CAAC,UAAU,0DAA0D;SAC/F,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAsB,EAAE,IAAU;IAC1D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAClC,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;gBACjC,OAAO,EAAE,IAAI,GAAG,CAAC,MAAM,aAAa,GAAG,CAAC,UAAU,CAAC,MAAM,YAAY;gBACrE,EAAE,EAAE,GAAG,CAAC,UAAU;gBAClB,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;gBACjB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE,iCAAiC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aACnE,CAAC,CAAC,CAAC;YACJ,SAAS;QACX,CAAC;QAED,uEAAuE;QACvE,6EAA6E;QAC7E,4EAA4E;QAC5E,2EAA2E;QAC3E,kBAAkB;QAClB,MAAM,IAAI,GAAW,GAAG,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,kBAAkB,CAAC;QAEnG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YAChB,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC;YAC3B,EAAE,EAAE,GAAG,CAAC,UAAU;YAClB,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;YACjB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC;SACtB,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAgB;IACrC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,gBAAgB;YACnB,OAAO,IAAI,GAAG,CAAC,MAAM,2CAA2C,CAAC;QACnE,KAAK,YAAY;YACf,OAAO,IAAI,GAAG,CAAC,MAAM,kDAAkD,CAAC;QAC1E;YACE,OAAO,IAAI,GAAG,CAAC,MAAM,oCAAoC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,GAAgB;IAClC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,gBAAgB,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC/F,8EAA8E;IAC9E,4EAA4E;IAC5E,oDAAoD;IACpD,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChE,OAAO,uFAAuF,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;IACpI,CAAC;IACD,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,gBAAgB;YACnB,OAAO,qDAAqD,CAAC;QAC/D,KAAK,YAAY;YACf,0EAA0E;YAC1E,iEAAiE;YACjE,OAAO,wCAAwC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;QACxE;YACE,OAAO,kDAAkD,CAAC;IAC9D,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,MAAc;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACjC,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;AACvE,CAAC;AAED;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,GAAgB;IACtC,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACtE,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AACnE,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,SAAS,mBAAmB,CAAC,KAAgB,EAAE,IAAU;IACvD,MAAM,KAAK,GAAG,CAAC,GAAG,gBAAgB,EAAE,YAAqB,CAAC,CAAC;IAC3D,4EAA4E;IAC5E,6EAA6E;IAC7E,gDAAgD;IAChD,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,SAAS;aACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;aAC/B,MAAM,CAAC,CAAC,IAAI,EAAwB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAC9D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QACjC,6EAA6E;QAC7E,4EAA4E;QAC5E,8CAA8C;QAC9C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC;YAAE,SAAS;QAElE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;QAC/F,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAiB,CAAC;QAExC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;YACjC,OAAO,EAAE,gBAAgB;gBACvB,CAAC,CAAC,6BAA6B,OAAO,CAAC,MAAM,YAAY;gBACzD,CAAC,CAAC,2BAA2B,OAAO,CAAC,MAAM,yCAAyC;YACtF,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,IAAI,CAAC,EAAE;YACnC,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAClH,IAAI,EAAE,uEAAuE;SAC9E,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,KAAgB,EAAE,SAA4B,EAAE,KAA8B;IAChG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;IACzE,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,KAAgB,EAAE,IAAU,EAAE,UAAkB;IAC3E,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,KAAK,QAAQ;YAAE,SAAS;QAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACrF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEhC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;QACnE,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;YACjC,OAAO,EAAE,GAAG,MAAM,yBAAyB,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,EAAE;YACjH,EAAE,EAAE,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAAE;YACpC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO,EAAE,IAAI;iBACV,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;iBACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACvE,IAAI,EAAE,gEAAgE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,SAAS,QAAQ,CAAC,EAAE,EAAE;SACnJ,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,SAAS,aAAa,CAAC,KAAgB,EAAE,IAAU;IACjD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,SAAS;YAAE,SAAS;QAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW;YAAE,SAAS;QAC1C,iEAAiE;QACjE,yEAAyE;QACzE,yEAAyE;QACzE,yEAAyE;QACzE,oEAAoE;QACpE,IAAI,WAAW,CAAC,KAAK,KAAK,QAAQ;YAAE,SAAS;QAE7C,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACrE,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC/B,mEAAmE;gBACnE,4DAA4D;gBAC5D,OAAO,EAAE,GAAG,UAAU,CAAC,EAAE,qBAAqB,WAAW,CAAC,EAAE,uBAAuB,UAAU,CAAC,KAAK,EAAE;gBACrG,EAAE,EAAE,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,EAAE;gBACxC,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC;gBACtC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,mCAAmC,CAAC,CAAC;gBACxE,IAAI,EAAE,QAAQ,UAAU,CAAC,EAAE,wCAAwC,WAAW,CAAC,EAAE,EAAE;aACpF,CAAC,CAAC,CAAC;YACJ,SAAS;QACX,CAAC;QAED,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;gBACzC,OAAO,EAAE,GAAG,UAAU,CAAC,EAAE,mCAAmC,WAAW,CAAC,EAAE,cAAc;gBACxF,EAAE,EAAE,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,EAAE;gBACxC,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC;gBACtC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,WAAW,CAAC,EAAE,2BAA2B,CAAC,CAAC;gBACtF,IAAI,EAAE,uBAAuB,WAAW,CAAC,EAAE,QAAQ,UAAU,CAAC,IAAI,4CAA4C;aAC/G,CAAC,CAAC,CAAC;QACN,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,SAAS,cAAc,CAAC,KAAgB,EAAE,IAAU;IAClD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC1C,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5B,OAAO,EAAE,iBAAiB,IAAI,CAAC,WAAW,qBAAqB,eAAe,CAAC,IAAI,CAAC,EAAE;YACtF,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACpB,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAChB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACrC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACxG;YACD,IAAI,EAAE,qDAAqD,IAAI,CAAC,QAAQ,EAAE;SAC3E,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAc;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAChG,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AACvH,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,KAAgB,EAAE,IAAU;IAClD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QAC1D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,SAAS;QACjE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5B,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,SAAS;YACpD,EAAE,EAAE,IAAI,CAAC,UAAU;YACnB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;YAClB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,MAAM,CAAC,mBAAmB;gBAC9B,CAAC,CAAC,+FAA+F;gBACjG,CAAC,CAAC,sEAAsE;SAC3E,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,KAAgB,EAAE,KAA6B,EAAE,IAAU;IAClF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACjD,wEAAwE;gBACxE,wEAAwE;gBACxE,4BAA4B;gBAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAEd,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;gBACxC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;oBACnB,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC;oBACnD,sEAAsE;oBACtE,kEAAkE;oBAClE,+DAA+D;oBAC/D,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,IAAI,CAAC,EAAE;oBACzC,KAAK;oBACL,OAAO,EAAE,KAAK,CAAC,KAAK;yBACjB,KAAK,CAAC,CAAC,CAAC;yBACR,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;oBACtG,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;iBAC9C,CAAC,CAAC,CAAC;YACN,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,SAAS,QAAQ,CAAC,IAAc;IAC9B,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC;AAC9F,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAa;IAC3C,OAAO,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;AACxE,CAAC;AAED,SAAS,YAAY,CAAC,QAAkC;IACtD,OAAO,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,OAAO,CAAC,EAAa,EAAE,IAAY;IAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,cAAc,GAAuD,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAE1G;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,WAAkC;IAChE,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC3E,IAAI,UAAU,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC;QACxC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QACtG,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAC9G,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAA8C,MAAM,CAAC,MAAM,CAAC;IACnF,gBAAgB,EAAE,sFAAsF;IACxG,eAAe,EAAE,mFAAmF;IACpG,qBAAqB,EAAE,iEAAiE;IACxF,gBAAgB,EAAE,2EAA2E;CAC9F,CAAC,CAAC","sourcesContent":["/**\n * The built-in diagnostics.\n *\n * Two of them - the two the whole project exists for - are written as selector\n * queries rather than as bespoke traversals. That is not a stunt: it is the\n * proof that the query language is expressive enough to be worth exposing. A\n * team whose convention spec-graph never anticipated can write the equivalent\n * of a built-in rule on the command line.\n *\n * ```text\n * ghost-handover *[openness!=closed][phase!=retired] -delegates-to,blocked-by-> *[receptivity=sealed]\n * stale-premise *[phase!=retired] -depends-on,assumes,amends,blocked-by-> document[phase=retired]\n * ```\n *\n * The rest are not path queries and are not pretended to be: dangling\n * references never became edges, and a cycle is not a fixed-length path.\n *\n * Every rule here obeys one discipline - **report the place a human can fix**.\n * For a supersession that the superseded document never acknowledged, that is\n * the superseded document, not the one that declared the relation.\n */\n\nimport { OBLIGATION_EDGES, type SpecGraph } from './graph.js';\nimport { dirnamePosix, resolveFrom } from './paths.js';\nimport { renderTemplate, type ProjectRule } from './project-rules.js';\nimport { execute, parseQuery, type QuerySpec } from './select.js';\nimport type { ResolvedCorpus } from './resolve.js';\nimport type {\n AnyRuleId,\n DanglingRef,\n Diagnostic,\n DocumentNode,\n Edge,\n ItemNode,\n RelatedLocation,\n RuleId,\n Severity,\n SourceRef,\n SpecNode,\n} from './types.js';\nimport { EDGE_TRAITS } from './types.js';\n\n/* -------------------------------------------------------------------------- */\n/* Configuration */\n/* -------------------------------------------------------------------------- */\n\nexport const DEFAULT_SEVERITIES: Readonly<Record<RuleId, Severity>> = Object.freeze({\n 'ghost-handover': 'error',\n 'stale-premise': 'error',\n 'broken-reference': 'error',\n 'reference-outside-corpus': 'warn',\n 'ambiguous-reference': 'warn',\n 'circular-delegation': 'error',\n 'orphaned-obligation': 'error',\n 'live-supersession': 'error',\n 'unreciprocated-supersession': 'warn',\n 'state-conflict': 'warn',\n 'self-reference': 'info',\n 'unknown-relation-key': 'warn',\n});\n\nexport const RULE_IDS = Object.keys(DEFAULT_SEVERITIES) as readonly RuleId[];\n\n/** One-line descriptions, printed by `spec-graph rules`. */\nexport const RULE_DESCRIPTIONS: Readonly<Record<RuleId, string>> = Object.freeze({\n 'ghost-handover': 'an open obligation is handed to a document that can no longer absorb it',\n 'stale-premise': 'a live document rests on a decision that has been retired or obviated',\n 'broken-reference': 'a citation names a document or anchor that does not exist',\n 'reference-outside-corpus': 'a citation names a real document the include patterns did not reach',\n 'ambiguous-reference': 'a citation matches more than one document',\n 'circular-delegation': 'obligations or supersessions form a cycle, so none of them can ever land',\n 'orphaned-obligation': 'a retired or frozen document still holds open obligations',\n 'live-supersession': 'a document has been superseded but still presents itself as current',\n 'unreciprocated-supersession': 'a retired document does not say what replaced it',\n 'state-conflict': 'an item declares two states that disagree about whether work remains',\n 'self-reference': 'a document delegates to or depends on itself',\n 'unknown-relation-key': 'a front-matter key reads as a relation but declares none',\n});\n\n/**\n * The severity map `--strict` implies, and which rules it actually moved.\n *\n * Strict raises `warn` to `error` and leaves `info` alone. That asymmetry is\n * deliberate: the `info` rules are advisory by nature - a self-link in a table\n * of contents is a formatting quirk - and promoting them would resurrect\n * precisely the false-positive problem ADR-0006 exists to prevent.\n *\n * An explicit `--rule` always wins over strict, so `--strict --rule x=warn`\n * keeps `x` at warn. That is what makes strict usable: a team can turn it on\n * and exempt the one rule their repository disagrees with, rather than choosing\n * between all of it and none of it.\n */\nexport function resolveStrict(\n overrides: Partial<Record<AnyRuleId, Severity>> = {},\n strict = false,\n projectRules: readonly ProjectRule[] = [],\n): { severities: Partial<Record<AnyRuleId, Severity>>; escalated: ReadonlySet<AnyRuleId> } {\n const severities: Partial<Record<AnyRuleId, Severity>> = { ...overrides };\n const escalated = new Set<AnyRuleId>();\n if (!strict) return { severities, escalated };\n\n // A project rule is escalated on the same terms as a built-in, reading its\n // declared severity as the default. Anything else would mean a team could\n // adopt --strict and quietly keep their own conventions advisory.\n const defaults: [AnyRuleId, Severity][] = [\n ...RULE_IDS.map((id): [AnyRuleId, Severity] => [id, DEFAULT_SEVERITIES[id]]),\n ...projectRules.map((rule): [AnyRuleId, Severity] => [rule.id, rule.severity]),\n ];\n\n for (const [id, level] of defaults) {\n if (overrides[id] !== undefined) continue;\n if (level !== 'warn') continue;\n severities[id] = 'error';\n escalated.add(id);\n }\n return { severities, escalated };\n}\n\nexport interface RuleOptions {\n readonly severities?: Partial<Record<AnyRuleId, Severity>> | undefined;\n /** Cap on related locations attached to one finding. */\n readonly maxRelated?: number | undefined;\n /** Conventions the repository wrote for itself. See ADR-0016. */\n readonly projectRules?: readonly ProjectRule[] | undefined;\n}\n\nconst DEFAULT_MAX_RELATED = 8;\n\n/* -------------------------------------------------------------------------- */\n/* Entry point */\n/* -------------------------------------------------------------------------- */\n\n/** Runs every enabled rule and returns findings in report order. */\nexport function runRules(graph: SpecGraph, corpus: ResolvedCorpus, options: RuleOptions = {}): Diagnostic[] {\n const projectRules = options.projectRules ?? [];\n const severities: Partial<Record<AnyRuleId, Severity>> = { ...DEFAULT_SEVERITIES };\n // A project rule's declared severity is its default, and sits in the same\n // table the built-ins do - so `--rule`, `--strict` and `severities` reach it\n // by exactly the machinery they already had.\n for (const rule of projectRules) severities[rule.id] = rule.severity;\n Object.assign(severities, options.severities ?? {});\n const maxRelated = options.maxRelated ?? DEFAULT_MAX_RELATED;\n const out: Diagnostic[] = [];\n\n const emit = (rule: AnyRuleId, build: () => Built): void => {\n const severity = severities[rule];\n // The `undefined` arm is the type system talking, not a case: the table is\n // seeded from every built-in and every project rule, and nothing emits an\n // id that is in neither. Deliberately untested - a mutant that drops it is\n // equivalent, and a test asserting otherwise would be asserting a fiction.\n if (severity === undefined || severity === 'off') return;\n const body = build();\n if (exempt(graph, rule, body.nodes)) return;\n // `target` ahead of the spread: a rule that names one overrides the default,\n // and the eight that have nothing to name say nothing.\n out.push({ rule, severity, target: null, ...body, related: body.related.slice(0, maxRelated) });\n };\n\n // Ghost handovers are reported first and claim their edges, because\n // `blocked-by` is both obligation-transferring and load-bearing: without this,\n // one open question blocked by an archived decision would produce two\n // findings on the same line, for the same defect, with the same fix.\n const claimed = ghostHandovers(graph, emit);\n stalePremises(graph, emit, claimed);\n brokenReferences(corpus, emit);\n circularDelegations(graph, emit);\n orphanedObligations(graph, emit, maxRelated);\n supersessions(graph, emit);\n stateConflicts(graph, emit);\n misreadKeys(corpus, emit);\n selfReferences(graph, emit);\n projectFindings(graph, projectRules, emit);\n\n return sortDiagnostics(out);\n}\n\n/** What a rule returns: the finding, minus what `emit` knows better. */\ntype Built = Omit<Diagnostic, 'rule' | 'severity' | 'target'> & { readonly target?: string };\n\ntype Emit = (rule: AnyRuleId, build: () => Built) => void;\n\n/**\n * Rules about what a document cites, rather than about what it owes.\n *\n * These are the ones a historical record still answers for. A link that goes\n * nowhere is broken whoever wrote it and whenever they wrote it.\n */\nconst REFERENCE_RULES: ReadonlySet<AnyRuleId> = new Set<AnyRuleId>([\n 'broken-reference',\n 'reference-outside-corpus',\n 'ambiguous-reference',\n // A key that declares no relation is a citation that did not happen, which a\n // journal answers for as squarely as a link that goes nowhere. ADR-0011 keeps\n // a record's obligations out of the report, not its references.\n 'unknown-relation-key',\n]);\n\n/**\n * Whether a finding is about history rather than about work.\n *\n * A record reports that something was decided; it does not decide anything. Its\n * open checkboxes are minutes, its delegations are things that were said, and\n * its lifecycle is not a lifecycle. So a record is never the *subject* of a\n * finding about obligations or lifecycle - though it is still a legitimate\n * target of one, because delegating live work into a log is exactly the ghost\n * handover this tool exists to find.\n *\n * Stated once, here, rather than as a guard repeated in eight rules: the\n * exemption is a property of what counts as a finding, not of any one rule, and\n * a rule added later inherits it without having to remember. See ADR-0011.\n */\nfunction exempt(graph: SpecGraph, rule: AnyRuleId, nodes: readonly string[]): boolean {\n if (REFERENCE_RULES.has(rule)) return false;\n const subject = nodes[0];\n if (subject === undefined) return false;\n return graph.owningDocument(subject)?.phase === 'record';\n}\n\n/* -------------------------------------------------------------------------- */\n/* Ghost handovers */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The flagship failure mode: an obligation handed into a closed ledger.\n *\n * The source must still be open and must not itself be retired - a retired\n * document delegating to another retired document is history, not a defect,\n * and reporting it would bury the live findings underneath the archive.\n */\nconst GHOST_HANDOVER: QuerySpec = parseQuery(\n '*[openness!=closed][phase!=retired] -delegates-to,blocked-by-> *[receptivity=sealed]',\n);\n\n/** Emits ghost-handover findings and returns the edges they account for. */\nfunction ghostHandovers(graph: SpecGraph, emit: Emit): Set<string> {\n const claimed = new Set<string>();\n for (const match of execute(graph, GHOST_HANDOVER)) {\n const source = match.nodes[0] as SpecNode;\n const target = match.nodes[1] as SpecNode;\n const edge = match.edges[0] as Edge;\n const targetDocument = graph.owningDocument(target.id);\n if (!targetDocument) continue;\n\n const sealed = SEALED_WORD[targetDocument.phase] ?? 'frozen';\n const what = source.kind === 'item' ? 'open obligation' : 'obligation';\n const verb = EDGE_TRAITS[edge.kind].phrase;\n claimed.add(edgeKey(edge));\n\n emit('ghost-handover', () => ({\n message: `${what} ${verb} ${describe(target)}, which is ${sealed}`,\n at: edge.declaredAt,\n nodes: [source.id, target.id],\n related: [\n related(targetDocument.statusAt ?? targetDocument.at, `${targetDocument.id} is ${sealed}${statusSuffix(targetDocument)}`),\n ...(source.kind === 'item' ? [related(source.at, `the obligation: ${source.text}`)] : []),\n ],\n hint: HANDOVER_HINT[targetDocument.phase]?.(targetDocument.id) ?? FROZEN_HINT(targetDocument.id),\n }));\n }\n return claimed;\n}\n\n/** How a sealed target is described in a ghost-handover message. */\nconst SEALED_WORD: Readonly<Partial<Record<string, string>>> = {\n retired: 'retired',\n record: 'a historical record',\n};\n\nconst FROZEN_HINT = (id: string): string =>\n `${id} is frozen and cannot take on new work - open an amendment, or close this here`;\n\n/** What to do about work handed into each kind of sealed document. */\nconst HANDOVER_HINT: Readonly<Partial<Record<string, (id: string) => string>>> = {\n retired: (id) => `nothing will be read from ${id} again - re-home this in a live document, or close it here`,\n record: (id) => `${id} is a log of what happened and will never act - re-home this in a live document`,\n};\n\n/** Identity of a relation, for the hand-off between overlapping rules. */\nfunction edgeKey(edge: Edge): string {\n return `${edge.kind} ${edge.from} ${edge.to}`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Stale premises */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A live document resting on something that stopped being true.\n *\n * Only load-bearing relations count. A \"See also\" pointing at a superseded ADR\n * is ordinary cross-referencing; `assumes` pointing at the same document means\n * somebody is designing around a constraint that was abolished.\n */\nconst STALE_PREMISE_DOCUMENT: QuerySpec = parseQuery(\n '*[phase!=retired] -depends-on,assumes,amends,blocked-by-> document[phase=retired]',\n);\nconst STALE_PREMISE_ITEM: QuerySpec = parseQuery(\n '*[phase!=retired] -depends-on,assumes,amends,blocked-by-> item[state=obviated]',\n);\n\nfunction stalePremises(graph: SpecGraph, emit: Emit, claimed: ReadonlySet<string>): void {\n const seen = new Set<string>();\n for (const spec of [STALE_PREMISE_DOCUMENT, STALE_PREMISE_ITEM]) {\n for (const match of execute(graph, spec)) {\n const source = match.nodes[0] as SpecNode;\n const target = match.nodes[1] as SpecNode;\n const edge = match.edges[0] as Edge;\n // Already reported as a ghost handover, which says the same thing in the\n // terms the reader needs.\n if (claimed.has(edgeKey(edge))) continue;\n const key = `${source.id}>${target.id}>${edge.kind}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const targetDocument = graph.owningDocument(target.id);\n const because =\n target.kind === 'item'\n ? 'that question was obviated - its premise no longer holds'\n : `${target.id} is retired${statusSuffix(targetDocument)}`;\n\n emit('stale-premise', () => ({\n message: `${describe(source)} ${EDGE_TRAITS[edge.kind].phrase} ${describe(target)}, which no longer holds`,\n at: edge.declaredAt,\n nodes: [source.id, target.id],\n // Point at the status line when there is one: that is the sentence that\n // makes the premise stale, and repeating the document's first line\n // underneath it adds nothing.\n related: [related(target.kind === 'document' ? (targetDocument?.statusAt ?? target.at) : target.at, because)],\n hint: `re-check this dependency: the constraint it assumes may have been lifted when ${target.kind === 'item' ? 'the question closed' : `${target.id} was retired`}`,\n }));\n }\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Reference integrity */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Keys that read as relations and declared none.\n *\n * The only rule here that is about the text rather than about the graph, and it\n * earns the place by what its absence costs: the finding is that an edge the\n * author wrote down is *not* in the graph, and a missing edge is invisible in a\n * report that says everything is consistent. Nothing else would ever mention it.\n */\nfunction misreadKeys(corpus: ResolvedCorpus, emit: Emit): void {\n for (const misread of corpus.misreadKeys) {\n emit('unknown-relation-key', () => ({\n message: `\"${misread.key}\" declares no relation`,\n at: misread.at,\n nodes: [misread.from],\n // The key, so two misspellings in one document are two findings rather\n // than one with a count of two - `nodes` names the document and nothing\n // else here names which key.\n target: misread.key,\n related: [],\n hint: `spell it ${misread.suggestion}, or move it out of front matter if it is not a relation`,\n }));\n }\n}\n\nfunction brokenReferences(corpus: ResolvedCorpus, emit: Emit): void {\n for (const ref of corpus.dangling) {\n if (ref.reason === 'ambiguous') {\n emit('ambiguous-reference', () => ({\n message: `\"${ref.target}\" matches ${ref.candidates.length} documents`,\n at: ref.declaredAt,\n nodes: [ref.from],\n target: ref.target,\n related: [],\n hint: `disambiguate it - candidates: ${ref.candidates.join(', ')}`,\n }));\n continue;\n }\n\n // A link to a file that exists but was not included is a configuration\n // problem: the graph is not broken, the corpus is just incomplete. Reporting\n // it as an error means a repository whose specifications live somewhere the\n // default patterns miss fails on its first run, for something the user has\n // not done wrong.\n const rule: RuleId = ref.reason === 'not-a-spec' ? 'reference-outside-corpus' : 'broken-reference';\n\n emit(rule, () => ({\n message: brokenMessage(ref),\n at: ref.declaredAt,\n nodes: [ref.from],\n target: ref.target,\n related: [],\n hint: brokenHint(ref),\n }));\n }\n}\n\nfunction brokenMessage(ref: DanglingRef): string {\n switch (ref.reason) {\n case 'unknown-anchor':\n return `\"${ref.target}\" points at an anchor that does not exist`;\n case 'not-a-spec':\n return `\"${ref.target}\" resolves to a file that is not a specification`;\n default:\n return `\"${ref.target}\" does not resolve to any document`;\n }\n}\n\nfunction brokenHint(ref: DanglingRef): string {\n if (ref.candidates.length > 0) return `did you mean ${ref.candidates.slice(0, 3).join(', ')}?`;\n // A wiki link carries no path, only a name, so whether it means a document at\n // all is a repository convention. Naming the flag here is what keeps that a\n // one-run discovery rather than a support question.\n if (ref.raw.startsWith('[[') && ref.reason === 'unknown-target') {\n return `fix the identifier, or - if [[...]] tags a concept here - exclude it: --ignore-ref \"${suggestReferenceGlob(ref.target)}\"`;\n }\n switch (ref.reason) {\n case 'unknown-anchor':\n return 'check the heading or item id it is meant to address';\n case 'not-a-spec':\n // Name the pattern that would include it: \"widen your patterns\" is advice\n // the reader then has to translate, and this is the translation.\n return `include it, for example: spec-graph \"${suggestPattern(ref)}\"`;\n default:\n return 'fix the identifier, or add the document it names';\n }\n}\n\n/**\n * A glob covering the family of concept tags a target belongs to.\n *\n * `trap 55` suggests `trap *` rather than `trap 55`, because these tags come in\n * numbered series and excluding them one at a time is not a fix anybody would\n * accept. A target with no trailing number is suggested verbatim.\n */\nfunction suggestReferenceGlob(target: string): string {\n const trimmed = target.trim();\n const series = /^(.*?)[\\s._-]*\\d+$/.exec(trimmed);\n const stem = series?.[1]?.trim();\n return stem !== undefined && stem.length > 0 ? `${stem} *` : trimmed;\n}\n\n/**\n * The narrowest include pattern that would reach a target the corpus missed.\n *\n * Built from the *resolved* repository-relative path, not the link as written:\n * `../notes.md` cited from `docs/adr/` needs `docs/**\\/*.md`, and suggesting\n * `../**\\/*.md` would be worse than saying nothing.\n */\nfunction suggestPattern(ref: DanglingRef): string {\n const withoutAnchor = (ref.target.split('#')[0] ?? ref.target).trim();\n const resolved = resolveFrom(ref.declaredAt.file, withoutAnchor);\n const directory = dirnamePosix(resolved);\n return directory.length > 0 ? `${directory}/**/*.md` : '**/*.md';\n}\n\n/* -------------------------------------------------------------------------- */\n/* Cycles */\n/* -------------------------------------------------------------------------- */\n\nfunction circularDelegations(graph: SpecGraph, emit: Emit): void {\n const kinds = [...OBLIGATION_EDGES, 'supersedes' as const];\n // Projected onto documents, so a question handed back and forth between two\n // of them is found even though each delegation runs item -> document and the\n // raw graph therefore contains no cycle at all.\n for (const component of graph.cycles(kinds, { byDocument: true })) {\n const members = component\n .map((id) => graph.document(id))\n .filter((node): node is DocumentNode => node !== undefined);\n if (members.length < 2) continue;\n // A cycle is a set, not a subject, so the exemption at `emit` cannot see it.\n // One record in the loop means the loop is partly a report of what was once\n // said, and nothing in it is owed by anybody.\n if (members.some((member) => member.phase === 'record')) continue;\n\n const edges = cycleEdges(graph, component, kinds);\n const onlySupersession = edges.length > 0 && edges.every((edge) => edge.kind === 'supersedes');\n const head = members[0] as DocumentNode;\n\n emit('circular-delegation', () => ({\n message: onlySupersession\n ? `supersession cycle across ${members.length} documents`\n : `delegation cycle across ${members.length} documents: nothing in it can ever land`,\n at: edges[0]?.declaredAt ?? head.at,\n nodes: component,\n related: edges.map((edge) => related(edge.declaredAt, `${edge.from} ${EDGE_TRAITS[edge.kind].phrase} ${edge.to}`)),\n hint: 'break the loop: one of these must own the work outright, or be closed',\n }));\n }\n}\n\n/**\n * The relations that keep a component strongly connected.\n *\n * Membership is by owning document, because the component is a projection: the\n * edge that closes the loop is usually written on an item, and that is the line\n * the report has to point at.\n */\nfunction cycleEdges(graph: SpecGraph, component: readonly string[], kinds: readonly Edge['kind'][]): Edge[] {\n const inside = new Set(component);\n const owner = (id: string): string => graph.owningDocument(id)?.id ?? id;\n const out: Edge[] = [];\n for (const edge of graph.edges) {\n if (!kinds.includes(edge.kind)) continue;\n const from = owner(edge.from);\n const to = owner(edge.to);\n if (from !== to && inside.has(from) && inside.has(to)) out.push(edge);\n }\n return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Orphaned obligations */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The black hole itself: a document nobody reads any more, still holding work.\n *\n * Reported once per document rather than once per item. Five findings that all\n * say \"this archived ADR has open questions\" is five times the noise and none\n * of the extra information.\n */\nfunction orphanedObligations(graph: SpecGraph, emit: Emit, maxRelated: number): void {\n for (const document of graph.documents) {\n if (document.phase !== 'retired' && document.phase !== 'frozen') continue;\n const open = graph.itemsOf(document.id).filter((item) => item.openness !== 'closed');\n if (open.length === 0) continue;\n\n const sealed = document.phase === 'retired' ? 'retired' : 'frozen';\n emit('orphaned-obligation', () => ({\n message: `${sealed} document still holds ${open.length} open ${open.length === 1 ? 'obligation' : 'obligations'}`,\n at: document.statusAt ?? document.at,\n nodes: [document.id, ...open.map((item) => item.id)],\n related: open\n .slice(0, maxRelated)\n .map((item) => related(item.at, `${item.disposition}: ${item.text}`)),\n hint: `move each one to a live document or close it - as it stands, ${open.length === 1 ? 'it disappears' : 'they disappear'} with ${document.id}`,\n }));\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Supersession consistency */\n/* -------------------------------------------------------------------------- */\n\nfunction supersessions(graph: SpecGraph, emit: Emit): void {\n for (const edge of graph.edges) {\n if (edge.kind !== 'supersedes' || edge.reflexive) continue;\n const superseded = graph.document(edge.to);\n const superseding = graph.document(edge.from);\n if (!superseded || !superseding) continue;\n // A record narrating \"ADR-0005 replaced ADR-0001\" is reporting a\n // supersession, not declaring one. Both hints below ask somebody to edit\n // the document that made the claim, and a log is the one document nobody\n // can edit - it says what was true when it was written. The exemption at\n // `emit` cannot see this: the subject here is the *other* document.\n if (superseding.phase === 'record') continue;\n\n if (superseded.phase !== 'retired' && superseded.phase !== 'unknown') {\n emit('live-supersession', () => ({\n // The fix belongs in the superseded document, so that is where the\n // finding points - not at the document that made the claim.\n message: `${superseded.id} is superseded by ${superseding.id} but still reads as ${superseded.phase}`,\n at: superseded.statusAt ?? superseded.at,\n nodes: [superseded.id, superseding.id],\n related: [related(edge.declaredAt, `the supersession is declared here`)],\n hint: `mark ${superseded.id} as superseded, or drop the claim in ${superseding.id}`,\n }));\n continue;\n }\n\n if (superseded.phase === 'retired' && !edge.declaredIn.includes(superseded.path)) {\n emit('unreciprocated-supersession', () => ({\n message: `${superseded.id} is retired but never says that ${superseding.id} replaced it`,\n at: superseded.statusAt ?? superseded.at,\n nodes: [superseded.id, superseding.id],\n related: [related(edge.declaredAt, `only ${superseding.id} records the relationship`)],\n hint: `add \"superseded-by: ${superseding.id}\" to ${superseded.path} so a reader who lands there is redirected`,\n }));\n }\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Item state */\n/* -------------------------------------------------------------------------- */\n\nfunction stateConflicts(graph: SpecGraph, emit: Emit): void {\n for (const item of graph.items) {\n if (item.conflicts.length === 0) continue;\n emit('state-conflict', () => ({\n message: `item reads as ${item.disposition} but also carries ${describeSignals(item)}`,\n at: item.evidence.at,\n nodes: [item.id],\n related: item.conflicts.map((signal) =>\n related(signal.at, `${signal.source} says ${signal.disposition}${signal.raw ? `: ${signal.raw}` : ''}`),\n ),\n hint: `make the two agree - spec-graph is treating it as ${item.openness}`,\n }));\n }\n}\n\nfunction describeSignals(item: ItemNode): string {\n const parts = item.conflicts.map((signal) => `a ${signal.source} saying ${signal.disposition}`);\n return parts.length === 1 ? (parts[0] as string) : `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Self references */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A document that delegates to, or depends on, itself.\n *\n * Almost always a copied link that was never repointed. Informational, because\n * a self-link in a table of contents is harmless - but a *delegation* to self\n * means an obligation that looks handed off and was not.\n */\nfunction selfReferences(graph: SpecGraph, emit: Emit): void {\n for (const edge of graph.edges) {\n if (!edge.reflexive || edge.kind === 'contains') continue;\n const traits = EDGE_TRAITS[edge.kind];\n if (!traits.transfersObligation && !traits.loadBearing) continue;\n const node = graph.node(edge.from);\n if (!node) continue;\n\n emit('self-reference', () => ({\n message: `${describe(node)} ${traits.phrase} itself`,\n at: edge.declaredAt,\n nodes: [edge.from],\n related: [],\n hint: traits.transfersObligation\n ? 'this obligation looks delegated but never left - point it at another document, or own it here'\n : 'a document cannot depend on itself - repoint or remove the reference',\n }));\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Project rules */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The conventions a repository wrote for itself.\n *\n * Run last, and through the same `emit` as everything else, which is the whole\n * point: a project rule inherits the record exemption, the severity table,\n * `--strict`, the related-location cap, the sort order and the baseline without\n * any of them being taught about it. See ADR-0016.\n */\nfunction projectFindings(graph: SpecGraph, rules: readonly ProjectRule[], emit: Emit): void {\n for (const rule of rules) {\n const seen = new Set<string>();\n for (const spec of rule.queries) {\n for (const match of execute(graph, spec)) {\n const nodes = match.nodes.map((node) => node.id);\n // Two selectors in one rule are a union, so a path both of them find is\n // one finding. The alternative is a repository being told twice about a\n // convention it broke once.\n const key = nodes.join('>');\n if (seen.has(key)) continue;\n seen.add(key);\n\n const head = match.nodes[0] as SpecNode;\n emit(rule.id, () => ({\n message: renderTemplate(rule.message, match, graph),\n // The line that declares the relation, not the document it points at:\n // that is where a human goes to change the answer. A rule with no\n // steps has no relation, so it points at the node it selected.\n at: match.edges[0]?.declaredAt ?? head.at,\n nodes,\n related: match.edges\n .slice(1)\n .map((edge) => related(edge.declaredAt, `${edge.from} ${EDGE_TRAITS[edge.kind].phrase} ${edge.to}`)),\n hint: renderTemplate(rule.hint, match, graph),\n }));\n }\n }\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction describe(node: SpecNode): string {\n return node.kind === 'document' ? node.id : `${node.document} \"${truncate(node.text, 48)}\"`;\n}\n\nfunction truncate(text: string, limit: number): string {\n return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;\n}\n\nfunction statusSuffix(document: DocumentNode | undefined): string {\n return document?.rawStatus ? ` (\"${document.rawStatus}\")` : '';\n}\n\nfunction related(at: SourceRef, note: string): RelatedLocation {\n return { at, note };\n}\n\nconst SEVERITY_ORDER: Readonly<Record<Exclude<Severity, 'off'>, number>> = { error: 0, warn: 1, info: 2 };\n\n/**\n * Total ordering, so two runs on the same corpus produce byte-identical output.\n *\n * CI output that reorders between runs cannot be diffed, and output that cannot\n * be diffed stops being read.\n */\nexport function sortDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n return [...diagnostics].sort((a, b) => {\n const bySeverity = SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity];\n if (bySeverity !== 0) return bySeverity;\n if (a.at.file !== b.at.file) return a.at.file < b.at.file ? -1 : 1;\n if (a.at.span.start.line !== b.at.span.start.line) return a.at.span.start.line - b.at.span.start.line;\n if (a.at.span.start.column !== b.at.span.start.column) return a.at.span.start.column - b.at.span.start.column;\n if (a.rule !== b.rule) return a.rule < b.rule ? -1 : 1;\n return a.message < b.message ? -1 : a.message > b.message ? 1 : 0;\n });\n}\n\n/** The selector equivalent of a rule, for `spec-graph rules --explain`. */\nexport const RULE_QUERIES: Readonly<Partial<Record<RuleId, string>>> = Object.freeze({\n 'ghost-handover': '*[openness!=closed][phase!=retired] -delegates-to,blocked-by-> *[receptivity=sealed]',\n 'stale-premise': '*[phase!=retired] -depends-on,assumes,amends,blocked-by-> document[phase=retired]',\n 'orphaned-obligation': 'document[receptivity=sealed] -contains-> item[openness!=closed]',\n 'self-reference': 'see --format json; reflexive edges are excluded from traversal by default',\n});\n"]}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The built-in diagnostics.\n *\n * Two of them - the two the whole project exists for - are written as selector\n * queries rather than as bespoke traversals. That is not a stunt: it is the\n * proof that the query language is expressive enough to be worth exposing. A\n * team whose convention spec-graph never anticipated can write the equivalent\n * of a built-in rule on the command line.\n *\n * ```text\n * ghost-handover *[openness!=closed][phase!=retired] -delegates-to,blocked-by-> *[receptivity=sealed]\n * stale-premise *[phase!=retired] -depends-on,assumes,amends,blocked-by-> document[phase=retired]\n * ```\n *\n * The rest are not path queries and are not pretended to be: dangling\n * references never became edges, and a cycle is not a fixed-length path.\n *\n * Every rule here obeys one discipline - **report the place a human can fix**.\n * For a supersession that the superseded document never acknowledged, that is\n * the superseded document, not the one that declared the relation.\n */\n\nimport { OBLIGATION_EDGES, type SpecGraph } from './graph.js';\nimport { dirnamePosix, resolveFrom } from './paths.js';\nimport { renderTemplate, type ProjectRule } from './project-rules.js';\nimport { execute, parseQuery, type QuerySpec } from './select.js';\nimport type { ResolvedCorpus } from './resolve.js';\nimport type {\n AnyRuleId,\n DanglingRef,\n Diagnostic,\n DocumentNode,\n Edge,\n ItemNode,\n RelatedLocation,\n RuleId,\n Severity,\n SourceRef,\n SpecNode,\n} from './types.js';\nimport { EDGE_TRAITS } from './types.js';\n\n/* -------------------------------------------------------------------------- */\n/* Configuration */\n/* -------------------------------------------------------------------------- */\n\nexport const DEFAULT_SEVERITIES: Readonly<Record<RuleId, Severity>> = Object.freeze({\n 'ghost-handover': 'error',\n 'stale-premise': 'error',\n 'broken-reference': 'error',\n 'reference-outside-corpus': 'warn',\n 'ambiguous-reference': 'warn',\n 'circular-delegation': 'error',\n 'orphaned-obligation': 'error',\n 'live-supersession': 'error',\n 'unreciprocated-supersession': 'warn',\n 'state-conflict': 'warn',\n 'self-reference': 'info',\n 'unknown-relation-key': 'warn',\n});\n\nexport const RULE_IDS = Object.keys(DEFAULT_SEVERITIES) as readonly RuleId[];\n\n/** One-line descriptions, printed by `spec-graph rules`. */\nexport const RULE_DESCRIPTIONS: Readonly<Record<RuleId, string>> = Object.freeze({\n 'ghost-handover': 'an open obligation is handed to a document that can no longer absorb it',\n 'stale-premise': 'a live document rests on a decision that has been retired or obviated',\n 'broken-reference': 'a citation names a document or anchor that does not exist',\n 'reference-outside-corpus': 'a citation names a real document the include patterns did not reach',\n 'ambiguous-reference': 'a citation matches more than one document',\n 'circular-delegation': 'obligations or supersessions form a cycle, so none of them can ever land',\n 'orphaned-obligation': 'a retired or frozen document still holds open obligations',\n 'live-supersession': 'a document has been superseded but still presents itself as current',\n 'unreciprocated-supersession': 'a retired document does not say what replaced it',\n 'state-conflict': 'an item declares two states that disagree about whether work remains',\n 'self-reference': 'a document delegates to or depends on itself',\n 'unknown-relation-key': 'a front-matter key reads as a relation but declares none',\n});\n\n/**\n * The decision behind each rule.\n *\n * A rule that fires is a claim about somebody's repository, and the reasoning\n * for the claim is written down - in the ADR that decided it, not in a string\n * table. So the table holds a pointer rather than a paraphrase: a second copy\n * of the reasoning would drift from the first, and the first is the one\n * `npm run selfcheck` keeps honest.\n *\n * Printed by `spec-graph rules --explain`, which is how somebody who has just\n * been told their document is inconsistent finds out why anybody decided that.\n */\nexport const RULE_DECISIONS: Readonly<Record<RuleId, string>> = Object.freeze({\n 'ghost-handover': 'docs/adr/0002-lifecycle-lattice.md',\n 'stale-premise': 'docs/adr/0002-lifecycle-lattice.md',\n 'broken-reference': 'docs/adr/0004-reference-resolution.md',\n 'reference-outside-corpus': 'docs/adr/0004-reference-resolution.md',\n 'ambiguous-reference': 'docs/adr/0004-reference-resolution.md',\n 'circular-delegation': 'docs/adr/0005-rules-are-queries.md',\n 'orphaned-obligation': 'docs/adr/0003-item-state-signals.md',\n 'live-supersession': 'docs/adr/0002-lifecycle-lattice.md',\n 'unreciprocated-supersession': 'docs/adr/0006-false-positives-cost-more.md',\n 'state-conflict': 'docs/adr/0003-item-state-signals.md',\n 'self-reference': 'docs/adr/0006-false-positives-cost-more.md',\n 'unknown-relation-key': 'docs/adr/0014-a-relation-is-spelled-both-ways.md',\n});\n\n/**\n * The severity map `--strict` implies, and which rules it actually moved.\n *\n * Strict raises `warn` to `error` and leaves `info` alone. That asymmetry is\n * deliberate: the `info` rules are advisory by nature - a self-link in a table\n * of contents is a formatting quirk - and promoting them would resurrect\n * precisely the false-positive problem ADR-0006 exists to prevent.\n *\n * An explicit `--rule` always wins over strict, so `--strict --rule x=warn`\n * keeps `x` at warn. That is what makes strict usable: a team can turn it on\n * and exempt the one rule their repository disagrees with, rather than choosing\n * between all of it and none of it.\n */\nexport function resolveStrict(\n overrides: Partial<Record<AnyRuleId, Severity>> = {},\n strict = false,\n projectRules: readonly ProjectRule[] = [],\n): { severities: Partial<Record<AnyRuleId, Severity>>; escalated: ReadonlySet<AnyRuleId> } {\n const severities: Partial<Record<AnyRuleId, Severity>> = { ...overrides };\n const escalated = new Set<AnyRuleId>();\n if (!strict) return { severities, escalated };\n\n // A project rule is escalated on the same terms as a built-in, reading its\n // declared severity as the default. Anything else would mean a team could\n // adopt --strict and quietly keep their own conventions advisory.\n const defaults: [AnyRuleId, Severity][] = [\n ...RULE_IDS.map((id): [AnyRuleId, Severity] => [id, DEFAULT_SEVERITIES[id]]),\n ...projectRules.map((rule): [AnyRuleId, Severity] => [rule.id, rule.severity]),\n ];\n\n for (const [id, level] of defaults) {\n if (overrides[id] !== undefined) continue;\n if (level !== 'warn') continue;\n severities[id] = 'error';\n escalated.add(id);\n }\n return { severities, escalated };\n}\n\nexport interface RuleOptions {\n readonly severities?: Partial<Record<AnyRuleId, Severity>> | undefined;\n /** Cap on related locations attached to one finding. */\n readonly maxRelated?: number | undefined;\n /** Conventions the repository wrote for itself. See ADR-0016. */\n readonly projectRules?: readonly ProjectRule[] | undefined;\n}\n\nconst DEFAULT_MAX_RELATED = 8;\n\n/* -------------------------------------------------------------------------- */\n/* Entry point */\n/* -------------------------------------------------------------------------- */\n\n/** Runs every enabled rule and returns findings in report order. */\nexport function runRules(graph: SpecGraph, corpus: ResolvedCorpus, options: RuleOptions = {}): Diagnostic[] {\n const projectRules = options.projectRules ?? [];\n const severities: Partial<Record<AnyRuleId, Severity>> = { ...DEFAULT_SEVERITIES };\n // A project rule's declared severity is its default, and sits in the same\n // table the built-ins do - so `--rule`, `--strict` and `severities` reach it\n // by exactly the machinery they already had.\n for (const rule of projectRules) severities[rule.id] = rule.severity;\n Object.assign(severities, options.severities ?? {});\n const maxRelated = options.maxRelated ?? DEFAULT_MAX_RELATED;\n const out: Diagnostic[] = [];\n\n const emit = (rule: AnyRuleId, build: () => Built): void => {\n const severity = severities[rule];\n // The `undefined` arm is the type system talking, not a case: the table is\n // seeded from every built-in and every project rule, and nothing emits an\n // id that is in neither. Deliberately untested - a mutant that drops it is\n // equivalent, and a test asserting otherwise would be asserting a fiction.\n if (severity === undefined || severity === 'off') return;\n const body = build();\n if (exempt(graph, rule, body.nodes)) return;\n // `target` ahead of the spread: a rule that names one overrides the default,\n // and the eight that have nothing to name say nothing.\n out.push({ rule, severity, target: null, ...body, related: body.related.slice(0, maxRelated) });\n };\n\n // Ghost handovers are reported first and claim their edges, because\n // `blocked-by` is both obligation-transferring and load-bearing: without this,\n // one open question blocked by an archived decision would produce two\n // findings on the same line, for the same defect, with the same fix.\n const claimed = ghostHandovers(graph, emit);\n stalePremises(graph, emit, claimed);\n brokenReferences(corpus, emit);\n circularDelegations(graph, emit);\n orphanedObligations(graph, emit, maxRelated);\n supersessions(graph, emit);\n stateConflicts(graph, emit);\n misreadKeys(corpus, emit);\n selfReferences(graph, emit);\n projectFindings(graph, projectRules, emit);\n\n return sortDiagnostics(out);\n}\n\n/** What a rule returns: the finding, minus what `emit` knows better. */\ntype Built = Omit<Diagnostic, 'rule' | 'severity' | 'target'> & { readonly target?: string };\n\ntype Emit = (rule: AnyRuleId, build: () => Built) => void;\n\n/**\n * Rules about what a document cites, rather than about what it owes.\n *\n * These are the ones a historical record still answers for. A link that goes\n * nowhere is broken whoever wrote it and whenever they wrote it.\n */\nconst REFERENCE_RULES: ReadonlySet<AnyRuleId> = new Set<AnyRuleId>([\n 'broken-reference',\n 'reference-outside-corpus',\n 'ambiguous-reference',\n // A key that declares no relation is a citation that did not happen, which a\n // journal answers for as squarely as a link that goes nowhere. ADR-0011 keeps\n // a record's obligations out of the report, not its references.\n 'unknown-relation-key',\n]);\n\n/**\n * Whether a finding is about history rather than about work.\n *\n * A record reports that something was decided; it does not decide anything. Its\n * open checkboxes are minutes, its delegations are things that were said, and\n * its lifecycle is not a lifecycle. So a record is never the *subject* of a\n * finding about obligations or lifecycle - though it is still a legitimate\n * target of one, because delegating live work into a log is exactly the ghost\n * handover this tool exists to find.\n *\n * Stated once, here, rather than as a guard repeated in eight rules: the\n * exemption is a property of what counts as a finding, not of any one rule, and\n * a rule added later inherits it without having to remember. See ADR-0011.\n */\nfunction exempt(graph: SpecGraph, rule: AnyRuleId, nodes: readonly string[]): boolean {\n if (REFERENCE_RULES.has(rule)) return false;\n const subject = nodes[0];\n if (subject === undefined) return false;\n return graph.owningDocument(subject)?.phase === 'record';\n}\n\n/* -------------------------------------------------------------------------- */\n/* Ghost handovers */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The flagship failure mode: an obligation handed into a closed ledger.\n *\n * The source must still be open and must not itself be retired - a retired\n * document delegating to another retired document is history, not a defect,\n * and reporting it would bury the live findings underneath the archive.\n */\nconst GHOST_HANDOVER: QuerySpec = parseQuery(\n '*[openness!=closed][phase!=retired] -delegates-to,blocked-by-> *[receptivity=sealed]',\n);\n\n/** Emits ghost-handover findings and returns the edges they account for. */\nfunction ghostHandovers(graph: SpecGraph, emit: Emit): Set<string> {\n const claimed = new Set<string>();\n for (const match of execute(graph, GHOST_HANDOVER)) {\n const source = match.nodes[0] as SpecNode;\n const target = match.nodes[1] as SpecNode;\n const edge = match.edges[0] as Edge;\n const targetDocument = graph.owningDocument(target.id);\n if (!targetDocument) continue;\n\n const sealed = SEALED_WORD[targetDocument.phase] ?? 'frozen';\n const what = source.kind === 'item' ? 'open obligation' : 'obligation';\n const verb = EDGE_TRAITS[edge.kind].phrase;\n claimed.add(edgeKey(edge));\n\n emit('ghost-handover', () => ({\n message: `${what} ${verb} ${describe(target)}, which is ${sealed}`,\n at: edge.declaredAt,\n nodes: [source.id, target.id],\n related: [\n related(targetDocument.statusAt ?? targetDocument.at, `${targetDocument.id} is ${sealed}${statusSuffix(targetDocument)}`),\n ...(source.kind === 'item' ? [related(source.at, `the obligation: ${source.text}`)] : []),\n ],\n hint: HANDOVER_HINT[targetDocument.phase]?.(targetDocument.id) ?? FROZEN_HINT(targetDocument.id),\n }));\n }\n return claimed;\n}\n\n/** How a sealed target is described in a ghost-handover message. */\nconst SEALED_WORD: Readonly<Partial<Record<string, string>>> = {\n retired: 'retired',\n record: 'a historical record',\n};\n\nconst FROZEN_HINT = (id: string): string =>\n `${id} is frozen and cannot take on new work - open an amendment, or close this here`;\n\n/** What to do about work handed into each kind of sealed document. */\nconst HANDOVER_HINT: Readonly<Partial<Record<string, (id: string) => string>>> = {\n retired: (id) => `nothing will be read from ${id} again - re-home this in a live document, or close it here`,\n record: (id) => `${id} is a log of what happened and will never act - re-home this in a live document`,\n};\n\n/** Identity of a relation, for the hand-off between overlapping rules. */\nfunction edgeKey(edge: Edge): string {\n return `${edge.kind} ${edge.from} ${edge.to}`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Stale premises */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A live document resting on something that stopped being true.\n *\n * Only load-bearing relations count. A \"See also\" pointing at a superseded ADR\n * is ordinary cross-referencing; `assumes` pointing at the same document means\n * somebody is designing around a constraint that was abolished.\n */\nconst STALE_PREMISE_DOCUMENT: QuerySpec = parseQuery(\n '*[phase!=retired] -depends-on,assumes,amends,blocked-by-> document[phase=retired]',\n);\nconst STALE_PREMISE_ITEM: QuerySpec = parseQuery(\n '*[phase!=retired] -depends-on,assumes,amends,blocked-by-> item[state=obviated]',\n);\n\nfunction stalePremises(graph: SpecGraph, emit: Emit, claimed: ReadonlySet<string>): void {\n const seen = new Set<string>();\n for (const spec of [STALE_PREMISE_DOCUMENT, STALE_PREMISE_ITEM]) {\n for (const match of execute(graph, spec)) {\n const source = match.nodes[0] as SpecNode;\n const target = match.nodes[1] as SpecNode;\n const edge = match.edges[0] as Edge;\n // Already reported as a ghost handover, which says the same thing in the\n // terms the reader needs.\n if (claimed.has(edgeKey(edge))) continue;\n const key = `${source.id}>${target.id}>${edge.kind}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const targetDocument = graph.owningDocument(target.id);\n const because =\n target.kind === 'item'\n ? 'that question was obviated - its premise no longer holds'\n : `${target.id} is retired${statusSuffix(targetDocument)}`;\n\n emit('stale-premise', () => ({\n message: `${describe(source)} ${EDGE_TRAITS[edge.kind].phrase} ${describe(target)}, which no longer holds`,\n at: edge.declaredAt,\n nodes: [source.id, target.id],\n // Point at the status line when there is one: that is the sentence that\n // makes the premise stale, and repeating the document's first line\n // underneath it adds nothing.\n related: [related(target.kind === 'document' ? (targetDocument?.statusAt ?? target.at) : target.at, because)],\n hint: `re-check this dependency: the constraint it assumes may have been lifted when ${target.kind === 'item' ? 'the question closed' : `${target.id} was retired`}`,\n }));\n }\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Reference integrity */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Keys that read as relations and declared none.\n *\n * The only rule here that is about the text rather than about the graph, and it\n * earns the place by what its absence costs: the finding is that an edge the\n * author wrote down is *not* in the graph, and a missing edge is invisible in a\n * report that says everything is consistent. Nothing else would ever mention it.\n */\nfunction misreadKeys(corpus: ResolvedCorpus, emit: Emit): void {\n for (const misread of corpus.misreadKeys) {\n emit('unknown-relation-key', () => ({\n message: `\"${misread.key}\" declares no relation`,\n at: misread.at,\n nodes: [misread.from],\n // The key, so two misspellings in one document are two findings rather\n // than one with a count of two - `nodes` names the document and nothing\n // else here names which key.\n target: misread.key,\n related: [],\n hint: `spell it ${misread.suggestion}, or move it out of front matter if it is not a relation`,\n }));\n }\n}\n\nfunction brokenReferences(corpus: ResolvedCorpus, emit: Emit): void {\n for (const ref of corpus.dangling) {\n if (ref.reason === 'ambiguous') {\n emit('ambiguous-reference', () => ({\n message: `\"${ref.target}\" matches ${ref.candidates.length} documents`,\n at: ref.declaredAt,\n nodes: [ref.from],\n target: ref.target,\n related: [],\n hint: `disambiguate it - candidates: ${ref.candidates.join(', ')}`,\n }));\n continue;\n }\n\n // A link to a file that exists but was not included is a configuration\n // problem: the graph is not broken, the corpus is just incomplete. Reporting\n // it as an error means a repository whose specifications live somewhere the\n // default patterns miss fails on its first run, for something the user has\n // not done wrong.\n const rule: RuleId = ref.reason === 'not-a-spec' ? 'reference-outside-corpus' : 'broken-reference';\n\n emit(rule, () => ({\n message: brokenMessage(ref),\n at: ref.declaredAt,\n nodes: [ref.from],\n target: ref.target,\n related: [],\n hint: brokenHint(ref),\n }));\n }\n}\n\nfunction brokenMessage(ref: DanglingRef): string {\n switch (ref.reason) {\n case 'unknown-anchor':\n return `\"${ref.target}\" points at an anchor that does not exist`;\n case 'not-a-spec':\n return `\"${ref.target}\" resolves to a file that is not a specification`;\n default:\n return `\"${ref.target}\" does not resolve to any document`;\n }\n}\n\nfunction brokenHint(ref: DanglingRef): string {\n if (ref.candidates.length > 0) return `did you mean ${ref.candidates.slice(0, 3).join(', ')}?`;\n // A wiki link carries no path, only a name, so whether it means a document at\n // all is a repository convention. Naming the flag here is what keeps that a\n // one-run discovery rather than a support question.\n if (ref.raw.startsWith('[[') && ref.reason === 'unknown-target') {\n return `fix the identifier, or - if [[...]] tags a concept here - exclude it: --ignore-ref \"${suggestReferenceGlob(ref.target)}\"`;\n }\n switch (ref.reason) {\n case 'unknown-anchor':\n return 'check the heading or item id it is meant to address';\n case 'not-a-spec':\n // Name the pattern that would include it: \"widen your patterns\" is advice\n // the reader then has to translate, and this is the translation.\n return `include it, for example: spec-graph \"${suggestPattern(ref)}\"`;\n default:\n return 'fix the identifier, or add the document it names';\n }\n}\n\n/**\n * A glob covering the family of concept tags a target belongs to.\n *\n * `trap 55` suggests `trap *` rather than `trap 55`, because these tags come in\n * numbered series and excluding them one at a time is not a fix anybody would\n * accept. A target with no trailing number is suggested verbatim.\n */\nfunction suggestReferenceGlob(target: string): string {\n const trimmed = target.trim();\n const series = /^(.*?)[\\s._-]*\\d+$/.exec(trimmed);\n const stem = series?.[1]?.trim();\n return stem !== undefined && stem.length > 0 ? `${stem} *` : trimmed;\n}\n\n/**\n * The narrowest include pattern that would reach a target the corpus missed.\n *\n * Built from the *resolved* repository-relative path, not the link as written:\n * `../notes.md` cited from `docs/adr/` needs `docs/**\\/*.md`, and suggesting\n * `../**\\/*.md` would be worse than saying nothing.\n */\nfunction suggestPattern(ref: DanglingRef): string {\n const withoutAnchor = (ref.target.split('#')[0] ?? ref.target).trim();\n const resolved = resolveFrom(ref.declaredAt.file, withoutAnchor);\n const directory = dirnamePosix(resolved);\n return directory.length > 0 ? `${directory}/**/*.md` : '**/*.md';\n}\n\n/* -------------------------------------------------------------------------- */\n/* Cycles */\n/* -------------------------------------------------------------------------- */\n\nfunction circularDelegations(graph: SpecGraph, emit: Emit): void {\n const kinds = [...OBLIGATION_EDGES, 'supersedes' as const];\n // Projected onto documents, so a question handed back and forth between two\n // of them is found even though each delegation runs item -> document and the\n // raw graph therefore contains no cycle at all.\n for (const component of graph.cycles(kinds, { byDocument: true })) {\n const members = component\n .map((id) => graph.document(id))\n .filter((node): node is DocumentNode => node !== undefined);\n if (members.length < 2) continue;\n // A cycle is a set, not a subject, so the exemption at `emit` cannot see it.\n // One record in the loop means the loop is partly a report of what was once\n // said, and nothing in it is owed by anybody.\n if (members.some((member) => member.phase === 'record')) continue;\n\n const edges = cycleEdges(graph, component, kinds);\n const onlySupersession = edges.length > 0 && edges.every((edge) => edge.kind === 'supersedes');\n const head = members[0] as DocumentNode;\n\n emit('circular-delegation', () => ({\n message: onlySupersession\n ? `supersession cycle across ${members.length} documents`\n : `delegation cycle across ${members.length} documents: nothing in it can ever land`,\n at: edges[0]?.declaredAt ?? head.at,\n nodes: component,\n related: edges.map((edge) => related(edge.declaredAt, `${edge.from} ${EDGE_TRAITS[edge.kind].phrase} ${edge.to}`)),\n hint: 'break the loop: one of these must own the work outright, or be closed',\n }));\n }\n}\n\n/**\n * The relations that keep a component strongly connected.\n *\n * Membership is by owning document, because the component is a projection: the\n * edge that closes the loop is usually written on an item, and that is the line\n * the report has to point at.\n */\nfunction cycleEdges(graph: SpecGraph, component: readonly string[], kinds: readonly Edge['kind'][]): Edge[] {\n const inside = new Set(component);\n const owner = (id: string): string => graph.owningDocument(id)?.id ?? id;\n const out: Edge[] = [];\n for (const edge of graph.edges) {\n if (!kinds.includes(edge.kind)) continue;\n const from = owner(edge.from);\n const to = owner(edge.to);\n if (from !== to && inside.has(from) && inside.has(to)) out.push(edge);\n }\n return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Orphaned obligations */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The black hole itself: a document nobody reads any more, still holding work.\n *\n * Reported once per document rather than once per item. Five findings that all\n * say \"this archived ADR has open questions\" is five times the noise and none\n * of the extra information.\n */\nfunction orphanedObligations(graph: SpecGraph, emit: Emit, maxRelated: number): void {\n for (const document of graph.documents) {\n if (document.phase !== 'retired' && document.phase !== 'frozen') continue;\n const open = graph.itemsOf(document.id).filter((item) => item.openness !== 'closed');\n if (open.length === 0) continue;\n\n const sealed = document.phase === 'retired' ? 'retired' : 'frozen';\n emit('orphaned-obligation', () => ({\n message: `${sealed} document still holds ${open.length} open ${open.length === 1 ? 'obligation' : 'obligations'}`,\n at: document.statusAt ?? document.at,\n nodes: [document.id, ...open.map((item) => item.id)],\n related: open\n .slice(0, maxRelated)\n .map((item) => related(item.at, `${item.disposition}: ${item.text}`)),\n hint: `move each one to a live document or close it - as it stands, ${open.length === 1 ? 'it disappears' : 'they disappear'} with ${document.id}`,\n }));\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Supersession consistency */\n/* -------------------------------------------------------------------------- */\n\nfunction supersessions(graph: SpecGraph, emit: Emit): void {\n for (const edge of graph.edges) {\n if (edge.kind !== 'supersedes' || edge.reflexive) continue;\n const superseded = graph.document(edge.to);\n const superseding = graph.document(edge.from);\n if (!superseded || !superseding) continue;\n // A record narrating \"ADR-0005 replaced ADR-0001\" is reporting a\n // supersession, not declaring one. Both hints below ask somebody to edit\n // the document that made the claim, and a log is the one document nobody\n // can edit - it says what was true when it was written. The exemption at\n // `emit` cannot see this: the subject here is the *other* document.\n if (superseding.phase === 'record') continue;\n\n if (superseded.phase !== 'retired' && superseded.phase !== 'unknown') {\n emit('live-supersession', () => ({\n // The fix belongs in the superseded document, so that is where the\n // finding points - not at the document that made the claim.\n message: `${superseded.id} is superseded by ${superseding.id} but still reads as ${superseded.phase}`,\n at: superseded.statusAt ?? superseded.at,\n nodes: [superseded.id, superseding.id],\n related: [related(edge.declaredAt, `the supersession is declared here`)],\n hint: `mark ${superseded.id} as superseded, or drop the claim in ${superseding.id}`,\n }));\n continue;\n }\n\n if (superseded.phase === 'retired' && !edge.declaredIn.includes(superseded.path)) {\n emit('unreciprocated-supersession', () => ({\n message: `${superseded.id} is retired but never says that ${superseding.id} replaced it`,\n at: superseded.statusAt ?? superseded.at,\n nodes: [superseded.id, superseding.id],\n related: [related(edge.declaredAt, `only ${superseding.id} records the relationship`)],\n hint: `add \"superseded-by: ${superseding.id}\" to ${superseded.path} so a reader who lands there is redirected`,\n }));\n }\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Item state */\n/* -------------------------------------------------------------------------- */\n\nfunction stateConflicts(graph: SpecGraph, emit: Emit): void {\n for (const item of graph.items) {\n if (item.conflicts.length === 0) continue;\n emit('state-conflict', () => ({\n message: `item reads as ${item.disposition} but also carries ${describeSignals(item)}`,\n at: item.evidence.at,\n nodes: [item.id],\n related: item.conflicts.map((signal) =>\n related(signal.at, `${signal.source} says ${signal.disposition}${signal.raw ? `: ${signal.raw}` : ''}`),\n ),\n hint: `make the two agree - spec-graph is treating it as ${item.openness}`,\n }));\n }\n}\n\nfunction describeSignals(item: ItemNode): string {\n const parts = item.conflicts.map((signal) => `a ${signal.source} saying ${signal.disposition}`);\n return parts.length === 1 ? (parts[0] as string) : `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Self references */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A document that delegates to, or depends on, itself.\n *\n * Almost always a copied link that was never repointed. Informational, because\n * a self-link in a table of contents is harmless - but a *delegation* to self\n * means an obligation that looks handed off and was not.\n */\nfunction selfReferences(graph: SpecGraph, emit: Emit): void {\n for (const edge of graph.edges) {\n if (!edge.reflexive || edge.kind === 'contains') continue;\n const traits = EDGE_TRAITS[edge.kind];\n if (!traits.transfersObligation && !traits.loadBearing) continue;\n const node = graph.node(edge.from);\n if (!node) continue;\n\n emit('self-reference', () => ({\n message: `${describe(node)} ${traits.phrase} itself`,\n at: edge.declaredAt,\n nodes: [edge.from],\n related: [],\n hint: traits.transfersObligation\n ? 'this obligation looks delegated but never left - point it at another document, or own it here'\n : 'a document cannot depend on itself - repoint or remove the reference',\n }));\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Project rules */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The conventions a repository wrote for itself.\n *\n * Run last, and through the same `emit` as everything else, which is the whole\n * point: a project rule inherits the record exemption, the severity table,\n * `--strict`, the related-location cap, the sort order and the baseline without\n * any of them being taught about it. See ADR-0016.\n */\nfunction projectFindings(graph: SpecGraph, rules: readonly ProjectRule[], emit: Emit): void {\n for (const rule of rules) {\n const seen = new Set<string>();\n for (const spec of rule.queries) {\n for (const match of execute(graph, spec)) {\n const nodes = match.nodes.map((node) => node.id);\n // Two selectors in one rule are a union, so a path both of them find is\n // one finding. The alternative is a repository being told twice about a\n // convention it broke once.\n const key = nodes.join('>');\n if (seen.has(key)) continue;\n seen.add(key);\n\n const head = match.nodes[0] as SpecNode;\n emit(rule.id, () => ({\n message: renderTemplate(rule.message, match, graph),\n // The line that declares the relation, not the document it points at:\n // that is where a human goes to change the answer. A rule with no\n // steps has no relation, so it points at the node it selected.\n at: match.edges[0]?.declaredAt ?? head.at,\n nodes,\n related: match.edges\n .slice(1)\n .map((edge) => related(edge.declaredAt, `${edge.from} ${EDGE_TRAITS[edge.kind].phrase} ${edge.to}`)),\n hint: renderTemplate(rule.hint, match, graph),\n }));\n }\n }\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction describe(node: SpecNode): string {\n return node.kind === 'document' ? node.id : `${node.document} \"${truncate(node.text, 48)}\"`;\n}\n\nfunction truncate(text: string, limit: number): string {\n return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;\n}\n\nfunction statusSuffix(document: DocumentNode | undefined): string {\n return document?.rawStatus ? ` (\"${document.rawStatus}\")` : '';\n}\n\nfunction related(at: SourceRef, note: string): RelatedLocation {\n return { at, note };\n}\n\nconst SEVERITY_ORDER: Readonly<Record<Exclude<Severity, 'off'>, number>> = { error: 0, warn: 1, info: 2 };\n\n/**\n * Total ordering, so two runs on the same corpus produce byte-identical output.\n *\n * CI output that reorders between runs cannot be diffed, and output that cannot\n * be diffed stops being read.\n */\nexport function sortDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n return [...diagnostics].sort((a, b) => {\n const bySeverity = SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity];\n if (bySeverity !== 0) return bySeverity;\n if (a.at.file !== b.at.file) return a.at.file < b.at.file ? -1 : 1;\n if (a.at.span.start.line !== b.at.span.start.line) return a.at.span.start.line - b.at.span.start.line;\n if (a.at.span.start.column !== b.at.span.start.column) return a.at.span.start.column - b.at.span.start.column;\n if (a.rule !== b.rule) return a.rule < b.rule ? -1 : 1;\n return a.message < b.message ? -1 : a.message > b.message ? 1 : 0;\n });\n}\n\n/** The selector equivalent of a rule, for `spec-graph rules --explain`. */\nexport const RULE_QUERIES: Readonly<Partial<Record<RuleId, string>>> = Object.freeze({\n 'ghost-handover': '*[openness!=closed][phase!=retired] -delegates-to,blocked-by-> *[receptivity=sealed]',\n 'stale-premise': '*[phase!=retired] -depends-on,assumes,amends,blocked-by-> document[phase=retired]',\n 'orphaned-obligation': 'document[receptivity=sealed] -contains-> item[openness!=closed]',\n 'self-reference': 'see --format json; reflexive edges are excluded from traversal by default',\n});\n"]}
package/dist/select.d.ts CHANGED
@@ -19,6 +19,7 @@
19
19
  * March" instead of naming two documents and leaving the reader to reconstruct
20
20
  * the relationship.
21
21
  */
22
+ import { type Matcher } from './regex.js';
22
23
  import type { SpecGraph } from './graph.js';
23
24
  import { type Edge, type EdgeKind, type NodeKind, type SpecNode } from './types.js';
24
25
  export type Operator = '=' | '!=' | '^=' | '$=' | '*=' | '~=' | 'exists';
@@ -76,6 +77,13 @@ export declare const SELECTOR_KEYS: readonly string[];
76
77
  * is what makes `[section=Open Questions]` read the way people expect.
77
78
  */
78
79
  export declare function attributesOf(node: SpecNode, key: string, graph?: SpecGraph): string[];
80
+ /**
81
+ * Compiles a `~=` pattern, once per distinct pattern.
82
+ *
83
+ * Cached because a rule runs its predicate against every node in the corpus,
84
+ * and because compiling is the expensive half now that matching is linear.
85
+ */
86
+ export declare function pattern(source: string): Matcher;
79
87
  /** True when a node satisfies a matcher. */
80
88
  export declare function matches(node: SpecNode, matcher: NodeMatcher, graph?: SpecGraph): boolean;
81
89
  export interface ExecuteOptions {
package/dist/select.js CHANGED
@@ -20,6 +20,7 @@
20
20
  * the relationship.
21
21
  */
22
22
  import { receptivityOf } from './lifecycle.js';
23
+ import { compilePattern, PatternError } from './regex.js';
23
24
  import { documentOf } from './resolve.js';
24
25
  import { EDGE_KINDS } from './types.js';
25
26
  export class QueryError extends Error {
@@ -110,10 +111,26 @@ class Parser {
110
111
  }
111
112
  const operator = operatorMatch[0];
112
113
  this.position += operator.length;
114
+ const valueStart = this.position;
113
115
  const value = this.parseValue();
114
116
  if (this.source[this.position] !== ']')
115
117
  throw new QueryError('expected "]" to close the predicate', this.position);
116
118
  this.position += 1;
119
+ // A pattern is checked here rather than where it runs, because here is the
120
+ // only place that knows where in the selector it was written. It used to be
121
+ // compiled on first use and an unparseable one silently matched nothing,
122
+ // which is the same silence a misspelled relation would have produced if
123
+ // this grammar tolerated one. See ADR-0017.
124
+ if (operator === '~=') {
125
+ try {
126
+ pattern(value);
127
+ }
128
+ catch (error) {
129
+ if (!(error instanceof PatternError))
130
+ throw error;
131
+ throw new QueryError(error.message, valueStart + error.offset + (quoted(this.source[valueStart]) ? 1 : 0));
132
+ }
133
+ }
117
134
  return { key, operator, value };
118
135
  }
119
136
  parseValue() {
@@ -313,27 +330,29 @@ function testPredicate(node, predicate, graph) {
313
330
  case '*=':
314
331
  return value.includes(needle);
315
332
  case '~=':
316
- return safeRegExp(predicate.value).test(raw);
333
+ return pattern(predicate.value).test(raw);
317
334
  default:
318
335
  return false;
319
336
  }
320
337
  });
321
338
  }
322
- const regexCache = new Map();
323
- function safeRegExp(source) {
324
- const cached = regexCache.get(source);
339
+ const patterns = new Map();
340
+ /**
341
+ * Compiles a `~=` pattern, once per distinct pattern.
342
+ *
343
+ * Cached because a rule runs its predicate against every node in the corpus,
344
+ * and because compiling is the expensive half now that matching is linear.
345
+ */
346
+ export function pattern(source) {
347
+ const cached = patterns.get(source);
325
348
  if (cached)
326
349
  return cached;
327
- let expression;
328
- try {
329
- expression = new RegExp(source, 'i');
330
- }
331
- catch {
332
- // An invalid pattern matches nothing rather than crashing a whole run.
333
- expression = /(?!)/;
334
- }
335
- regexCache.set(source, expression);
336
- return expression;
350
+ const compiled = compilePattern(source);
351
+ patterns.set(source, compiled);
352
+ return compiled;
353
+ }
354
+ function quoted(char) {
355
+ return char === '"' || char === "'";
337
356
  }
338
357
  /** True when a node satisfies a matcher. */
339
358
  export function matches(node, matcher, graph) {
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The selector language.\n *\n * Rules and users ask the graph the same kinds of question, so they use the same\n * machinery. Every built-in diagnostic is a path query plus a message; anything\n * a rule can find, `spec-graph query` can find too, which means a team can\n * express a convention spec-graph never anticipated without writing a plugin.\n *\n * ```text\n * item[openness=open] -delegates-to-> document[phase=retired]\n * document[phase=active] -assumes,depends-on-> document[phase=retired]\n * document =supersedes=> document[phase=active]\n * item[state=obviated] <-assumes- *\n * *[path^=docs/adr] -blocked-by-> item[openness=open]\n * ```\n *\n * A query evaluates to **paths**, not endpoints. A rule that has the whole path\n * can say \"ADR-0004 line 31 delegates this to ADR-0002, which was retired in\n * March\" instead of naming two documents and leaving the reader to reconstruct\n * the relationship.\n */\n\nimport { receptivityOf } from './lifecycle.js';\nimport { documentOf } from './resolve.js';\nimport type { SpecGraph } from './graph.js';\nimport { EDGE_KINDS, type Edge, type EdgeKind, type NodeKind, type SpecNode } from './types.js';\n\n/* -------------------------------------------------------------------------- */\n/* Shapes */\n/* -------------------------------------------------------------------------- */\n\nexport type Operator = '=' | '!=' | '^=' | '$=' | '*=' | '~=' | 'exists';\n\nexport interface Predicate {\n readonly key: string;\n readonly operator: Operator;\n readonly value: string;\n}\n\nexport interface NodeMatcher {\n /** `null` matches both documents and items. */\n readonly kind: NodeKind | null;\n readonly predicates: readonly Predicate[];\n}\n\nexport interface StepSpec {\n readonly direction: 'out' | 'in';\n /** `null` matches any edge kind. */\n readonly kinds: readonly EdgeKind[] | null;\n /** Follow the relation transitively, taking the shortest path to each node. */\n readonly transitive: boolean;\n readonly node: NodeMatcher;\n}\n\nexport interface QuerySpec {\n readonly start: NodeMatcher;\n readonly steps: readonly StepSpec[];\n}\n\n/** One path through the graph. `edges` always has one fewer entry than `nodes`. */\nexport interface Match {\n readonly nodes: readonly SpecNode[];\n readonly edges: readonly Edge[];\n}\n\nexport class QueryError extends Error {\n /** Offset into the query string where the problem starts. */\n readonly offset: number;\n\n constructor(message: string, offset: number) {\n super(message);\n this.name = 'QueryError';\n this.offset = offset;\n }\n}\n\n/** Guards against a pathological query fanning out over a huge corpus. */\nexport const DEFAULT_MATCH_LIMIT = 10_000;\n\n/* -------------------------------------------------------------------------- */\n/* Parsing */\n/* -------------------------------------------------------------------------- */\n\nconst NODE_KINDS: Readonly<Record<string, NodeKind | null>> = {\n document: 'document',\n documents: 'document',\n doc: 'document',\n docs: 'document',\n item: 'item',\n items: 'item',\n node: null,\n nodes: null,\n any: null,\n '*': null,\n};\n\n/** Compiles a selector string into a {@link QuerySpec}. */\nexport function parseQuery(source: string): QuerySpec {\n const parser = new Parser(source);\n const start = parser.parseNodeMatcher();\n const steps: StepSpec[] = [];\n parser.skipSpace();\n while (!parser.atEnd()) {\n steps.push(parser.parseStep());\n parser.skipSpace();\n }\n return { start, steps };\n}\n\nclass Parser {\n private readonly source: string;\n private position = 0;\n\n constructor(source: string) {\n this.source = source;\n }\n\n atEnd(): boolean {\n return this.position >= this.source.length;\n }\n\n skipSpace(): void {\n while (this.position < this.source.length && /\\s/.test(this.source[this.position] as string)) this.position += 1;\n }\n\n parseNodeMatcher(): NodeMatcher {\n this.skipSpace();\n let kind: NodeKind | null = null;\n const word = /^[A-Za-z]+|^\\*/.exec(this.source.slice(this.position));\n if (word) {\n const text = (word[0] as string).toLowerCase();\n if (!(text in NODE_KINDS)) {\n throw new QueryError(\n `unknown node type \"${word[0]}\", expected one of: document, item, * (any)`,\n this.position,\n );\n }\n kind = NODE_KINDS[text] as NodeKind | null;\n this.position += (word[0] as string).length;\n } else if (this.source[this.position] !== '[') {\n throw new QueryError('expected a node type (document, item or *) or a [predicate]', this.position);\n }\n\n const predicates: Predicate[] = [];\n while (this.source[this.position] === '[') predicates.push(this.parsePredicate());\n return { kind, predicates };\n }\n\n private parsePredicate(): Predicate {\n this.position += 1;\n const keyMatch = /^[A-Za-z_][A-Za-z0-9_.:-]*/.exec(this.source.slice(this.position));\n if (!keyMatch) throw new QueryError('expected an attribute name after \"[\"', this.position);\n const key = (keyMatch[0] as string).toLowerCase();\n this.position += (keyMatch[0] as string).length;\n\n if (this.source[this.position] === ']') {\n this.position += 1;\n return { key, operator: 'exists', value: '' };\n }\n\n const operatorMatch = /^(!=|\\^=|\\$=|\\*=|~=|=)/.exec(this.source.slice(this.position));\n if (!operatorMatch) {\n throw new QueryError(\n `expected an operator (=, !=, ^=, $=, *=, ~=) or \"]\" after \"${key}\"`,\n this.position,\n );\n }\n const operator = operatorMatch[0] as Operator;\n this.position += operator.length;\n\n const value = this.parseValue();\n if (this.source[this.position] !== ']') throw new QueryError('expected \"]\" to close the predicate', this.position);\n this.position += 1;\n return { key, operator, value };\n }\n\n private parseValue(): string {\n const quote = this.source[this.position];\n if (quote === '\"' || quote === \"'\") {\n this.position += 1;\n let out = '';\n while (this.position < this.source.length && this.source[this.position] !== quote) {\n if (this.source[this.position] === '\\\\') this.position += 1;\n out += this.source[this.position] ?? '';\n this.position += 1;\n }\n if (this.source[this.position] !== quote) throw new QueryError('unterminated quoted value', this.position);\n this.position += 1;\n return out;\n }\n const match = /^[^\\]\\s]*/.exec(this.source.slice(this.position));\n const value = (match?.[0] ?? '') as string;\n this.position += value.length;\n return value;\n }\n\n parseStep(): StepSpec {\n const rest = this.source.slice(this.position);\n // The forward form is lazy because its terminator is two characters (`->`),\n // which cannot be confused with the hyphen inside `delegates-to`. The\n // backward terminator is a single `-`, so it must be greedy and backtrack:\n // matching lazily would read `<-delegates-to-` as the relation `delegates`.\n const forward = /^(-|=)([A-Za-z,*-]*?)(->|=>)/.exec(rest);\n const backward = /^(<-|<=)([A-Za-z,*-]*)(-|=)(?=\\s|$|[A-Za-z*[])/.exec(rest);\n\n if (forward && (!backward || (forward.index ?? 0) <= (backward.index ?? 0))) {\n const transitive = (forward[1] as string) === '=';\n const closing = forward[3] as string;\n if ((closing === '=>') !== transitive) {\n throw new QueryError('mismatched arrow: use -kind-> for one hop or =kind=> for transitive', this.position);\n }\n const kinds = this.parseKinds(forward[2] as string, this.position + 1);\n this.position += (forward[0] as string).length;\n return { direction: 'out', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n if (backward) {\n const transitive = (backward[1] as string) === '<=';\n const closing = backward[3] as string;\n if ((closing === '=') !== transitive) {\n throw new QueryError('mismatched arrow: use <-kind- for one hop or <=kind= for transitive', this.position);\n }\n const kinds = this.parseKinds(backward[2] as string, this.position + 2);\n this.position += (backward[0] as string).length;\n return { direction: 'in', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n throw new QueryError(\n 'expected a relation step such as -delegates-to->, <-assumes- or =supersedes=>',\n this.position,\n );\n }\n\n private parseKinds(raw: string, offset: number): readonly EdgeKind[] | null {\n const trimmed = raw.trim();\n if (trimmed.length === 0 || trimmed === '*') return null;\n const kinds: EdgeKind[] = [];\n for (const part of trimmed.split(',')) {\n const name = part.trim().toLowerCase();\n if (name.length === 0) continue;\n if (!(EDGE_KINDS as readonly string[]).includes(name)) {\n throw new QueryError(`unknown relation \"${name}\", expected one of: ${EDGE_KINDS.join(', ')}`, offset);\n }\n kinds.push(name as EdgeKind);\n }\n return kinds.length > 0 ? kinds : null;\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Attributes */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Every attribute key a node can answer to, excluding the open `fm.` namespace.\n *\n * Selectors do not validate their keys - an unknown one simply matches nothing,\n * which is the forgiving reading a query typed at a prompt wants. A message\n * template is the opposite case: `{1.phse}` would render as an empty string in\n * a diagnostic somebody has to act on, silently and forever. So the list is\n * published here, next to the switch it mirrors, for the one caller that needs\n * to be strict. See ADR-0016.\n */\nexport const SELECTOR_KEYS: readonly string[] = Object.freeze([\n 'alias',\n 'body',\n 'conflicted',\n 'disposition',\n 'document',\n 'evidence',\n 'file',\n 'id',\n 'kind',\n 'line',\n 'openness',\n 'path',\n 'phase',\n 'receptivity',\n 'section',\n 'state',\n 'status',\n 'text',\n 'title',\n]);\n\n/**\n * The values a predicate key sees on a node.\n *\n * Multi-valued keys (`alias`, `section`) match when *any* value matches, which\n * is what makes `[section=Open Questions]` read the way people expect.\n */\nexport function attributesOf(node: SpecNode, key: string, graph?: SpecGraph): string[] {\n switch (key) {\n case 'id':\n return [node.id];\n case 'kind':\n return [node.kind];\n case 'title':\n return [node.title];\n case 'file':\n return [node.at.file];\n case 'line':\n return [String(node.at.span.start.line)];\n case 'document':\n return [node.kind === 'item' ? node.document : node.id];\n default:\n break;\n }\n\n if (node.kind === 'document') {\n switch (key) {\n case 'path':\n return [node.path];\n case 'phase':\n return [node.phase];\n case 'status':\n return node.rawStatus === null ? [] : [node.rawStatus];\n case 'receptivity':\n return [receptivityOf(node.phase)];\n case 'alias':\n return [...node.aliases];\n default:\n break;\n }\n if (key.startsWith('fm.')) {\n const value = node.frontMatter[key.slice(3)];\n if (value === undefined) return [];\n return typeof value === 'string' ? [value] : [...value];\n }\n return [];\n }\n\n // An item inherits its document's lifecycle. Without this, the two rules that\n // matter most could not be written as queries at all, because the question\n // they ask - \"is the document holding this obligation still open?\" - is about\n // the owner, not the item.\n if (key === 'phase' || key === 'receptivity' || key === 'status' || key === 'path' || key === 'alias') {\n const owner = graph?.owningDocument(node.id);\n if (owner) return attributesOf(owner, key, graph);\n return key === 'path' ? [node.at.file] : [];\n }\n\n switch (key) {\n case 'state':\n case 'disposition':\n return [node.disposition];\n case 'openness':\n return [node.openness];\n case 'section':\n return [...node.section];\n case 'text':\n return [node.text];\n case 'body':\n return [node.body];\n case 'evidence':\n return [node.evidence.source];\n case 'conflicted':\n return [node.conflicts.length > 0 ? 'true' : 'false'];\n default:\n return [];\n }\n}\n\nfunction testPredicate(node: SpecNode, predicate: Predicate, graph?: SpecGraph): boolean {\n const values = attributesOf(node, predicate.key, graph);\n const needle = predicate.value.toLowerCase();\n\n if (predicate.operator === 'exists') return values.some((value) => value.length > 0);\n if (predicate.operator === '!=') return !values.some((value) => value.toLowerCase() === needle);\n\n return values.some((raw) => {\n const value = raw.toLowerCase();\n switch (predicate.operator) {\n case '=':\n return value === needle;\n case '^=':\n return value.startsWith(needle);\n case '$=':\n return value.endsWith(needle);\n case '*=':\n return value.includes(needle);\n case '~=':\n return safeRegExp(predicate.value).test(raw);\n default:\n return false;\n }\n });\n}\n\nconst regexCache = new Map<string, RegExp>();\n\nfunction safeRegExp(source: string): RegExp {\n const cached = regexCache.get(source);\n if (cached) return cached;\n let expression: RegExp;\n try {\n expression = new RegExp(source, 'i');\n } catch {\n // An invalid pattern matches nothing rather than crashing a whole run.\n expression = /(?!)/;\n }\n regexCache.set(source, expression);\n return expression;\n}\n\n/** True when a node satisfies a matcher. */\nexport function matches(node: SpecNode, matcher: NodeMatcher, graph?: SpecGraph): boolean {\n if (matcher.kind !== null && node.kind !== matcher.kind) return false;\n return matcher.predicates.every((predicate) => testPredicate(node, predicate, graph));\n}\n\n/* -------------------------------------------------------------------------- */\n/* Execution */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExecuteOptions {\n /**\n * Cap on the paths produced by each traversal step.\n *\n * It bounds *expansion*, not the initial selection: a query with no steps\n * returns every matching node. That asymmetry is deliberate. The limit exists\n * so a query across a dense graph cannot fan out unboundedly, and the rules\n * run through this engine - truncating the set of nodes a rule starts from\n * would silently drop findings, whereas truncating a runaway expansion only\n * ever drops paths that were already beyond reading.\n */\n readonly limit?: number | undefined;\n /**\n * Whether a step may stay inside one document.\n *\n * Off by default for reflexive edges: a document that links to itself is a\n * formatting quirk, not a relationship, and letting those through turns every\n * table of contents into a finding.\n */\n readonly allowReflexive?: boolean | undefined;\n}\n\n/** Runs a compiled query and returns every matching path. */\nexport function execute(graph: SpecGraph, spec: QuerySpec, options: ExecuteOptions = {}): Match[] {\n const limit = options.limit ?? DEFAULT_MATCH_LIMIT;\n const allowReflexive = options.allowReflexive ?? false;\n\n let frontier: Match[] = [];\n for (const node of graph.nodes.values()) {\n if (matches(node, spec.start, graph)) frontier.push({ nodes: [node], edges: [] });\n }\n\n for (const step of spec.steps) {\n const next: Match[] = [];\n const seen = new Set<string>();\n\n for (const match of frontier) {\n const tail = match.nodes[match.nodes.length - 1] as SpecNode;\n for (const { node, path } of expand(graph, tail, step, allowReflexive)) {\n if (!matches(node, step.node, graph)) continue;\n const key = `${match.nodes.map((n) => n.id).join('>')}>${node.id}`;\n if (seen.has(key)) continue;\n seen.add(key);\n next.push({ nodes: [...match.nodes, node], edges: [...match.edges, ...path] });\n if (next.length >= limit) break;\n }\n if (next.length >= limit) break;\n }\n\n frontier = next;\n if (frontier.length === 0) break;\n }\n\n return frontier;\n}\n\ninterface Expansion {\n readonly node: SpecNode;\n readonly path: readonly Edge[];\n}\n\nfunction expand(graph: SpecGraph, from: SpecNode, step: StepSpec, allowReflexive: boolean): Expansion[] {\n const kinds = step.kinds ?? [];\n const out: Expansion[] = [];\n\n if (!step.transitive) {\n const edges = step.direction === 'out' ? graph.out(from.id, kinds) : graph.in(from.id, kinds);\n for (const edge of edges) {\n if (!allowReflexive && edge.reflexive) continue;\n const targetId = step.direction === 'out' ? edge.to : edge.from;\n const node = graph.node(targetId);\n if (node) out.push({ node, path: [edge] });\n }\n return out;\n }\n\n // Transitive steps take the shortest path to each reachable node, which keeps\n // the result deterministic and the reported evidence minimal.\n const reached =\n step.direction === 'out'\n ? graph.reach(from.id, kinds)\n : reachIncoming(graph, from.id, kinds);\n\n for (const [id, path] of reached) {\n if (!allowReflexive && path.every((edge) => edge.reflexive)) continue;\n const node = graph.node(id);\n if (node) out.push({ node, path });\n }\n return out;\n}\n\nfunction reachIncoming(graph: SpecGraph, id: string, kinds: readonly EdgeKind[]): Map<string, readonly Edge[]> {\n const paths = new Map<string, readonly Edge[]>();\n const pathTo = new Map<string, readonly Edge[]>([[id, []]]);\n const queue: string[] = [id];\n\n while (queue.length > 0) {\n const current = queue.shift() as string;\n const prefix = pathTo.get(current) as readonly Edge[];\n for (const edge of graph.in(current, kinds)) {\n if (pathTo.has(edge.from) && edge.from !== id) continue;\n const path = [...prefix, edge];\n if (edge.from === id) {\n if (!paths.has(id)) paths.set(id, path);\n continue;\n }\n pathTo.set(edge.from, path);\n paths.set(edge.from, path);\n queue.push(edge.from);\n }\n }\n return paths;\n}\n\n/** Parses and runs a selector in one call. */\nexport function query(graph: SpecGraph, selector: string, options?: ExecuteOptions): Match[] {\n return execute(graph, parseQuery(selector), options);\n}\n\n/** Renders a match as `A -kind-> B`, for reports and for `--explain`. */\nexport function renderMatch(match: Match): string {\n const parts: string[] = [match.nodes[0]?.id ?? ''];\n for (let i = 0; i < match.edges.length; i += 1) {\n const edge = match.edges[i] as Edge;\n const node = match.nodes[i + 1];\n parts.push(`-${edge.kind}->`, node?.id ?? documentOf(edge.to));\n }\n return parts.join(' ');\n}\n"]}
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The selector language.\n *\n * Rules and users ask the graph the same kinds of question, so they use the same\n * machinery. Every built-in diagnostic is a path query plus a message; anything\n * a rule can find, `spec-graph query` can find too, which means a team can\n * express a convention spec-graph never anticipated without writing a plugin.\n *\n * ```text\n * item[openness=open] -delegates-to-> document[phase=retired]\n * document[phase=active] -assumes,depends-on-> document[phase=retired]\n * document =supersedes=> document[phase=active]\n * item[state=obviated] <-assumes- *\n * *[path^=docs/adr] -blocked-by-> item[openness=open]\n * ```\n *\n * A query evaluates to **paths**, not endpoints. A rule that has the whole path\n * can say \"ADR-0004 line 31 delegates this to ADR-0002, which was retired in\n * March\" instead of naming two documents and leaving the reader to reconstruct\n * the relationship.\n */\n\nimport { receptivityOf } from './lifecycle.js';\nimport { compilePattern, PatternError, type Matcher } from './regex.js';\nimport { documentOf } from './resolve.js';\nimport type { SpecGraph } from './graph.js';\nimport { EDGE_KINDS, type Edge, type EdgeKind, type NodeKind, type SpecNode } from './types.js';\n\n/* -------------------------------------------------------------------------- */\n/* Shapes */\n/* -------------------------------------------------------------------------- */\n\nexport type Operator = '=' | '!=' | '^=' | '$=' | '*=' | '~=' | 'exists';\n\nexport interface Predicate {\n readonly key: string;\n readonly operator: Operator;\n readonly value: string;\n}\n\nexport interface NodeMatcher {\n /** `null` matches both documents and items. */\n readonly kind: NodeKind | null;\n readonly predicates: readonly Predicate[];\n}\n\nexport interface StepSpec {\n readonly direction: 'out' | 'in';\n /** `null` matches any edge kind. */\n readonly kinds: readonly EdgeKind[] | null;\n /** Follow the relation transitively, taking the shortest path to each node. */\n readonly transitive: boolean;\n readonly node: NodeMatcher;\n}\n\nexport interface QuerySpec {\n readonly start: NodeMatcher;\n readonly steps: readonly StepSpec[];\n}\n\n/** One path through the graph. `edges` always has one fewer entry than `nodes`. */\nexport interface Match {\n readonly nodes: readonly SpecNode[];\n readonly edges: readonly Edge[];\n}\n\nexport class QueryError extends Error {\n /** Offset into the query string where the problem starts. */\n readonly offset: number;\n\n constructor(message: string, offset: number) {\n super(message);\n this.name = 'QueryError';\n this.offset = offset;\n }\n}\n\n/** Guards against a pathological query fanning out over a huge corpus. */\nexport const DEFAULT_MATCH_LIMIT = 10_000;\n\n/* -------------------------------------------------------------------------- */\n/* Parsing */\n/* -------------------------------------------------------------------------- */\n\nconst NODE_KINDS: Readonly<Record<string, NodeKind | null>> = {\n document: 'document',\n documents: 'document',\n doc: 'document',\n docs: 'document',\n item: 'item',\n items: 'item',\n node: null,\n nodes: null,\n any: null,\n '*': null,\n};\n\n/** Compiles a selector string into a {@link QuerySpec}. */\nexport function parseQuery(source: string): QuerySpec {\n const parser = new Parser(source);\n const start = parser.parseNodeMatcher();\n const steps: StepSpec[] = [];\n parser.skipSpace();\n while (!parser.atEnd()) {\n steps.push(parser.parseStep());\n parser.skipSpace();\n }\n return { start, steps };\n}\n\nclass Parser {\n private readonly source: string;\n private position = 0;\n\n constructor(source: string) {\n this.source = source;\n }\n\n atEnd(): boolean {\n return this.position >= this.source.length;\n }\n\n skipSpace(): void {\n while (this.position < this.source.length && /\\s/.test(this.source[this.position] as string)) this.position += 1;\n }\n\n parseNodeMatcher(): NodeMatcher {\n this.skipSpace();\n let kind: NodeKind | null = null;\n const word = /^[A-Za-z]+|^\\*/.exec(this.source.slice(this.position));\n if (word) {\n const text = (word[0] as string).toLowerCase();\n if (!(text in NODE_KINDS)) {\n throw new QueryError(\n `unknown node type \"${word[0]}\", expected one of: document, item, * (any)`,\n this.position,\n );\n }\n kind = NODE_KINDS[text] as NodeKind | null;\n this.position += (word[0] as string).length;\n } else if (this.source[this.position] !== '[') {\n throw new QueryError('expected a node type (document, item or *) or a [predicate]', this.position);\n }\n\n const predicates: Predicate[] = [];\n while (this.source[this.position] === '[') predicates.push(this.parsePredicate());\n return { kind, predicates };\n }\n\n private parsePredicate(): Predicate {\n this.position += 1;\n const keyMatch = /^[A-Za-z_][A-Za-z0-9_.:-]*/.exec(this.source.slice(this.position));\n if (!keyMatch) throw new QueryError('expected an attribute name after \"[\"', this.position);\n const key = (keyMatch[0] as string).toLowerCase();\n this.position += (keyMatch[0] as string).length;\n\n if (this.source[this.position] === ']') {\n this.position += 1;\n return { key, operator: 'exists', value: '' };\n }\n\n const operatorMatch = /^(!=|\\^=|\\$=|\\*=|~=|=)/.exec(this.source.slice(this.position));\n if (!operatorMatch) {\n throw new QueryError(\n `expected an operator (=, !=, ^=, $=, *=, ~=) or \"]\" after \"${key}\"`,\n this.position,\n );\n }\n const operator = operatorMatch[0] as Operator;\n this.position += operator.length;\n\n const valueStart = this.position;\n const value = this.parseValue();\n if (this.source[this.position] !== ']') throw new QueryError('expected \"]\" to close the predicate', this.position);\n this.position += 1;\n // A pattern is checked here rather than where it runs, because here is the\n // only place that knows where in the selector it was written. It used to be\n // compiled on first use and an unparseable one silently matched nothing,\n // which is the same silence a misspelled relation would have produced if\n // this grammar tolerated one. See ADR-0017.\n if (operator === '~=') {\n try {\n pattern(value);\n } catch (error) {\n if (!(error instanceof PatternError)) throw error;\n throw new QueryError(error.message, valueStart + error.offset + (quoted(this.source[valueStart]) ? 1 : 0));\n }\n }\n return { key, operator, value };\n }\n\n private parseValue(): string {\n const quote = this.source[this.position];\n if (quote === '\"' || quote === \"'\") {\n this.position += 1;\n let out = '';\n while (this.position < this.source.length && this.source[this.position] !== quote) {\n if (this.source[this.position] === '\\\\') this.position += 1;\n out += this.source[this.position] ?? '';\n this.position += 1;\n }\n if (this.source[this.position] !== quote) throw new QueryError('unterminated quoted value', this.position);\n this.position += 1;\n return out;\n }\n const match = /^[^\\]\\s]*/.exec(this.source.slice(this.position));\n const value = (match?.[0] ?? '') as string;\n this.position += value.length;\n return value;\n }\n\n parseStep(): StepSpec {\n const rest = this.source.slice(this.position);\n // The forward form is lazy because its terminator is two characters (`->`),\n // which cannot be confused with the hyphen inside `delegates-to`. The\n // backward terminator is a single `-`, so it must be greedy and backtrack:\n // matching lazily would read `<-delegates-to-` as the relation `delegates`.\n const forward = /^(-|=)([A-Za-z,*-]*?)(->|=>)/.exec(rest);\n const backward = /^(<-|<=)([A-Za-z,*-]*)(-|=)(?=\\s|$|[A-Za-z*[])/.exec(rest);\n\n if (forward && (!backward || (forward.index ?? 0) <= (backward.index ?? 0))) {\n const transitive = (forward[1] as string) === '=';\n const closing = forward[3] as string;\n if ((closing === '=>') !== transitive) {\n throw new QueryError('mismatched arrow: use -kind-> for one hop or =kind=> for transitive', this.position);\n }\n const kinds = this.parseKinds(forward[2] as string, this.position + 1);\n this.position += (forward[0] as string).length;\n return { direction: 'out', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n if (backward) {\n const transitive = (backward[1] as string) === '<=';\n const closing = backward[3] as string;\n if ((closing === '=') !== transitive) {\n throw new QueryError('mismatched arrow: use <-kind- for one hop or <=kind= for transitive', this.position);\n }\n const kinds = this.parseKinds(backward[2] as string, this.position + 2);\n this.position += (backward[0] as string).length;\n return { direction: 'in', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n throw new QueryError(\n 'expected a relation step such as -delegates-to->, <-assumes- or =supersedes=>',\n this.position,\n );\n }\n\n private parseKinds(raw: string, offset: number): readonly EdgeKind[] | null {\n const trimmed = raw.trim();\n if (trimmed.length === 0 || trimmed === '*') return null;\n const kinds: EdgeKind[] = [];\n for (const part of trimmed.split(',')) {\n const name = part.trim().toLowerCase();\n if (name.length === 0) continue;\n if (!(EDGE_KINDS as readonly string[]).includes(name)) {\n throw new QueryError(`unknown relation \"${name}\", expected one of: ${EDGE_KINDS.join(', ')}`, offset);\n }\n kinds.push(name as EdgeKind);\n }\n return kinds.length > 0 ? kinds : null;\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Attributes */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Every attribute key a node can answer to, excluding the open `fm.` namespace.\n *\n * Selectors do not validate their keys - an unknown one simply matches nothing,\n * which is the forgiving reading a query typed at a prompt wants. A message\n * template is the opposite case: `{1.phse}` would render as an empty string in\n * a diagnostic somebody has to act on, silently and forever. So the list is\n * published here, next to the switch it mirrors, for the one caller that needs\n * to be strict. See ADR-0016.\n */\nexport const SELECTOR_KEYS: readonly string[] = Object.freeze([\n 'alias',\n 'body',\n 'conflicted',\n 'disposition',\n 'document',\n 'evidence',\n 'file',\n 'id',\n 'kind',\n 'line',\n 'openness',\n 'path',\n 'phase',\n 'receptivity',\n 'section',\n 'state',\n 'status',\n 'text',\n 'title',\n]);\n\n/**\n * The values a predicate key sees on a node.\n *\n * Multi-valued keys (`alias`, `section`) match when *any* value matches, which\n * is what makes `[section=Open Questions]` read the way people expect.\n */\nexport function attributesOf(node: SpecNode, key: string, graph?: SpecGraph): string[] {\n switch (key) {\n case 'id':\n return [node.id];\n case 'kind':\n return [node.kind];\n case 'title':\n return [node.title];\n case 'file':\n return [node.at.file];\n case 'line':\n return [String(node.at.span.start.line)];\n case 'document':\n return [node.kind === 'item' ? node.document : node.id];\n default:\n break;\n }\n\n if (node.kind === 'document') {\n switch (key) {\n case 'path':\n return [node.path];\n case 'phase':\n return [node.phase];\n case 'status':\n return node.rawStatus === null ? [] : [node.rawStatus];\n case 'receptivity':\n return [receptivityOf(node.phase)];\n case 'alias':\n return [...node.aliases];\n default:\n break;\n }\n if (key.startsWith('fm.')) {\n const value = node.frontMatter[key.slice(3)];\n if (value === undefined) return [];\n return typeof value === 'string' ? [value] : [...value];\n }\n return [];\n }\n\n // An item inherits its document's lifecycle. Without this, the two rules that\n // matter most could not be written as queries at all, because the question\n // they ask - \"is the document holding this obligation still open?\" - is about\n // the owner, not the item.\n if (key === 'phase' || key === 'receptivity' || key === 'status' || key === 'path' || key === 'alias') {\n const owner = graph?.owningDocument(node.id);\n if (owner) return attributesOf(owner, key, graph);\n return key === 'path' ? [node.at.file] : [];\n }\n\n switch (key) {\n case 'state':\n case 'disposition':\n return [node.disposition];\n case 'openness':\n return [node.openness];\n case 'section':\n return [...node.section];\n case 'text':\n return [node.text];\n case 'body':\n return [node.body];\n case 'evidence':\n return [node.evidence.source];\n case 'conflicted':\n return [node.conflicts.length > 0 ? 'true' : 'false'];\n default:\n return [];\n }\n}\n\nfunction testPredicate(node: SpecNode, predicate: Predicate, graph?: SpecGraph): boolean {\n const values = attributesOf(node, predicate.key, graph);\n const needle = predicate.value.toLowerCase();\n\n if (predicate.operator === 'exists') return values.some((value) => value.length > 0);\n if (predicate.operator === '!=') return !values.some((value) => value.toLowerCase() === needle);\n\n return values.some((raw) => {\n const value = raw.toLowerCase();\n switch (predicate.operator) {\n case '=':\n return value === needle;\n case '^=':\n return value.startsWith(needle);\n case '$=':\n return value.endsWith(needle);\n case '*=':\n return value.includes(needle);\n case '~=':\n return pattern(predicate.value).test(raw);\n default:\n return false;\n }\n });\n}\n\nconst patterns = new Map<string, Matcher>();\n\n/**\n * Compiles a `~=` pattern, once per distinct pattern.\n *\n * Cached because a rule runs its predicate against every node in the corpus,\n * and because compiling is the expensive half now that matching is linear.\n */\nexport function pattern(source: string): Matcher {\n const cached = patterns.get(source);\n if (cached) return cached;\n const compiled = compilePattern(source);\n patterns.set(source, compiled);\n return compiled;\n}\n\nfunction quoted(char: string | undefined): boolean {\n return char === '\"' || char === \"'\";\n}\n\n/** True when a node satisfies a matcher. */\nexport function matches(node: SpecNode, matcher: NodeMatcher, graph?: SpecGraph): boolean {\n if (matcher.kind !== null && node.kind !== matcher.kind) return false;\n return matcher.predicates.every((predicate) => testPredicate(node, predicate, graph));\n}\n\n/* -------------------------------------------------------------------------- */\n/* Execution */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExecuteOptions {\n /**\n * Cap on the paths produced by each traversal step.\n *\n * It bounds *expansion*, not the initial selection: a query with no steps\n * returns every matching node. That asymmetry is deliberate. The limit exists\n * so a query across a dense graph cannot fan out unboundedly, and the rules\n * run through this engine - truncating the set of nodes a rule starts from\n * would silently drop findings, whereas truncating a runaway expansion only\n * ever drops paths that were already beyond reading.\n */\n readonly limit?: number | undefined;\n /**\n * Whether a step may stay inside one document.\n *\n * Off by default for reflexive edges: a document that links to itself is a\n * formatting quirk, not a relationship, and letting those through turns every\n * table of contents into a finding.\n */\n readonly allowReflexive?: boolean | undefined;\n}\n\n/** Runs a compiled query and returns every matching path. */\nexport function execute(graph: SpecGraph, spec: QuerySpec, options: ExecuteOptions = {}): Match[] {\n const limit = options.limit ?? DEFAULT_MATCH_LIMIT;\n const allowReflexive = options.allowReflexive ?? false;\n\n let frontier: Match[] = [];\n for (const node of graph.nodes.values()) {\n if (matches(node, spec.start, graph)) frontier.push({ nodes: [node], edges: [] });\n }\n\n for (const step of spec.steps) {\n const next: Match[] = [];\n const seen = new Set<string>();\n\n for (const match of frontier) {\n const tail = match.nodes[match.nodes.length - 1] as SpecNode;\n for (const { node, path } of expand(graph, tail, step, allowReflexive)) {\n if (!matches(node, step.node, graph)) continue;\n const key = `${match.nodes.map((n) => n.id).join('>')}>${node.id}`;\n if (seen.has(key)) continue;\n seen.add(key);\n next.push({ nodes: [...match.nodes, node], edges: [...match.edges, ...path] });\n if (next.length >= limit) break;\n }\n if (next.length >= limit) break;\n }\n\n frontier = next;\n if (frontier.length === 0) break;\n }\n\n return frontier;\n}\n\ninterface Expansion {\n readonly node: SpecNode;\n readonly path: readonly Edge[];\n}\n\nfunction expand(graph: SpecGraph, from: SpecNode, step: StepSpec, allowReflexive: boolean): Expansion[] {\n const kinds = step.kinds ?? [];\n const out: Expansion[] = [];\n\n if (!step.transitive) {\n const edges = step.direction === 'out' ? graph.out(from.id, kinds) : graph.in(from.id, kinds);\n for (const edge of edges) {\n if (!allowReflexive && edge.reflexive) continue;\n const targetId = step.direction === 'out' ? edge.to : edge.from;\n const node = graph.node(targetId);\n if (node) out.push({ node, path: [edge] });\n }\n return out;\n }\n\n // Transitive steps take the shortest path to each reachable node, which keeps\n // the result deterministic and the reported evidence minimal.\n const reached =\n step.direction === 'out'\n ? graph.reach(from.id, kinds)\n : reachIncoming(graph, from.id, kinds);\n\n for (const [id, path] of reached) {\n if (!allowReflexive && path.every((edge) => edge.reflexive)) continue;\n const node = graph.node(id);\n if (node) out.push({ node, path });\n }\n return out;\n}\n\nfunction reachIncoming(graph: SpecGraph, id: string, kinds: readonly EdgeKind[]): Map<string, readonly Edge[]> {\n const paths = new Map<string, readonly Edge[]>();\n const pathTo = new Map<string, readonly Edge[]>([[id, []]]);\n const queue: string[] = [id];\n\n while (queue.length > 0) {\n const current = queue.shift() as string;\n const prefix = pathTo.get(current) as readonly Edge[];\n for (const edge of graph.in(current, kinds)) {\n if (pathTo.has(edge.from) && edge.from !== id) continue;\n const path = [...prefix, edge];\n if (edge.from === id) {\n if (!paths.has(id)) paths.set(id, path);\n continue;\n }\n pathTo.set(edge.from, path);\n paths.set(edge.from, path);\n queue.push(edge.from);\n }\n }\n return paths;\n}\n\n/** Parses and runs a selector in one call. */\nexport function query(graph: SpecGraph, selector: string, options?: ExecuteOptions): Match[] {\n return execute(graph, parseQuery(selector), options);\n}\n\n/** Renders a match as `A -kind-> B`, for reports and for `--explain`. */\nexport function renderMatch(match: Match): string {\n const parts: string[] = [match.nodes[0]?.id ?? ''];\n for (let i = 0; i < match.edges.length; i += 1) {\n const edge = match.edges[i] as Edge;\n const node = match.nodes[i + 1];\n parts.push(`-${edge.kind}->`, node?.id ?? documentOf(edge.to));\n }\n return parts.join(' ');\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descent-vtt/spec-graph",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Turn Markdown specs into a verifiable relational graph. Catches ghost handovers, stale premises and broken references in CI.",
5
5
  "keywords": [
6
6
  "adr",