@amalgm/live 0.2.27 → 0.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/PURPOSE.md +38 -25
  2. package/README.md +1 -2
  3. package/dist/contracts/index.d.ts +0 -1
  4. package/dist/contracts/index.d.ts.map +1 -1
  5. package/dist/contracts/index.js +0 -1
  6. package/dist/contracts/index.js.map +1 -1
  7. package/dist/detection/record-proposal.d.ts +3 -2
  8. package/dist/detection/record-proposal.d.ts.map +1 -1
  9. package/dist/detection/record-proposal.js +9 -7
  10. package/dist/detection/record-proposal.js.map +1 -1
  11. package/dist/index.d.ts +3 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/machines/index.d.ts +0 -2
  16. package/dist/machines/index.d.ts.map +1 -1
  17. package/dist/machines/index.js +0 -2
  18. package/dist/machines/index.js.map +1 -1
  19. package/dist/records/authority.d.ts +23 -0
  20. package/dist/records/authority.d.ts.map +1 -0
  21. package/dist/records/authority.js +28 -0
  22. package/dist/records/authority.js.map +1 -0
  23. package/dist/records/codec.d.ts +6 -0
  24. package/dist/records/codec.d.ts.map +1 -0
  25. package/dist/records/codec.js +42 -0
  26. package/dist/records/codec.js.map +1 -0
  27. package/dist/records/contracts.d.ts +46 -0
  28. package/dist/records/contracts.d.ts.map +1 -0
  29. package/dist/records/contracts.js +114 -0
  30. package/dist/records/contracts.js.map +1 -0
  31. package/dist/records/inbox.d.ts +18 -0
  32. package/dist/records/inbox.d.ts.map +1 -0
  33. package/dist/records/inbox.js +34 -0
  34. package/dist/records/inbox.js.map +1 -0
  35. package/dist/records/index.d.ts +7 -0
  36. package/dist/records/index.d.ts.map +1 -0
  37. package/dist/records/index.js +7 -0
  38. package/dist/records/index.js.map +1 -0
  39. package/dist/records/outbox.d.ts +20 -0
  40. package/dist/records/outbox.d.ts.map +1 -0
  41. package/dist/records/outbox.js +44 -0
  42. package/dist/records/outbox.js.map +1 -0
  43. package/dist/registration/user-ground.d.ts +4 -4
  44. package/dist/registration/user-ground.d.ts.map +1 -1
  45. package/dist/registration/user-ground.js +8 -3
  46. package/dist/registration/user-ground.js.map +1 -1
  47. package/dist-cjs/contracts/binding.js +26 -0
  48. package/dist-cjs/contracts/binding.js.map +1 -0
  49. package/dist-cjs/contracts/content.js +99 -0
  50. package/dist-cjs/contracts/content.js.map +1 -0
  51. package/dist-cjs/contracts/docs.js +56 -0
  52. package/dist-cjs/contracts/docs.js.map +1 -0
  53. package/dist-cjs/contracts/events.js +44 -0
  54. package/dist-cjs/contracts/events.js.map +1 -0
  55. package/dist-cjs/contracts/frames/gateway.js +39 -0
  56. package/dist-cjs/contracts/frames/gateway.js.map +1 -0
  57. package/dist-cjs/contracts/frames/stream.js +20 -0
  58. package/dist-cjs/contracts/frames/stream.js.map +1 -0
  59. package/dist-cjs/contracts/frames/tunnel.js +60 -0
  60. package/dist-cjs/contracts/frames/tunnel.js.map +1 -0
  61. package/dist-cjs/contracts/index.js +34 -0
  62. package/dist-cjs/contracts/index.js.map +1 -0
  63. package/dist-cjs/contracts/presence.js +38 -0
  64. package/dist-cjs/contracts/presence.js.map +1 -0
  65. package/dist-cjs/contracts/resources.js +114 -0
  66. package/dist-cjs/contracts/resources.js.map +1 -0
  67. package/dist-cjs/contracts/snapshot.js +31 -0
  68. package/dist-cjs/contracts/snapshot.js.map +1 -0
  69. package/dist-cjs/contracts/validate.js +34 -0
  70. package/dist-cjs/contracts/validate.js.map +1 -0
  71. package/dist-cjs/detection/adapter-contract.js +168 -0
  72. package/dist-cjs/detection/adapter-contract.js.map +1 -0
  73. package/dist-cjs/detection/batch.js +71 -0
  74. package/dist-cjs/detection/batch.js.map +1 -0
  75. package/dist-cjs/detection/classify.js +48 -0
  76. package/dist-cjs/detection/classify.js.map +1 -0
  77. package/dist-cjs/detection/content.js +122 -0
  78. package/dist-cjs/detection/content.js.map +1 -0
  79. package/dist-cjs/detection/continuity.js +88 -0
  80. package/dist-cjs/detection/continuity.js.map +1 -0
  81. package/dist-cjs/detection/diff.js +193 -0
  82. package/dist-cjs/detection/diff.js.map +1 -0
  83. package/dist-cjs/detection/echo.js +25 -0
  84. package/dist-cjs/detection/echo.js.map +1 -0
  85. package/dist-cjs/detection/enrollment.js +189 -0
  86. package/dist-cjs/detection/enrollment.js.map +1 -0
  87. package/dist-cjs/detection/index.js +57 -0
  88. package/dist-cjs/detection/index.js.map +1 -0
  89. package/dist-cjs/detection/record-proposal.js +170 -0
  90. package/dist-cjs/detection/record-proposal.js.map +1 -0
  91. package/dist-cjs/detection/refusal.js +44 -0
  92. package/dist-cjs/detection/refusal.js.map +1 -0
  93. package/dist-cjs/detection/repository.js +67 -0
  94. package/dist-cjs/detection/repository.js.map +1 -0
  95. package/dist-cjs/detection/territory.js +82 -0
  96. package/dist-cjs/detection/territory.js.map +1 -0
  97. package/dist-cjs/detection/watch-boundary.js +51 -0
  98. package/dist-cjs/detection/watch-boundary.js.map +1 -0
  99. package/dist-cjs/entities/bytes.js +92 -0
  100. package/dist-cjs/entities/bytes.js.map +1 -0
  101. package/dist-cjs/entities/cloud.js +171 -0
  102. package/dist-cjs/entities/cloud.js.map +1 -0
  103. package/dist-cjs/entities/index.js +39 -0
  104. package/dist-cjs/entities/index.js.map +1 -0
  105. package/dist-cjs/entities/moves.js +85 -0
  106. package/dist-cjs/entities/moves.js.map +1 -0
  107. package/dist-cjs/entities/repo-states.js +256 -0
  108. package/dist-cjs/entities/repo-states.js.map +1 -0
  109. package/dist-cjs/entities/rules.js +216 -0
  110. package/dist-cjs/entities/rules.js.map +1 -0
  111. package/dist-cjs/entities/types.js +44 -0
  112. package/dist-cjs/entities/types.js.map +1 -0
  113. package/dist-cjs/files/commands.js +120 -0
  114. package/dist-cjs/files/commands.js.map +1 -0
  115. package/dist-cjs/files/index.js +19 -0
  116. package/dist-cjs/files/index.js.map +1 -0
  117. package/dist-cjs/index.js +39 -0
  118. package/dist-cjs/index.js.map +1 -0
  119. package/dist-cjs/machines/arbitration.js +41 -0
  120. package/dist-cjs/machines/arbitration.js.map +1 -0
  121. package/dist-cjs/machines/backoff.js +38 -0
  122. package/dist-cjs/machines/backoff.js.map +1 -0
  123. package/dist-cjs/machines/bootstrap.js +110 -0
  124. package/dist-cjs/machines/bootstrap.js.map +1 -0
  125. package/dist-cjs/machines/chunks.js +72 -0
  126. package/dist-cjs/machines/chunks.js.map +1 -0
  127. package/dist-cjs/machines/index.js +28 -0
  128. package/dist-cjs/machines/index.js.map +1 -0
  129. package/dist-cjs/machines/presence.js +53 -0
  130. package/dist-cjs/machines/presence.js.map +1 -0
  131. package/dist-cjs/merge/index.js +25 -0
  132. package/dist-cjs/merge/index.js.map +1 -0
  133. package/dist-cjs/merge/merge3.js +191 -0
  134. package/dist-cjs/merge/merge3.js.map +1 -0
  135. package/dist-cjs/package.json +1 -0
  136. package/dist-cjs/records/authority.js +31 -0
  137. package/dist-cjs/records/authority.js.map +1 -0
  138. package/dist-cjs/records/codec.js +48 -0
  139. package/dist-cjs/records/codec.js.map +1 -0
  140. package/dist-cjs/records/contracts.js +121 -0
  141. package/dist-cjs/records/contracts.js.map +1 -0
  142. package/dist-cjs/records/inbox.js +37 -0
  143. package/dist-cjs/records/inbox.js.map +1 -0
  144. package/dist-cjs/records/index.js +23 -0
  145. package/dist-cjs/records/index.js.map +1 -0
  146. package/dist-cjs/records/outbox.js +48 -0
  147. package/dist-cjs/records/outbox.js.map +1 -0
  148. package/dist-cjs/registration/index.js +19 -0
  149. package/dist-cjs/registration/index.js.map +1 -0
  150. package/dist-cjs/registration/user-ground.js +183 -0
  151. package/dist-cjs/registration/user-ground.js.map +1 -0
  152. package/dist-cjs/transfer/artifacts.js +75 -0
  153. package/dist-cjs/transfer/artifacts.js.map +1 -0
  154. package/dist-cjs/transfer/batches.js +44 -0
  155. package/dist-cjs/transfer/batches.js.map +1 -0
  156. package/dist-cjs/transfer/download.js +88 -0
  157. package/dist-cjs/transfer/download.js.map +1 -0
  158. package/dist-cjs/transfer/index.js +21 -0
  159. package/dist-cjs/transfer/index.js.map +1 -0
  160. package/dist-cjs/transfer/parallel.js +35 -0
  161. package/dist-cjs/transfer/parallel.js.map +1 -0
  162. package/dist-cjs/transfer/upload.js +161 -0
  163. package/dist-cjs/transfer/upload.js.map +1 -0
  164. package/dist-cjs/watching/coverage.js +54 -0
  165. package/dist-cjs/watching/coverage.js.map +1 -0
  166. package/dist-cjs/watching/index.js +24 -0
  167. package/dist-cjs/watching/index.js.map +1 -0
  168. package/dist-cjs/watching/suspicion.js +105 -0
  169. package/dist-cjs/watching/suspicion.js.map +1 -0
  170. package/dist-cjs/workspace/api.js +66 -0
  171. package/dist-cjs/workspace/api.js.map +1 -0
  172. package/dist-cjs/workspace/identity.js +32 -0
  173. package/dist-cjs/workspace/identity.js.map +1 -0
  174. package/dist-cjs/workspace/index.js +14 -0
  175. package/dist-cjs/workspace/index.js.map +1 -0
  176. package/dist-cjs/workspace/memory-store.js +21 -0
  177. package/dist-cjs/workspace/memory-store.js.map +1 -0
  178. package/dist-cjs/workspace/registry.js +98 -0
  179. package/dist-cjs/workspace/registry.js.map +1 -0
  180. package/dist-cjs/workspace/types.js +3 -0
  181. package/dist-cjs/workspace/types.js.map +1 -0
  182. package/package.json +30 -8
  183. package/dist/contracts/mutation.d.ts +0 -51
  184. package/dist/contracts/mutation.d.ts.map +0 -1
  185. package/dist/contracts/mutation.js +0 -55
  186. package/dist/contracts/mutation.js.map +0 -1
  187. package/dist/machines/journal.d.ts +0 -63
  188. package/dist/machines/journal.d.ts.map +0 -1
  189. package/dist/machines/journal.js +0 -71
  190. package/dist/machines/journal.js.map +0 -1
  191. package/dist/machines/ordering.d.ts +0 -53
  192. package/dist/machines/ordering.d.ts.map +0 -1
  193. package/dist/machines/ordering.js +0 -87
  194. package/dist/machines/ordering.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-contract.js","sourceRoot":"","sources":["../../src/detection/adapter-contract.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;;AA8DH,sCA6CC;AAQD,oCAyBC;AAxID,gEAAgE;AACnD,QAAA,KAAK,GAAoB,MAAM,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ;CAClE,CAAC,CAAC;AAuBH;;;;;;;;;GASG;AACU,QAAA,OAAO,GAAuD,MAAM,CAAC,MAAM,CAAC;IACvF,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;CACjC,CAAC,CAAC;AAgBH;;;GAGG;AACH,SAAgB,aAAa,CAAC,OAAgB;IAC5C,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;QACvF,CAAC,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,mCAAmC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IACjC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oEAAoE,CAAC,CAAC;IAChG,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,0DAA0D,CAAC,CAAC;IACtF,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,IAAI,CAAE,aAA2B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,kCAAkC,aAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzG,CAAC;QACD,MAAM,MAAM,GAAG,eAAO,CAAC,IAAY,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,UAAU,IAAI,2FAA2F,CAAC,CAAC;QACrI,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,UAAU,IAAI,kDAAkD,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,UAAU,IAAI,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;QAC5L,CAAC;QACD,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,IAAI,IAAI,OAAO,wEAAwE,CAAC,CAAC;YACxH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAuC,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAC1B,QAA2B,EAC3B,QAA0B;IAE1B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;IACpD,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,CAAC,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YACrH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,yBAAyB,CAAC,CAAC;YACtI,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAOD;;;;;;;;;;GAUG;AACI,MAAM,UAAU,GAAG,CACxB,KAAiB,EACoF,EAAE,CACvG,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;IACjD,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrB,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AALpC,QAAA,UAAU,cAK0B;AAEjD;;;;;;;;;;GAUG;AACU,QAAA,gBAAgB,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC/D,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,4FAA4F;KACxG,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;CACzB,CAAC,CAAC"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Net-difference planning for one settled Watch batch.
