@cello-protocol/daemon 0.0.121 → 0.0.122
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/document-delivery-transport.d.ts +78 -0
- package/dist/document-delivery-transport.d.ts.map +1 -0
- package/dist/document-delivery-transport.js +109 -0
- package/dist/document-delivery-transport.js.map +1 -0
- package/dist/document-delivery.d.ts +130 -0
- package/dist/document-delivery.d.ts.map +1 -0
- package/dist/document-delivery.js +246 -0
- package/dist/document-delivery.js.map +1 -0
- package/dist/document-engine.d.ts.map +1 -1
- package/dist/document-engine.js +10 -4
- package/dist/document-engine.js.map +1 -1
- package/dist/document-gate.d.ts +139 -0
- package/dist/document-gate.d.ts.map +1 -0
- package/dist/document-gate.js +465 -0
- package/dist/document-gate.js.map +1 -0
- package/dist/document-handshake.d.ts +88 -0
- package/dist/document-handshake.d.ts.map +1 -0
- package/dist/document-handshake.js +239 -0
- package/dist/document-handshake.js.map +1 -0
- package/dist/document-lifecycle.d.ts +104 -0
- package/dist/document-lifecycle.d.ts.map +1 -0
- package/dist/document-lifecycle.js +363 -0
- package/dist/document-lifecycle.js.map +1 -0
- package/dist/document-notify.d.ts +130 -0
- package/dist/document-notify.d.ts.map +1 -0
- package/dist/document-notify.js +313 -0
- package/dist/document-notify.js.map +1 -0
- package/dist/document-reachability.d.ts +42 -0
- package/dist/document-reachability.d.ts.map +1 -0
- package/dist/document-reachability.js +72 -0
- package/dist/document-reachability.js.map +1 -0
- package/dist/document-rejection.d.ts +224 -0
- package/dist/document-rejection.d.ts.map +1 -0
- package/dist/document-rejection.js +374 -0
- package/dist/document-rejection.js.map +1 -0
- package/dist/document-store.d.ts +88 -0
- package/dist/document-store.d.ts.map +1 -1
- package/dist/document-store.js +344 -1
- package/dist/document-store.js.map +1 -1
- package/dist/document-write-path.d.ts +84 -0
- package/dist/document-write-path.d.ts.map +1 -0
- package/dist/document-write-path.js +412 -0
- package/dist/document-write-path.js.map +1 -0
- package/dist/line-lcs.d.ts +51 -0
- package/dist/line-lcs.d.ts.map +1 -0
- package/dist/line-lcs.js +71 -0
- package/dist/line-lcs.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-gate.js","sourceRoot":"","sources":["../src/document-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAIzB,gFAAgF;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAa3C,yGAAyG;AACzG,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,6FAA6F;IAC7F,kDAAkD;IAClD,cAAc,EAAE,IAAI,GAAG,IAAI;IAC3B,gBAAgB,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IACjC,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,GAAG;CACzB,CAAC;AAsEF,MAAM,OAAO,YAAY;IACd,OAAO,CAAiB;IACxB,OAAO,CAAa;IACpB,OAAO,CAAS;IAChB,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,uEAAuE;IAC9D,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE/C,YAAY,MAAsB,EAAE,MAA2B,EAAE,MAAc;QAC7E,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,6FAA6F;QAC7F,mFAAmF;QACnF,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,mBAAmB,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAC5F,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,sFAAsF;IACtF,OAAO,CAAC,IAAY,EAAE,IAAc;QAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,QAAe,EAAE,MAAkB,EAAE,OAAoB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QAClF,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,yFAAyF;YACzF,gCAAgC;YAChC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACzD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,SAAS,CAAC,QAAe,EAAE,MAAkB,EAAE,OAAoB,EAAE,GAAW;QAC9E,2EAA2E;QAC3E,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;aAC7F,CAAC,CAAC;QACL,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,yFAAyF;YACzF,qEAAqE;YACrE,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,qDAAqD;aAC9E,CAAC,CAAC;QACL,CAAC;QAED,6FAA6F;QAC7F,sDAAsD;QACtD,IAAI,OAAO,CAAC,gBAAgB,KAAK,kBAAkB,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,sCAAsC;gBAC9C,MAAM,EAAE,8BAA8B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC,IAAI;oBACxF,QAAQ,kBAAkB,sEAAsE;aACnG,CAAC,CAAC;QACL,CAAC;QAED,6FAA6F;QAC7F,oFAAoF;QACpF,IAAI,OAAO,CAAC,kBAAkB,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,gCAAgC;gBACxC,MAAM,EAAE,8BAA8B,MAAM,CAAC,OAAO,CAAC,kBAAkB,IAAI,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI;oBACnG,eAAe,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,6CAA6C;oBAC3F,+EAA+E;aAClF,CAAC,CAAC;QACL,CAAC;QAED,2EAA2E;QAC3E,sFAAsF;QACtF,0FAA0F;QAC1F,8FAA8F;QAC9F,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QAC/F,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACtD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,+BAA+B;gBACvC,KAAK,EAAE;oBACL,IAAI,EAAE,qBAAqB;oBAC3B,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB;oBACvC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;iBAC1B;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAChD,4FAA4F;QAC5F,+BAA+B;QAC/B,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,GAAG,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/F,CAAC;QAED,2EAA2E;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,oCAAoC;gBAC5C,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACzD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAA6B,CAAC,CAAC,CAAC;QAEtG,IAAI,CAAC;YACH,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,uFAAuF;YACvF,oEAAoE;YACpE,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACzD,CAAC,CAAC;QACL,CAAC;QAED,2FAA2F;QAC3F,wFAAwF;QACxF,uFAAuF;QACvF,0FAA0F;QAC1F,kCAAkC;QAClC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC;QACnD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QACzC,IAAI,cAAc,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,yCAAyC;gBACjD,MAAM,EAAE,cAAc;oBACpB,CAAC,CAAC,cAAc,cAAc,CAAC,OAAO,CAAC,IAAI,gDAAgD;oBAC3F,CAAC,CAAC,2EAA2E;aAChF,CAAC,CAAC;QACL,CAAC;QAED,4FAA4F;QAC5F,2FAA2F;QAC3F,wFAAwF;QACxF,wFAAwF;QACxF,2FAA2F;QAC3F,yEAAyE;QACzE,EAAE;QACF,6FAA6F;QAC7F,yFAAyF;QACzF,wBAAwB;QACxB,IAAI,eAA2B,CAAC;QAChC,IAAI,CAAC;YACH,eAAe,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,kFAAkF;YAClF,4FAA4F;YAC5F,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACzD,CAAC,CAAC;QACL,CAAC;QACD,MAAM,SAAS,GAAG,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,gCAAgC;gBACxC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,kDAAkD;oBACjG,0EAA0E;aAC7E,CAAC,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACpE,IAAI,UAAU;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAErE,2EAA2E;QAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAA6B,CAAC,CAAC,CAAC;QACrG,MAAM,IAAI,GAAkB;YAC1B,QAAQ,EAAE,YAAY,CAAC,UAAU,EAAE,SAAS,CAAC;YAC7C,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,SAAS,CAAC;YACjD,WAAW,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAC3E,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC9E;YACD,cAAc,EAAE,SAAS,CAAC,MAAM;YAChC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;SAC5D,CAAC;QAEF,2EAA2E;QAC3E,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,oBAAoB;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE;aACvG,CAAC,CAAC;QACL,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;gBACvC,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,KAAK,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;aAC/F,CAAC,CAAC;QACL,CAAC;QAED,2FAA2F;QAC3F,kEAAkE;QAClE,EAAE;QACF,8FAA8F;QAC9F,2FAA2F;QAC3F,uEAAuE;QACvE,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAChC,wFAAwF;YACxF,uCAAuC;YACvC,4FAA4F;YAC5F,6FAA6F;YAC7F,mEAAmE;YACnE,yFAAyF;YACzF,yFAAyF;YACzF,0FAA0F;YAC1F,wFAAwF;YACxF,wBAAwB;YACxB,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;oBACvC,KAAK,EAAE,KAAK;oBACZ,MAAM,EAAE,gCAAgC;oBACxC,MAAM,EAAE,kCAAkC,SAAS,oCAAoC;wBACrF,sBAAsB;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE;YAC5C,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YACnC,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,gBAAgB,CACd,QAAe,EACf,MAAa,EACb,OAAoB;QAEpB,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;YACpC,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,gCAAgC;gBACxC,MAAM,EAAE,eAAe,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,wCAAwC;oBAC/E,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,8CAA8C;oBACnF,iFAAiF;oBACjF,oCAAoC;aACvC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW,CAAC,OAAoB,EAAE,MAAkB,EAAE,OAA4C;QAChG,8FAA8F;QAC9F,sEAAsE;QACtE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE;YAC/C,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QACH,wFAAwF;QACxF,4FAA4F;QAC5F,8BAA8B;QAC9B,OAAO,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7D,CAAC;CACF;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,KAAa;IACjD,IAAI,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC7C,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC;QAAE,IAAI,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;IAClC,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,KAAa;IACjD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,OAAO,IAAI,GAAG,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC;QAAE,IAAI,EAAE,CAAC;IAC1D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OACE,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI;QAC7B,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI;QAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,EACvE,CAAC;QACD,MAAM,EAAE,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,WAAW,CAAC,GAAU,EAAE,MAAc;IAC7C,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,KAAK,GAA4D,EAAE,CAAC;IAC1E,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAA+B,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACrC,IAAI,KAAK,GAAG,OAAO;YAAE,OAAO,GAAG,KAAK,CAAC;QACrC,iFAAiF;QACjF,IAAI,OAAO,GAAG,MAAM;YAAE,OAAO,OAAO,CAAC;QAErC,MAAM,SAAS,GAAG,IAGjB,CAAC;QACF,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,MAAM;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QACD,IAAI,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC;QAC5B,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3D,IAAI,GAAG,IAAI,CAAC,KAAoB,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,iFAAiF;AACjF,SAAS,UAAU,CAAC,IAA8C;IAChE,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;IAC9B,IAAI,OAAO,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO,OAAO,CAAC,IAA+B,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,MAAkB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC;QACjE,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,uFAAuF;QACvF,0EAA0E;QAC1E,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-HANDSHAKE-1 — the document handshake, daemon side (§16.3).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the attestation-consent pattern operators already understand: a proposal arrives, sits
|
|
5
|
+
* as a pending item, and is accepted or refused once. On accept both sides mint the document from
|
|
6
|
+
* the agreed starting content.
|
|
7
|
+
*
|
|
8
|
+
* ── WHY ACCEPTANCE IS COMPARE-AND-SET ─────────────────────────────────────────────────────────
|
|
9
|
+
*
|
|
10
|
+
* `UPDATE … WHERE consent_state = 'pending'`, and the row count is the answer. Read-then-write
|
|
11
|
+
* would let two concurrent accepts — an agent and a CLI, or two windows on one machine, both real
|
|
12
|
+
* on a multi-attended daemon — each see `pending`, each create the document, and each report
|
|
13
|
+
* success. Worse in the other direction: a REFUSED proposal re-read as pending would be accepted
|
|
14
|
+
* after the operator declined it, which is the one outcome consent exists to make impossible.
|
|
15
|
+
*
|
|
16
|
+
* The same reasoning applies to refuse. Both transitions are terminal and both are guarded.
|
|
17
|
+
*
|
|
18
|
+
* ── WHY THE SEAM IS CHECKED AGAIN HERE ────────────────────────────────────────────────────────
|
|
19
|
+
*
|
|
20
|
+
* `seamViolation` already ran when the proposal was recorded. It runs again at accept because the
|
|
21
|
+
* proposer and the accepter run DIFFERENT BUILDS: a peer one version ahead can propose a value
|
|
22
|
+
* this build cannot honour, and if only the proposer validated, whichever side is newer would
|
|
23
|
+
* silently decide the terms for both. Re-checking at the transition is also what makes an upgrade
|
|
24
|
+
* safe — a proposal recorded under an older build cannot be accepted under rules it predates.
|
|
25
|
+
*/
|
|
26
|
+
import { type DocumentConsentState, type DocumentProposalEnvelope } from "@cello-protocol/protocol-types";
|
|
27
|
+
import type { DaemonDatabase } from "./sqlcipher-db.js";
|
|
28
|
+
import type { Logger } from "./types.js";
|
|
29
|
+
/**
|
|
30
|
+
* Verify a proposal's signature against the agent that claims to have made it.
|
|
31
|
+
*
|
|
32
|
+
* INJECTED and REQUIRED — this class cannot resolve `proposer_agent_id` to a public key, and a
|
|
33
|
+
* default implementation would be a default answer to "is this authentic". The composition root
|
|
34
|
+
* wires the real one.
|
|
35
|
+
*/
|
|
36
|
+
export type ProposalSignatureVerifier = (proposerAgentId: string, tbs: Uint8Array, signature: Uint8Array) => boolean;
|
|
37
|
+
export interface DocumentProposalRecord {
|
|
38
|
+
documentId: string;
|
|
39
|
+
proposerAgentId: string;
|
|
40
|
+
peerAgentId: string;
|
|
41
|
+
envelope: DocumentProposalEnvelope;
|
|
42
|
+
consentState: DocumentConsentState;
|
|
43
|
+
refusalReason?: string;
|
|
44
|
+
createdAtMs: number;
|
|
45
|
+
decidedAtMs?: number;
|
|
46
|
+
}
|
|
47
|
+
export type AcceptOutcome = {
|
|
48
|
+
ok: true;
|
|
49
|
+
documentId: string;
|
|
50
|
+
envelope: DocumentProposalEnvelope;
|
|
51
|
+
} | {
|
|
52
|
+
ok: false;
|
|
53
|
+
reason: string;
|
|
54
|
+
detail: string;
|
|
55
|
+
};
|
|
56
|
+
export declare class DocumentHandshake {
|
|
57
|
+
#private;
|
|
58
|
+
constructor(db: DaemonDatabase, logger: Logger, verify: ProposalSignatureVerifier);
|
|
59
|
+
/**
|
|
60
|
+
* Record an arriving proposal as PENDING, or refuse it outright.
|
|
61
|
+
*
|
|
62
|
+
* A seam violation or a version mismatch is recorded as `refused` with its reason rather than
|
|
63
|
+
* dropped, so the operator can see that a peer tried and why it could not proceed. A dropped
|
|
64
|
+
* proposal is indistinguishable from a peer that never sent one.
|
|
65
|
+
*/
|
|
66
|
+
recordProposal(ownerAgentId: string, wire: Uint8Array, nowMs: number): {
|
|
67
|
+
documentId: string;
|
|
68
|
+
state: DocumentConsentState;
|
|
69
|
+
reason?: string;
|
|
70
|
+
};
|
|
71
|
+
/** Proposals still awaiting a decision — the operator's inbox for documents. */
|
|
72
|
+
pending(ownerAgentId: string): DocumentProposalRecord[];
|
|
73
|
+
get(ownerAgentId: string, documentId: string): DocumentProposalRecord | null;
|
|
74
|
+
/**
|
|
75
|
+
* Accept a pending proposal. Compare-and-set: the transition happens iff the row was still
|
|
76
|
+
* pending, and the affected-row count is what says so.
|
|
77
|
+
*/
|
|
78
|
+
accept(ownerAgentId: string, documentId: string, nowMs: number): AcceptOutcome;
|
|
79
|
+
/** Refuse a pending proposal. Same compare-and-set guard; a reason is mandatory. */
|
|
80
|
+
refuse(ownerAgentId: string, documentId: string, reason: string, nowMs: number): {
|
|
81
|
+
ok: true;
|
|
82
|
+
} | {
|
|
83
|
+
ok: false;
|
|
84
|
+
reason: string;
|
|
85
|
+
detail: string;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=document-handshake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-handshake.d.ts","sourceRoot":"","sources":["../src/document-handshake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAOL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,eAAe,EAAE,MAAM,EACvB,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,KAClB,OAAO,CAAC;AA+Bb,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,YAAY,EAAE,oBAAoB,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,wBAAwB,CAAA;CAAE,GACpE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,qBAAa,iBAAiB;;gBAKhB,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB;IAOjF;;;;;;OAMG;IACH,cAAc,CACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,GACZ;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,oBAAoB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAyFvE,gFAAgF;IAChF,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,sBAAsB,EAAE;IAIvD,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAS5E;;;OAGG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa;IA6D9E,oFAAoF;IACpF,MAAM,CACJ,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAwChE"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-HANDSHAKE-1 — the document handshake, daemon side (§16.3).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the attestation-consent pattern operators already understand: a proposal arrives, sits
|
|
5
|
+
* as a pending item, and is accepted or refused once. On accept both sides mint the document from
|
|
6
|
+
* the agreed starting content.
|
|
7
|
+
*
|
|
8
|
+
* ── WHY ACCEPTANCE IS COMPARE-AND-SET ─────────────────────────────────────────────────────────
|
|
9
|
+
*
|
|
10
|
+
* `UPDATE … WHERE consent_state = 'pending'`, and the row count is the answer. Read-then-write
|
|
11
|
+
* would let two concurrent accepts — an agent and a CLI, or two windows on one machine, both real
|
|
12
|
+
* on a multi-attended daemon — each see `pending`, each create the document, and each report
|
|
13
|
+
* success. Worse in the other direction: a REFUSED proposal re-read as pending would be accepted
|
|
14
|
+
* after the operator declined it, which is the one outcome consent exists to make impossible.
|
|
15
|
+
*
|
|
16
|
+
* The same reasoning applies to refuse. Both transitions are terminal and both are guarded.
|
|
17
|
+
*
|
|
18
|
+
* ── WHY THE SEAM IS CHECKED AGAIN HERE ────────────────────────────────────────────────────────
|
|
19
|
+
*
|
|
20
|
+
* `seamViolation` already ran when the proposal was recorded. It runs again at accept because the
|
|
21
|
+
* proposer and the accepter run DIFFERENT BUILDS: a peer one version ahead can propose a value
|
|
22
|
+
* this build cannot honour, and if only the proposer validated, whichever side is newer would
|
|
23
|
+
* silently decide the terms for both. Re-checking at the transition is also what makes an upgrade
|
|
24
|
+
* safe — a proposal recorded under an older build cannot be accepted under rules it predates.
|
|
25
|
+
*/
|
|
26
|
+
import { buildDocumentProposalTbs, decodeDocumentProposal, documentFeatureIncompatibility, documentIdFromProposal, encodeDocumentProposal, seamViolation, } from "@cello-protocol/protocol-types";
|
|
27
|
+
/**
|
|
28
|
+
* NOTE FOR THE NEXT COLUMN. `CREATE TABLE IF NOT EXISTS` is correct only while no daemon has ever
|
|
29
|
+
* created this table — true today, since it is new in an unreleased milestone. The moment any dev
|
|
30
|
+
* or staging DB holds it, adding a column here returns silently and that column never appears on
|
|
31
|
+
* an upgraded database while fresh installs get it. That divergence has already shipped once in
|
|
32
|
+
* this repo (see `consent-migration.ts`). Any future column needs a `PRAGMA table_info` birth-gated
|
|
33
|
+
* ALTER under `BEGIN IMMEDIATE`, following that file.
|
|
34
|
+
*/
|
|
35
|
+
const CREATE_PROPOSALS_SQL = `
|
|
36
|
+
CREATE TABLE IF NOT EXISTS document_proposals (
|
|
37
|
+
owner_agent_id TEXT NOT NULL,
|
|
38
|
+
document_id TEXT NOT NULL,
|
|
39
|
+
proposer_agent_id TEXT NOT NULL,
|
|
40
|
+
peer_agent_id TEXT NOT NULL,
|
|
41
|
+
-- The proposal envelope as it arrived. Kept whole rather than exploded into columns, because
|
|
42
|
+
-- document_id is the hash of exactly these bytes: reconstructing them from columns would make
|
|
43
|
+
-- the identity depend on this schema's round-trip fidelity forever.
|
|
44
|
+
envelope BLOB NOT NULL,
|
|
45
|
+
consent_state TEXT NOT NULL CHECK (consent_state IN ('pending', 'accepted', 'refused')),
|
|
46
|
+
-- Why it was refused, when it was. An operator who declined a proposal weeks ago, or whose
|
|
47
|
+
-- daemon declined it on a seam violation, has no other record of which it was.
|
|
48
|
+
refusal_reason TEXT,
|
|
49
|
+
created_at INTEGER NOT NULL,
|
|
50
|
+
decided_at INTEGER,
|
|
51
|
+
PRIMARY KEY (owner_agent_id, document_id),
|
|
52
|
+
CHECK (consent_state <> 'refused' OR refusal_reason IS NOT NULL)
|
|
53
|
+
);
|
|
54
|
+
`;
|
|
55
|
+
export class DocumentHandshake {
|
|
56
|
+
#db;
|
|
57
|
+
#logger;
|
|
58
|
+
#verify;
|
|
59
|
+
constructor(db, logger, verify) {
|
|
60
|
+
this.#db = db;
|
|
61
|
+
this.#logger = logger;
|
|
62
|
+
this.#verify = verify;
|
|
63
|
+
this.#db.exec(CREATE_PROPOSALS_SQL);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Record an arriving proposal as PENDING, or refuse it outright.
|
|
67
|
+
*
|
|
68
|
+
* A seam violation or a version mismatch is recorded as `refused` with its reason rather than
|
|
69
|
+
* dropped, so the operator can see that a peer tried and why it could not proceed. A dropped
|
|
70
|
+
* proposal is indistinguishable from a peer that never sent one.
|
|
71
|
+
*/
|
|
72
|
+
recordProposal(ownerAgentId, wire, nowMs) {
|
|
73
|
+
const envelope = decodeDocumentProposal(wire);
|
|
74
|
+
const documentId = documentIdFromProposal(envelope);
|
|
75
|
+
// AUTHENTICITY FIRST, and it is fatal rather than a recorded refusal. The operator's consent
|
|
76
|
+
// decision rests entirely on the proposal having come from the agent it names, and an
|
|
77
|
+
// unverified proposal must not reach the inbox at all — `ON CONFLICT DO NOTHING` means the
|
|
78
|
+
// FIRST arrival's bytes are the permanent record for a document_id, so anyone who observed the
|
|
79
|
+
// honest proposal (and therefore knows the nonce) could race a byte-variant carrying junk,
|
|
80
|
+
// win the primary key, and permanently poison the id while the honest proposal is silently
|
|
81
|
+
// discarded. The proposer would have to re-propose under a new nonce with no signal why.
|
|
82
|
+
if (!this.#verify(envelope.proposer_agent_id, buildDocumentProposalTbs(envelope), envelope.signature)) {
|
|
83
|
+
this.#logger.error("document.proposal.signature_invalid", {
|
|
84
|
+
documentId,
|
|
85
|
+
proposerAgentId: envelope.proposer_agent_id,
|
|
86
|
+
});
|
|
87
|
+
throw new Error(`document_proposal_signature_invalid: the proposal claims to come from ` +
|
|
88
|
+
`${envelope.proposer_agent_id} but its signature does not verify against that agent`);
|
|
89
|
+
}
|
|
90
|
+
// ADDRESSED TO US. `ownerAgentId` comes from the caller and `peer_agent_id` comes from the
|
|
91
|
+
// wire, and on a multi-agent daemon — which is why owner_agent_id is in the key at all — an
|
|
92
|
+
// unchecked pair lets a proposal addressed to agent Z be recorded under agent Y and accepted
|
|
93
|
+
// BY agent Y. Consent would then be taken from a party the proposal never named, while the
|
|
94
|
+
// document_id (which does commit to peer_agent_id) says otherwise, with no error anywhere.
|
|
95
|
+
if (envelope.peer_agent_id !== ownerAgentId) {
|
|
96
|
+
this.#logger.warn("document.proposal.wrong_peer", {
|
|
97
|
+
documentId,
|
|
98
|
+
addressedTo: envelope.peer_agent_id,
|
|
99
|
+
recordedFor: ownerAgentId,
|
|
100
|
+
});
|
|
101
|
+
throw new Error(`document_proposal_wrong_peer: this proposal is addressed to ${envelope.peer_agent_id}, ` +
|
|
102
|
+
`not to ${ownerAgentId} — consent belongs to the agent the proposer named`);
|
|
103
|
+
}
|
|
104
|
+
// The HUMAN answer, not a machine label. The clause exists because the alternative to a
|
|
105
|
+
// sentence is a proposal that is never answered, which surfaces as a hang and gets diagnosed
|
|
106
|
+
// as a network fault — and because "upgrade" is useless without saying WHOSE client.
|
|
107
|
+
const incompatible = documentFeatureIncompatibility(envelope.feature_version);
|
|
108
|
+
const reason = incompatible ?? seamViolation(envelope.properties);
|
|
109
|
+
this.#db
|
|
110
|
+
.prepare(`INSERT INTO document_proposals
|
|
111
|
+
(owner_agent_id, document_id, proposer_agent_id, peer_agent_id, envelope,
|
|
112
|
+
consent_state, refusal_reason, created_at, decided_at)
|
|
113
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
114
|
+
ON CONFLICT (owner_agent_id, document_id) DO NOTHING`)
|
|
115
|
+
.run(ownerAgentId, documentId, envelope.proposer_agent_id, envelope.peer_agent_id, Buffer.from(encodeDocumentProposal(envelope)), reason ? "refused" : "pending", reason, nowMs, reason ? nowMs : null);
|
|
116
|
+
// READ BACK THE ROW, do not report what we intended. On a redelivery the INSERT does nothing —
|
|
117
|
+
// correct — and returning the state we would have written announces a decision the operator
|
|
118
|
+
// already made as still awaiting one, and logs an arrival that did not happen.
|
|
119
|
+
const stored = this.get(ownerAgentId, documentId);
|
|
120
|
+
const state = stored?.consentState ?? (reason ? "refused" : "pending");
|
|
121
|
+
const storedReason = stored?.refusalReason ?? reason ?? undefined;
|
|
122
|
+
if (state === "refused") {
|
|
123
|
+
this.#logger.warn("document.proposal.refused", {
|
|
124
|
+
documentId,
|
|
125
|
+
reason: storedReason,
|
|
126
|
+
autoRefused: true,
|
|
127
|
+
});
|
|
128
|
+
return { documentId, state, reason: storedReason };
|
|
129
|
+
}
|
|
130
|
+
if (state === "pending") {
|
|
131
|
+
this.#logger.info("document.proposal.pending", {
|
|
132
|
+
documentId,
|
|
133
|
+
proposerAgentId: envelope.proposer_agent_id,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return { documentId, state, ...(storedReason ? { reason: storedReason } : {}) };
|
|
137
|
+
}
|
|
138
|
+
/** Proposals still awaiting a decision — the operator's inbox for documents. */
|
|
139
|
+
pending(ownerAgentId) {
|
|
140
|
+
return this.#rows(ownerAgentId, "WHERE owner_agent_id = ? AND consent_state = 'pending'", []);
|
|
141
|
+
}
|
|
142
|
+
get(ownerAgentId, documentId) {
|
|
143
|
+
const rows = this.#rows(ownerAgentId, "WHERE owner_agent_id = ? AND document_id = ?", [documentId]);
|
|
144
|
+
return rows[0] ?? null;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Accept a pending proposal. Compare-and-set: the transition happens iff the row was still
|
|
148
|
+
* pending, and the affected-row count is what says so.
|
|
149
|
+
*/
|
|
150
|
+
accept(ownerAgentId, documentId, nowMs) {
|
|
151
|
+
const record = this.get(ownerAgentId, documentId);
|
|
152
|
+
if (!record) {
|
|
153
|
+
return {
|
|
154
|
+
ok: false,
|
|
155
|
+
reason: "document_proposal_unknown",
|
|
156
|
+
detail: `no proposal ${documentId.slice(0, 16)}… for this agent`,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Re-checked at the transition, not merely at arrival — the proposer runs a different build.
|
|
160
|
+
const violation = seamViolation(record.envelope.properties);
|
|
161
|
+
if (violation) {
|
|
162
|
+
// TRANSITION, do not just refuse the call. Leaving the row pending gives the operator an
|
|
163
|
+
// inbox entry they can never clear, carrying no reason — while the arrival path records one
|
|
164
|
+
// for the identical condition. Two behaviours for one fact, and the one that persists is the
|
|
165
|
+
// one with no explanation attached.
|
|
166
|
+
if (record.consentState === "pending") {
|
|
167
|
+
this.#db
|
|
168
|
+
.prepare(`UPDATE document_proposals SET consent_state = 'refused', refusal_reason = ?,
|
|
169
|
+
decided_at = ?
|
|
170
|
+
WHERE owner_agent_id = ? AND document_id = ? AND consent_state = 'pending'`)
|
|
171
|
+
.run(violation, nowMs, ownerAgentId, documentId);
|
|
172
|
+
this.#logger.warn("document.proposal.refused", {
|
|
173
|
+
documentId,
|
|
174
|
+
reason: violation,
|
|
175
|
+
autoRefused: true,
|
|
176
|
+
at: "accept",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return { ok: false, reason: "document_seam_violation", detail: violation };
|
|
180
|
+
}
|
|
181
|
+
const info = this.#db
|
|
182
|
+
.prepare(`UPDATE document_proposals SET consent_state = 'accepted', decided_at = ?
|
|
183
|
+
WHERE owner_agent_id = ? AND document_id = ? AND consent_state = 'pending'`)
|
|
184
|
+
.run(nowMs, ownerAgentId, documentId);
|
|
185
|
+
if (Number(info.changes) === 0) {
|
|
186
|
+
// The row exists but was not pending. Naming the state it IS in is the whole value of the
|
|
187
|
+
// message: "already accepted" and "you refused this" are different facts to an operator, and
|
|
188
|
+
// a generic failure would read as a bug in the handshake.
|
|
189
|
+
const now = this.get(ownerAgentId, documentId);
|
|
190
|
+
return {
|
|
191
|
+
ok: false,
|
|
192
|
+
reason: "document_proposal_not_pending",
|
|
193
|
+
detail: `proposal ${documentId.slice(0, 16)}… is ${now?.consentState ?? "gone"}` +
|
|
194
|
+
(now?.refusalReason ? ` (${now.refusalReason})` : "") +
|
|
195
|
+
" — a consent decision is made once",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
this.#logger.info("document.proposal.accepted", { documentId });
|
|
199
|
+
return { ok: true, documentId, envelope: record.envelope };
|
|
200
|
+
}
|
|
201
|
+
/** Refuse a pending proposal. Same compare-and-set guard; a reason is mandatory. */
|
|
202
|
+
refuse(ownerAgentId, documentId, reason, nowMs) {
|
|
203
|
+
if (reason.trim().length === 0) {
|
|
204
|
+
// The column's CHECK enforces this too. Refused here so the caller gets a usable error
|
|
205
|
+
// rather than a constraint violation naming a column.
|
|
206
|
+
throw new Error("document_refusal_reason_required: a refusal must say why");
|
|
207
|
+
}
|
|
208
|
+
const info = this.#db
|
|
209
|
+
.prepare(`UPDATE document_proposals SET consent_state = 'refused', refusal_reason = ?, decided_at = ?
|
|
210
|
+
WHERE owner_agent_id = ? AND document_id = ? AND consent_state = 'pending'`)
|
|
211
|
+
.run(reason, nowMs, ownerAgentId, documentId);
|
|
212
|
+
if (Number(info.changes) === 0) {
|
|
213
|
+
const now = this.get(ownerAgentId, documentId);
|
|
214
|
+
return {
|
|
215
|
+
ok: false,
|
|
216
|
+
reason: "document_proposal_not_pending",
|
|
217
|
+
detail: `proposal ${documentId.slice(0, 16)}… is ${now?.consentState ?? "unknown"} — a consent decision is made once`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
this.#logger.info("document.proposal.refused", { documentId, reason, autoRefused: false });
|
|
221
|
+
return { ok: true };
|
|
222
|
+
}
|
|
223
|
+
#rows(ownerAgentId, where, extra) {
|
|
224
|
+
const rows = this.#db
|
|
225
|
+
.prepare(`SELECT * FROM document_proposals ${where} ORDER BY created_at ASC, rowid ASC`)
|
|
226
|
+
.all(ownerAgentId, ...extra);
|
|
227
|
+
return rows.map((r) => ({
|
|
228
|
+
documentId: r["document_id"],
|
|
229
|
+
proposerAgentId: r["proposer_agent_id"],
|
|
230
|
+
peerAgentId: r["peer_agent_id"],
|
|
231
|
+
envelope: decodeDocumentProposal(new Uint8Array(r["envelope"])),
|
|
232
|
+
consentState: r["consent_state"],
|
|
233
|
+
refusalReason: r["refusal_reason"] ?? undefined,
|
|
234
|
+
createdAtMs: r["created_at"],
|
|
235
|
+
decidedAtMs: r["decided_at"] ?? undefined,
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=document-handshake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-handshake.js","sourceRoot":"","sources":["../src/document-handshake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-LIFECYCLE-1 — the verbs (§3.5 + §16.4).
|
|
3
|
+
*
|
|
4
|
+
* Three ways a document can end, and they are not interchangeable. Conflating any two of them
|
|
5
|
+
* makes a promise the protocol cannot keep:
|
|
6
|
+
*
|
|
7
|
+
* close BILATERAL. Both sides ack and the document is complete by agreement. One side's
|
|
8
|
+
* close is a REQUEST — treating it as a conclusion would tell this operator the
|
|
9
|
+
* collaboration ended while the peer is still writing into it.
|
|
10
|
+
* kill UNILATERAL. Stop accepting and publishing, notify the peer, and KEEP the local copy
|
|
11
|
+
* and the log. The peer keeps what it holds, and that is said out loud: it is the one
|
|
12
|
+
* thing an operator is most likely to assume a kill undoes, and the one thing it
|
|
13
|
+
* cannot.
|
|
14
|
+
* withdraw ONE UNDELIVERED update. A local rollback plus a withdrawal record BESIDE the
|
|
15
|
+
* original — marked, never deleted, because a hole in an append-only log is
|
|
16
|
+
* indistinguishable from tampering. Once the peer has it, withdrawal is refused rather
|
|
17
|
+
* than faked.
|
|
18
|
+
*
|
|
19
|
+
* ── THE KILL SWITCH (§16.7-11) ────────────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* A platform-paused agent refuses OUTBOUND publishes loudly, still admits INBOUND mechanically,
|
|
22
|
+
* and suppresses notifications. The asymmetry is deliberate. Refusing inbound would surface the
|
|
23
|
+
* pause to the peer as a protocol fault and force a rejection round for something that is not
|
|
24
|
+
* their doing; refusing outbound silently would leave the operator writing into a document that is
|
|
25
|
+
* going nowhere, with their work piling up locally and no sign anything is wrong.
|
|
26
|
+
*/
|
|
27
|
+
import type { DocumentStore } from "./document-store.js";
|
|
28
|
+
import type { Logger } from "./types.js";
|
|
29
|
+
/** How the peer is told about a unilateral end. Injected — the transport is not this unit's. */
|
|
30
|
+
export interface LifecycleNotifier {
|
|
31
|
+
notifyPeer(documentId: string, verb: "kill" | "close"): Promise<{
|
|
32
|
+
ok: true;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
reason: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export interface DocumentListRow {
|
|
39
|
+
documentId: string;
|
|
40
|
+
peerAgentId: string;
|
|
41
|
+
documentType: string;
|
|
42
|
+
/** Constant in V1, shown because it is seam surface — a field nobody sees cannot be noticed. */
|
|
43
|
+
assuranceTier: string;
|
|
44
|
+
epochId: number;
|
|
45
|
+
status: string;
|
|
46
|
+
pendingDeliveries: number;
|
|
47
|
+
/** We have closed and the peer has not. */
|
|
48
|
+
closePending: boolean;
|
|
49
|
+
}
|
|
50
|
+
export type Verdict = {
|
|
51
|
+
ok: true;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
reason: string;
|
|
55
|
+
detail: string;
|
|
56
|
+
};
|
|
57
|
+
export declare class DocumentLifecycle {
|
|
58
|
+
#private;
|
|
59
|
+
constructor(store: DocumentStore, logger: Logger, notifier: LifecycleNotifier,
|
|
60
|
+
/**
|
|
61
|
+
* Undo one envelope's operations on the LIVE document, as inverses. Injected because the live
|
|
62
|
+
* `Y.Doc` and its UndoManager belong to the engine, not here — and REQUIRED, because a default
|
|
63
|
+
* that quietly did nothing would restore exactly the defect this argument exists to fix.
|
|
64
|
+
*/
|
|
65
|
+
rollback: (ownerAgentId: string, documentId: string, envelopeHash: string) => {
|
|
66
|
+
ok: true;
|
|
67
|
+
} | {
|
|
68
|
+
ok: false;
|
|
69
|
+
reason: string;
|
|
70
|
+
});
|
|
71
|
+
list(ownerAgentId: string, nowMs: number): DocumentListRow[];
|
|
72
|
+
/** Our half of a bilateral close. Completes only when the peer's half is also on record. */
|
|
73
|
+
close(ownerAgentId: string, documentId: string, nowMs: number): Promise<Verdict>;
|
|
74
|
+
/** The peer's half, arriving over the session. */
|
|
75
|
+
recordPeerClose(ownerAgentId: string, documentId: string, peerAgentId: string, nowMs: number): Verdict;
|
|
76
|
+
/**
|
|
77
|
+
* Unilateral end. Local, and deliberately not contingent on the peer hearing about it — a
|
|
78
|
+
* decision to stop that depends on the other party being online is not a decision to stop.
|
|
79
|
+
*/
|
|
80
|
+
kill(ownerAgentId: string, documentId: string, nowMs: number): Promise<{
|
|
81
|
+
ok: true;
|
|
82
|
+
peerNotified: boolean;
|
|
83
|
+
note: string;
|
|
84
|
+
} | {
|
|
85
|
+
ok: false;
|
|
86
|
+
reason: string;
|
|
87
|
+
detail: string;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Withdraw ONE undelivered update: a withdrawal record beside the original.
|
|
91
|
+
*
|
|
92
|
+
* Every refusal here is the same shape — say no rather than produce a record that claims
|
|
93
|
+
* something untrue about the log.
|
|
94
|
+
*/
|
|
95
|
+
withdraw(ownerAgentId: string, documentId: string, envelopeHash: string, nowMs: number): Verdict;
|
|
96
|
+
setPlatformPaused(agentId: string, paused: boolean, nowMs: number): void;
|
|
97
|
+
isPlatformPaused(agentId: string): boolean;
|
|
98
|
+
/** Outbound. Refused loudly while paused, and while the document has ended. */
|
|
99
|
+
canPublish(ownerAgentId: string, documentId: string): Verdict;
|
|
100
|
+
/** Inbound. A pause does NOT refuse it — see the header. */
|
|
101
|
+
canAdmit(ownerAgentId: string, documentId: string): Verdict;
|
|
102
|
+
shouldNotify(agentId: string): boolean;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=document-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-lifecycle.d.ts","sourceRoot":"","sources":["../src/document-lifecycle.ts"],"names":[],"mappings":"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"}
|