4
+ *
5
+ * Identity reconciliation and type-specific capture happen before this seam.
6
+ * This seam makes cancellation, unsettled truth, lifecycle authority, coverage
7
+ * requests, and Watch settlement one total decision.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.planDetectionBatch = planDetectionBatch;
11
+ const types_js_1 = require("../entities/types.js");
12
+ const record_proposal_js_1 = require("./record-proposal.js");
13
+ const watch_boundary_js_1 = require("./watch-boundary.js");
14
+ const newlyDirectoryGround = (transition) => transition.relPath !== ''
15
+ &&
16
+ types_js_1.CONTAINERS.has(transition.result.type)
17
+ && (transition.base === null || !types_js_1.CONTAINERS.has(transition.base.type));
18
+ /** Plan the complete net difference. No partial proposals escape an unsettled batch. */
19
+ function planDetectionBatch(batch, transitions) {
20
+ const unsettled = transitions.filter((transition) => transition.truth === 'unsettled');
21
+ if (unsettled.length > 0) {
22
+ return Object.freeze({
23
+ kind: 'retry',
24
+ reasons: Object.freeze(unsettled.map((transition) => transition.reason ?? 'truth is unsettled')),
25
+ });
26
+ }
27
+ const proposals = [];
28
+ const missing = [];
29
+ const createdDirectories = [];
30
+ for (const transition of transitions) {
31
+ if (transition.truth === 'present') {
32
+ const proposal = (0, record_proposal_js_1.detectedChangeProposal)(transition);
33
+ if (proposal)
34
+ proposals.push(proposal);
35
+ if (newlyDirectoryGround(transition)) {
36
+ createdDirectories.push(transition.relPath);
37
+ }
38
+ continue;
39
+ }
40
+ if (transition.truth !== 'absent') {
41
+ throw new Error('unsettled truth escaped the batch retry gate');
42
+ }
43
+ if (transition.base === null)
44
+ continue; // absent before and after: no entity existed
45
+ if (transition.base.status !== 'active')
46
+ continue;
47
+ if (transition.lifecycleAuthorization !== 'trash') {
48
+ missing.push(transition.base);
49
+ continue;
50
+ }
51
+ if (!transition.trashedResult) {
52
+ throw new Error('authorized Trash requires the entity law\'s exact trashed result');
53
+ }
54
+ const proposal = (0, record_proposal_js_1.detectedChangeProposal)({
55
+ base: transition.base,
56
+ result: transition.trashedResult,
57
+ replay: { kind: 'structure' },
58
+ lifecycleAuthorization: 'trash',
59
+ });
60
+ if (proposal)
61
+ proposals.push(proposal);
62
+ }
63
+ return Object.freeze({
64
+ kind: 'ready',
65
+ proposals: Object.freeze(proposals),
66
+ missing: Object.freeze(missing),
67
+ coverage: (0, watch_boundary_js_1.directoryCoverageRequests)(batch, createdDirectories),
68
+ settle: batch,
69
+ });
70
+ }
71
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/detection/batch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Amalgm's file-type policy: which physical type a piece of file ground
4
+ * takes. Ratified by entity-model.md ("Formats live underneath the file
5
+ * types"; text versus binary is an adapter difference, never an
6
+ * identity difference).
7
+ *
8
+ * Classification is an INJECTED policy everywhere it is used — the
9
+ * registration boundary and its lenses refuse to construct without one
10
+ * — so it lives in its own file with no other job: one definition,
11
+ * replaceable whole.
12
+ *
13
+ * The rule is the oldest one there is: bytes holding a NUL are not
14
+ * text. What matters is WHERE that fact comes from. It is not read
15
+ * here. Detect's single read of a file produces its fingerprint and
16
+ * this report together, and this policy only names the type that report
17
+ * implies.
18
+ *
19
+ * That is the whole law: A FILE'S HASH AND ITS TYPE DESCRIBE THE SAME
20
+ * OBSERVED BYTES. A policy that opened the ground itself would be a
21
+ * second look — and a second look can meet different bytes, or none at
22
+ * all, leaving a record whose type contradicts the payload beside it.
23
+ * So this function takes evidence, never a path; it is total, and it
24
+ * cannot fail.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.classifyFile = classifyFile;
28
+ exports.classifyDirectory = classifyDirectory;
29
+ exports.classifyRegisteredRoot = classifyRegisteredRoot;
30
+ exports.isRepositoryMetadataEntry = isRepositoryMetadataEntry;
31
+ function classifyFile({ binary }) {
32
+ return binary ? 'file.binary' : 'file.text';
33
+ }
34
+ function classifyDirectory({ repository }) {
35
+ return repository ? 'repo.git' : 'folder';
36
+ }
37
+ /** A deliberately registered external directory remains a tree root. A Git
38
+ * root wears `repo.git`; an ordinary root wears `workspace`. */
39
+ function classifyRegisteredRoot({ repository }) {
40
+ return repository ? 'repo.git' : 'workspace';
41
+ }
42
+ /** `.git` is cargo of a repository entity, never one of its worktree
43
+ * children. Marker presence makes the parent a repository before this rule is
44
+ * asked, regardless of whether Git can currently consume that marker. */
45
+ function isRepositoryMetadataEntry(parentType, name) {
46
+ return parentType === 'repo.git' && name === '.git';
47
+ }
48
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/detection/classify.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;;AAWH,oCAEC;AASD,8CAEC;AAID,wDAEC;AAKD,8DAEC;AA1BD,SAAgB,YAAY,CAAC,EAAE,MAAM,EAAoB;IACvD,OAAO,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;AAC9C,CAAC;AASD,SAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAsB;IAClE,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5C,CAAC;AAED;gEACgE;AAChE,SAAgB,sBAAsB,CAAC,EAAE,UAAU,EAAsB;IACvE,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;AAC/C,CAAC;AAED;;yEAEyE;AACzE,SAAgB,yBAAyB,CAAC,UAA8C,EAAE,IAAY;IACpG,OAAO,UAAU,KAAK,UAAU,IAAI,IAAI,KAAK,MAAM,CAAC;AACtD,CAAC"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /** Type-sensitive content capture from Detection's one settled byte read. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.textSplice = textSplice;
5
+ exports.captureTextChange = captureTextChange;
6
+ exports.reproduceTextChange = reproduceTextChange;
7
+ exports.captureBinaryChange = captureBinaryChange;
8
+ exports.captureLinkChange = captureLinkChange;
9
+ const content_js_1 = require("../contracts/content.js");
10
+ const bytes_js_1 = require("../entities/bytes.js");
11
+ const upload_js_1 = require("../transfer/upload.js");
12
+ const capturedArtifact = (entityId, entityType, kind, input, sha256Hex) => {
13
+ const bytes = input.slice();
14
+ const artifact = {
15
+ entityId,
16
+ entityType,
17
+ kind,
18
+ contentHash: sha256Hex(bytes),
19
+ };
20
+ return Object.freeze({
21
+ artifact: Object.freeze(artifact),
22
+ bytes,
23
+ manifest: (0, upload_js_1.deriveUploadManifest)(artifact, bytes, sha256Hex),
24
+ });
25
+ };
26
+ /** The smallest single replacement span that transforms base bytes to result. */
27
+ function textSplice(base, result) {
28
+ let prefix = 0;
29
+ const shared = Math.min(base.byteLength, result.byteLength);
30
+ while (prefix < shared && base[prefix] === result[prefix])
31
+ prefix += 1;
32
+ let suffix = 0;
33
+ while (suffix < shared - prefix
34
+ && base[base.byteLength - suffix - 1] === result[result.byteLength - suffix - 1]) {
35
+ suffix += 1;
36
+ }
37
+ return Object.freeze({
38
+ offset: prefix,
39
+ deleteBytes: base.byteLength - prefix - suffix,
40
+ insert: result.slice(prefix, result.byteLength - suffix),
41
+ });
42
+ }
43
+ /**
44
+ * Capture text as one verified byte splice when that instruction is smaller
45
+ * than the result bytes. The immutable snapshot is always sealed as repair and
46
+ * cold-materialization truth.
47
+ */
48
+ function captureTextChange(entityId, base, result, sha256Hex) {
49
+ const cargo = capturedArtifact(entityId, 'file.text', 'file', result, sha256Hex);
50
+ const basePayloadVersion = base === null ? null : sha256Hex(base);
51
+ if (basePayloadVersion === cargo.artifact.contentHash)
52
+ return null;
53
+ const delta = base === null ? null : textSplice(base, result);
54
+ // Two numeric fields are fixed overhead on the wire. This conservative
55
+ // estimate keeps a replace-all operation on the snapshot path.
56
+ const useDelta = delta !== null && delta.insert.byteLength + 16 < result.byteLength;
57
+ return Object.freeze({
58
+ replay: Object.freeze({
59
+ kind: 'file.text',
60
+ mode: useDelta ? 'delta' : 'snapshot',
61
+ basePayloadVersion,
62
+ resultPayloadVersion: cargo.artifact.contentHash,
63
+ delta: useDelta ? delta : null,
64
+ }),
65
+ cargo,
66
+ });
67
+ }
68
+ /** Apply a text replay and verify its exact result, falling back to snapshot. */
69
+ function reproduceTextChange(base, replay, snapshot, sha256Hex) {
70
+ const verifiedSnapshot = () => {
71
+ if (sha256Hex(snapshot) !== replay.resultPayloadVersion) {
72
+ throw new Error('text snapshot does not match its declared result');
73
+ }
74
+ return snapshot.slice();
75
+ };
76
+ if (replay.mode !== 'delta' || replay.delta === null || base === null
77
+ || sha256Hex(base) !== replay.basePayloadVersion) {
78
+ return verifiedSnapshot();
79
+ }
80
+ const { offset, deleteBytes, insert } = replay.delta;
81
+ if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(deleteBytes)
82
+ || offset < 0 || deleteBytes < 0 || offset + deleteBytes > base.byteLength) {
83
+ return verifiedSnapshot();
84
+ }
85
+ const result = new Uint8Array(base.byteLength - deleteBytes + insert.byteLength);
86
+ result.set(base.subarray(0, offset), 0);
87
+ result.set(insert, offset);
88
+ result.set(base.subarray(offset + deleteBytes), offset + insert.byteLength);
89
+ return sha256Hex(result) === replay.resultPayloadVersion ? result : verifiedSnapshot();
90
+ }
91
+ /** Binary replay is the existing exact content manifest; Transfer moves gaps. */
92
+ function captureBinaryChange(entityId, previous, result, sha256Hex) {
93
+ if (previous !== null && !(0, content_js_1.checkContentManifest)(previous).ok) {
94
+ throw new Error('previous binary content manifest is invalid');
95
+ }
96
+ const cargo = capturedArtifact(entityId, 'file.binary', 'file', result, sha256Hex);
97
+ if (previous?.contentHash === cargo.artifact.contentHash)
98
+ return null;
99
+ return Object.freeze({
100
+ replay: Object.freeze({
101
+ kind: 'file.binary',
102
+ resultPayloadVersion: cargo.artifact.contentHash,
103
+ manifest: cargo.manifest,
104
+ }),
105
+ cargo,
106
+ });
107
+ }
108
+ /** A symlink's portable content is the literal target text, never its target. */
109
+ function captureLinkChange(entityId, previousTarget, target, sha256Hex) {
110
+ if (previousTarget === target)
111
+ return null;
112
+ const cargo = capturedArtifact(entityId, 'link', 'link', (0, bytes_js_1.utf8Encode)(target), sha256Hex);
113
+ return Object.freeze({
114
+ replay: Object.freeze({
115
+ kind: 'link',
116
+ resultPayloadVersion: cargo.artifact.contentHash,
117
+ target,
118
+ }),
119
+ cargo,
120
+ });
121
+ }
122
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/detection/content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * Root continuity verdicts: what a root's WITNESSED physical identity
4
+ * is, whether its recorded address still holds its ground, and whether
5
+ * a piece of ground rescues a moved root. Ratified by entity-model.md
6
+ * ("Ground that moves is rescued by continuity" — the directory law
7
+ * lifted to roots; "the follow rides witnessed continuity, never
8
+ * clairvoyance").
9
+ *
10
+ * Pure verdicts over injected answers — the host supplies the one look
11
+ * at an address (`statAt`) and the store's witnessed channel row
12
+ * (`channelIdentity`); the ACTIONS a verdict triggers (rebind, presence
13
+ * transitions, the undecided-address decision) stay in the host's
14
+ * wiring, because they re-aim watchers and scans.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createContinuity = createContinuity;
18
+ function createContinuity({ statAt, channelIdentity }) {
19
+ /**
20
+ * A root's WITNESSED physical identity, for continuity rescue.
21
+ * Directory roots carry their own device:inode (nothing replaces a
22
+ * directory's inode in place). A single-ground root's identity lives
23
+ * in its one channel row. Ground that changed inodes inside a
24
+ * still-open settle window is unwitnessed — no evidence, no claim.
25
+ */
26
+ function rootIdentity(root) {
27
+ if (root.kind !== 'file') {
28
+ const { device, inode } = root;
29
+ return device == null || inode == null ? null : { device, inode };
30
+ }
31
+ return channelIdentity(root.rootId);
32
+ }
33
+ /** Orphaned means the recorded address no longer holds this ground. */
34
+ function orphanedAtAddress(root) {
35
+ const identity = rootIdentity(root);
36
+ if (!identity)
37
+ return false;
38
+ const stat = statAt(root.path);
39
+ if (!stat)
40
+ return true;
41
+ return stat.device !== identity.device || stat.inode !== identity.inode;
42
+ }
43
+ /**
44
+ * Continuity claims a root exactly like it claims the directories
45
+ * inside one: unique device:inode match, exactly one candidate, and
46
+ * only for a path-orphan — a root whose recorded address still holds
47
+ * its ground is never stolen by a lookalike.
48
+ */
49
+ function findMovedRoot(stat, roots) {
50
+ const wantDir = stat.kind === 'dir';
51
+ const matches = roots.filter((root) => {
52
+ if (wantDir !== (root.kind !== 'file'))
53
+ return false;
54
+ const identity = rootIdentity(root);
55
+ return identity !== null && identity.device === stat.device && identity.inode === stat.inode;
56
+ });
57
+ const only = matches.length === 1 ? matches[0] : null;
58
+ return only && orphanedAtAddress(only) ? only : null;
59
+ }
60
+ /**
61
+ * A scan's evidence horizon is the root's ground; the root's own
62
+ * address is the horizon's edge. Ground missing there — or a
63
+ * directory root's address wearing a different physical identity — is
64
+ * UNDECIDABLE from here: moved away, deleted, or replaced by a
65
+ * lookalike all present the same address, and concluding "deleted"
66
+ * would end every channel a rescue could have saved. So the scan
67
+ * concludes nothing: beliefs freeze, the referee convicts the
68
+ * divergence, and the next enrollment moment decides — naming the new
69
+ * address rescues, re-naming this one adopts, and explicit removal is
70
+ * the only deletion (an external filesystem change is never
71
+ * permission to end identity). A single-ground root's address
72
+ * lawfully churns inodes (atomic saves, retargets), so only absence —
73
+ * or foreign directory ground — freezes it; presence is the file
74
+ * laws' business.
75
+ */
76
+ function addressUndecided(root) {
77
+ const stat = statAt(root.path);
78
+ if (!stat)
79
+ return true;
80
+ if (root.kind === 'file')
81
+ return stat.kind !== 'file' && stat.kind !== 'link';
82
+ if (stat.kind !== 'dir')
83
+ return true;
84
+ return root.device != null && (stat.device !== root.device || stat.inode !== root.inode);
85
+ }
86
+ return { rootIdentity, findMovedRoot, addressUndecided };
87
+ }
88
+ //# sourceMappingURL=continuity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuity.js","sourceRoot":"","sources":["../../src/detection/continuity.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;AA8CH,4CAmEC;AAnED,SAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAmB;IAC3E;;;;;;OAMG;IACH,SAAS,YAAY,CAAC,IAAoB;QACxC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YAC/B,OAAO,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACpE,CAAC;QACD,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,uEAAuE;IACvE,SAAS,iBAAiB,CAAC,IAAoB;QAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC;IAC1E,CAAC;IAED;;;;;OAKG;IACH,SAAS,aAAa,CAAC,IAAgB,EAAE,KAAgC;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC;QACpC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACpC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;YACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;QAC/F,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,OAAO,IAAI,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,SAAS,gBAAgB,CAAC,IAAoB;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;QAC9E,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3F,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ /**
3
+ * The compare core of detection: rows (store memory) + entries (disk
4
+ * truth) in, actions out. Pure — the walk that produces entries and the
5
+ * hashing that settles `checks` are the host's; only the identity
6
+ * verdicts live here. Ratified by entity-model.md ("Address and
7
+ * physical continuity are the two identity witnesses, never content").
8
+ *
9
+ * Three kinds of channel, three orderings of the same two witnesses:
10
+ *
11
+ * - Files: path claims first; the inode rescues path-orphans. An
12
+ * atomic save replaces a file's inode in place, so the address must
13
+ * absorb that churn.
14
+ * - Directories: physical continuity claims first; the address claims
15
+ * what no inode claims. Nothing replaces a directory's inode in
16
+ * place, so a known inode at a new address IS the directory, moved.
17
+ * - Links: the FILE rules, for the file reason — retarget is unlink +
18
+ * recreate, so the inode churns exactly like an atomic save.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.matchByInode = matchByInode;
22
+ exports.diffDirState = diffDirState;
23
+ exports.diffLinkState = diffLinkState;
24
+ exports.diffRootState = diffRootState;
25
+ /**
26
+ * Physical continuity, shared by every compare function: a row and an
27
+ * entry sharing one device:inode, exactly one match on both sides → the
28
+ * same physical thing. Anything else is never guessed. For files this
29
+ * rescues path-orphans (rule 2); for directories it IS rule 1.
30
+ */
31
+ function matchByInode(rows, entries) {
32
+ const one = (map, key, value) => map.set(key, map.has(key) ? 'many' : value);
33
+ const rowsByInode = new Map();
34
+ for (const row of rows)
35
+ one(rowsByInode, `${row.device}:${row.inode}`, row);
36
+ const entriesByInode = new Map();
37
+ for (const entry of entries)
38
+ one(entriesByInode, `${entry.device}:${entry.inode}`, entry);
39
+ const matched = [];
40
+ for (const [key, entry] of entriesByInode) {
41
+ const row = rowsByInode.get(key);
42
+ if (entry === 'many' || !row || row === 'many')
43
+ continue;
44
+ matched.push({ row, entry });
45
+ }
46
+ return matched;
47
+ }
48
+ /**
49
+ * The compare function for directory channels — the file identity rules
50
+ * in the OPPOSITE order, for the mirror reason. A file's inode is
51
+ * replaced in place on every atomic save, so for files the path must
52
+ * absorb that churn (path claims first). Nothing replaces a directory's
53
+ * inode in place: a known inode at a new address IS the directory,
54
+ * moved — even when its old address was reoccupied in the same interval
55
+ * (two directories exchanging names cross by inode, exactly like the
56
+ * files inside them). So:
57
+ * 1. Physical continuity claims the channel: unique device:inode,
58
+ * whole sets, same path = continued, new path = rename.
59
+ * 2. The address claims what no inode claims — recreation under an old
60
+ * name is the same channel wearing a never-seen inode (`retags`,
61
+ * silent).
62
+ * 3. Leftover entries are creates; leftover rows are deletes.
63
+ * No content: a directory's membership is derived state upstream, so
64
+ * there is nothing to hash or check.
65
+ */
66
+ function diffDirState(rows, entries) {
67
+ const matched = matchByInode(rows, entries);
68
+ const matchedRowIds = new Set(matched.map((pair) => pair.row.dirId));
69
+ const matchedEntries = new Set(matched.map((pair) => pair.entry));
70
+ const rowsByPath = new Map(rows.filter((row) => !matchedRowIds.has(row.dirId))
71
+ .map((row) => [row.relPath, row]));
72
+ const retags = [];
73
+ const creates = [];
74
+ for (const entry of entries) {
75
+ if (matchedEntries.has(entry))
76
+ continue;
77
+ const row = rowsByPath.get(entry.relPath);
78
+ if (row) {
79
+ rowsByPath.delete(entry.relPath);
80
+ retags.push({ row, entry });
81
+ }
82
+ else {
83
+ creates.push(entry);
84
+ }
85
+ }
86
+ return {
87
+ renames: matched.filter((pair) => pair.row.relPath !== pair.entry.relPath),
88
+ retags,
89
+ creates,
90
+ deletes: [...rowsByPath.values()],
91
+ };
92
+ }
93
+ /**
94
+ * The compare function for link channels — the FILE identity rules, for
95
+ * the file reason: a symlink cannot be retargeted in place (retarget is
96
+ * unlink + recreate, so the inode churns exactly like an atomic save),
97
+ * so the path absorbs that churn and claims first; the inode rescues
98
+ * path-orphans (`mv` preserves a symlink's inode). The payload is the
99
+ * target string, already read at walk time. A consequence worth naming:
100
+ * two links exchanging names read as two retargets (path-first),
101
+ * because a link's meaning IS its written address.
102
+ * 1. Path claims the channel: same target = continued (a new inode
103
+ * under an old name with an old target is silent recreation),
104
+ * different target = changed.
105
+ * 2. Inode rescues path-orphans: renames.
106
+ * 3. Leftover entries are creates; leftover rows are deletes.
107
+ */
108
+ function diffLinkState(rows, entries) {
109
+ const changes = [];
110
+ const retags = [];
111
+ const rowsByPath = new Map(rows.map((row) => [row.relPath, row]));
112
+ const claimedRowIds = new Set();
113
+ const orphanEntries = [];
114
+ for (const entry of entries) {
115
+ const row = rowsByPath.get(entry.relPath);
116
+ if (!row) {
117
+ orphanEntries.push(entry);
118
+ continue;
119
+ }
120
+ claimedRowIds.add(row.linkId);
121
+ if (row.target !== entry.target)
122
+ changes.push({ row, entry });
123
+ else if (row.device !== entry.device || row.inode !== entry.inode)
124
+ retags.push({ row, entry });
125
+ }
126
+ const orphanRows = rows.filter((row) => !claimedRowIds.has(row.linkId));
127
+ const renames = matchByInode(orphanRows, orphanEntries);
128
+ const renamedRowIds = new Set(renames.map((pair) => pair.row.linkId));
129
+ const renamedEntries = new Set(renames.map((pair) => pair.entry));
130
+ return {
131
+ changes,
132
+ retags,
133
+ renames,
134
+ creates: orphanEntries.filter((entry) => !renamedEntries.has(entry)),
135
+ deletes: orphanRows.filter((row) => !renamedRowIds.has(row.linkId)),
136
+ };
137
+ }
138
+ /**
139
+ * The compare function for file channels — doorbells and rescans both
140
+ * end here. Hashing is deferred — `checks` name the files whose content
141
+ * must be read before an event may be claimed.
142
+ *
143
+ * Identity rules, in order:
144
+ * 1. Path claims the channel. Same rel_path = same file_id, even when
145
+ * the inode changed (atomic saves replace the inode on every
146
+ * write).
147
+ * 2. Inode rescues path-orphans (matchByInode above).
148
+ * 3. Leftover entries are creates; leftover rows are deletes.
149
+ *
150
+ * The single stat-shortcut this layer allows itself: a (size, mtime,
151
+ * inode) triple identical to the stored one is skipped as unchanged —
152
+ * but only when the mtime is strictly older than the moment we last
153
+ * read the bytes (git's "racily clean" rule), and only when nothing
154
+ * pointed at the file. A path named in `mustCheck` (the doorbell said
155
+ * so) is always hashed: timestamps can lie, a delivered watcher event
156
+ * cannot be un-delivered.
157
+ */
158
+ function diffRootState(rows, entries, mustCheck = null) {
159
+ const checks = [];
160
+ let unchanged = 0;
161
+ const rowsByPath = new Map(rows.map((row) => [row.relPath, row]));
162
+ const claimedRowIds = new Set();
163
+ const orphanEntries = [];
164
+ for (const entry of entries) {
165
+ const row = rowsByPath.get(entry.relPath);
166
+ if (!row) {
167
+ orphanEntries.push(entry);
168
+ continue;
169
+ }
170
+ claimedRowIds.add(row.fileId);
171
+ const statsMatch = row.size === entry.size && row.mtimeMs === entry.mtimeMs && row.inode === entry.inode;
172
+ const provablyBeforeLastRead = typeof row.hashedAtMs === 'number' && entry.mtimeMs < row.hashedAtMs;
173
+ const named = mustCheck !== null && mustCheck.has(entry.relPath);
174
+ if (statsMatch && provablyBeforeLastRead && !named) {
175
+ unchanged += 1;
176
+ }
177
+ else {
178
+ checks.push({ row, entry });
179
+ }
180
+ }
181
+ const orphanRows = rows.filter((row) => !claimedRowIds.has(row.fileId));
182
+ const renames = matchByInode(orphanRows, orphanEntries);
183
+ const renamedRowIds = new Set(renames.map((pair) => pair.row.fileId));
184
+ const renamedEntries = new Set(renames.map((pair) => pair.entry));
185
+ return {
186
+ checks,
187
+ renames,
188
+ creates: orphanEntries.filter((entry) => !renamedEntries.has(entry)),
189
+ deletes: orphanRows.filter((row) => !renamedRowIds.has(row.fileId)),
190
+ unchanged,
191
+ };
192
+ }
193
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/detection/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * Echo judgment after incoming Apply.
4
+ *
5
+ * Apply never suppresses watcher rings. It verifies the incoming result and
6
+ * advances the notebook. The retained suspicion then uses this ordinary
7
+ * equality judgment: exact expected truth is silence; different truth is a
8
+ * real local change; unreadable truth is retried.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.echoDecision = echoDecision;
12
+ function echoDecision(notebook, observed) {
13
+ if (observed.truth === 'unsettled') {
14
+ return observed.reason === undefined
15
+ ? { kind: 'retry' }
16
+ : { kind: 'retry', reason: observed.reason };
17
+ }
18
+ if (notebook.status === 'active') {
19
+ return observed.truth === 'present' && observed.version === notebook.version
20
+ ? { kind: 'silence' }
21
+ : { kind: 'detect' };
22
+ }
23
+ return observed.truth === 'absent' ? { kind: 'silence' } : { kind: 'detect' };
24
+ }
25
+ //# sourceMappingURL=echo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echo.js","sourceRoot":"","sources":["../../src/detection/echo.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAUH,oCAeC;AAfD,SAAgB,YAAY,CAC1B,QAAuD,EACvD,QAAsB;IAEtB,IAAI,QAAQ,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;QACnC,OAAO,QAAQ,CAAC,MAAM,KAAK,SAAS;YAClC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;YACnB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;YAC1E,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE;YACrB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChF,CAAC"}