groundswell 0.0.2 → 0.0.3

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 (633) hide show
  1. package/dist/__tests__/adversarial/attachChild-performance.test.d.ts +16 -0
  2. package/dist/__tests__/adversarial/attachChild-performance.test.d.ts.map +1 -0
  3. package/dist/__tests__/adversarial/attachChild-performance.test.js +187 -0
  4. package/dist/__tests__/adversarial/attachChild-performance.test.js.map +1 -0
  5. package/dist/__tests__/adversarial/circular-reference.test.d.ts +13 -0
  6. package/dist/__tests__/adversarial/circular-reference.test.d.ts.map +1 -0
  7. package/dist/__tests__/adversarial/circular-reference.test.js +92 -0
  8. package/dist/__tests__/adversarial/circular-reference.test.js.map +1 -0
  9. package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts +16 -0
  10. package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts.map +1 -0
  11. package/dist/__tests__/adversarial/complex-circular-reference.test.js +127 -0
  12. package/dist/__tests__/adversarial/complex-circular-reference.test.js.map +1 -0
  13. package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts +21 -0
  14. package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts.map +1 -0
  15. package/dist/__tests__/adversarial/concurrent-task-failures.test.js +667 -0
  16. package/dist/__tests__/adversarial/concurrent-task-failures.test.js.map +1 -0
  17. package/dist/__tests__/adversarial/deep-analysis.test.d.ts +6 -0
  18. package/dist/__tests__/adversarial/deep-analysis.test.d.ts.map +1 -0
  19. package/dist/__tests__/adversarial/deep-analysis.test.js +877 -0
  20. package/dist/__tests__/adversarial/deep-analysis.test.js.map +1 -0
  21. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts +13 -0
  22. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts.map +1 -0
  23. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js +186 -0
  24. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js.map +1 -0
  25. package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts +6 -0
  26. package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts.map +1 -0
  27. package/dist/__tests__/adversarial/e2e-prd-validation.test.js +626 -0
  28. package/dist/__tests__/adversarial/e2e-prd-validation.test.js.map +1 -0
  29. package/dist/__tests__/adversarial/edge-case.test.d.ts +6 -0
  30. package/dist/__tests__/adversarial/edge-case.test.d.ts.map +1 -0
  31. package/dist/__tests__/adversarial/edge-case.test.js +857 -0
  32. package/dist/__tests__/adversarial/edge-case.test.js.map +1 -0
  33. package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts +20 -0
  34. package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts.map +1 -0
  35. package/dist/__tests__/adversarial/error-merge-strategy.test.js +907 -0
  36. package/dist/__tests__/adversarial/error-merge-strategy.test.js.map +1 -0
  37. package/dist/__tests__/adversarial/incremental-performance.test.d.ts +2 -0
  38. package/dist/__tests__/adversarial/incremental-performance.test.d.ts.map +1 -0
  39. package/dist/__tests__/adversarial/incremental-performance.test.js +113 -0
  40. package/dist/__tests__/adversarial/incremental-performance.test.js.map +1 -0
  41. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts +22 -0
  42. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts.map +1 -0
  43. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js +383 -0
  44. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js.map +1 -0
  45. package/dist/__tests__/adversarial/observer-propagation.test.d.ts +21 -0
  46. package/dist/__tests__/adversarial/observer-propagation.test.d.ts.map +1 -0
  47. package/dist/__tests__/adversarial/observer-propagation.test.js +404 -0
  48. package/dist/__tests__/adversarial/observer-propagation.test.js.map +1 -0
  49. package/dist/__tests__/adversarial/parent-validation.test.d.ts +13 -0
  50. package/dist/__tests__/adversarial/parent-validation.test.d.ts.map +1 -0
  51. package/dist/__tests__/adversarial/parent-validation.test.js +128 -0
  52. package/dist/__tests__/adversarial/parent-validation.test.js.map +1 -0
  53. package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts +20 -0
  54. package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts.map +1 -0
  55. package/dist/__tests__/adversarial/prd-12-2-compliance.test.js +482 -0
  56. package/dist/__tests__/adversarial/prd-12-2-compliance.test.js.map +1 -0
  57. package/dist/__tests__/adversarial/prd-compliance.test.d.ts +6 -0
  58. package/dist/__tests__/adversarial/prd-compliance.test.d.ts.map +1 -0
  59. package/dist/__tests__/adversarial/prd-compliance.test.js +886 -0
  60. package/dist/__tests__/adversarial/prd-compliance.test.js.map +1 -0
  61. package/dist/__tests__/compatibility/backward-compatibility.test.d.ts +22 -0
  62. package/dist/__tests__/compatibility/backward-compatibility.test.d.ts.map +1 -0
  63. package/dist/__tests__/compatibility/backward-compatibility.test.js +1843 -0
  64. package/dist/__tests__/compatibility/backward-compatibility.test.js.map +1 -0
  65. package/dist/__tests__/helpers/index.d.ts +10 -0
  66. package/dist/__tests__/helpers/index.d.ts.map +1 -0
  67. package/{src/__tests__/helpers/index.ts → dist/__tests__/helpers/index.js} +2 -10
  68. package/dist/__tests__/helpers/index.js.map +1 -0
  69. package/dist/__tests__/helpers/tree-verification.d.ts +90 -0
  70. package/dist/__tests__/helpers/tree-verification.d.ts.map +1 -0
  71. package/dist/__tests__/helpers/tree-verification.js +202 -0
  72. package/dist/__tests__/helpers/tree-verification.js.map +1 -0
  73. package/dist/__tests__/integration/agent-workflow.test.d.ts +2 -0
  74. package/dist/__tests__/integration/agent-workflow.test.d.ts.map +1 -0
  75. package/dist/__tests__/integration/agent-workflow.test.js +256 -0
  76. package/dist/__tests__/integration/agent-workflow.test.js.map +1 -0
  77. package/dist/__tests__/integration/bidirectional-consistency.test.d.ts +14 -0
  78. package/dist/__tests__/integration/bidirectional-consistency.test.d.ts.map +1 -0
  79. package/dist/__tests__/integration/bidirectional-consistency.test.js +668 -0
  80. package/dist/__tests__/integration/bidirectional-consistency.test.js.map +1 -0
  81. package/dist/__tests__/integration/observer-logging.test.d.ts +2 -0
  82. package/dist/__tests__/integration/observer-logging.test.d.ts.map +1 -0
  83. package/dist/__tests__/integration/observer-logging.test.js +517 -0
  84. package/dist/__tests__/integration/observer-logging.test.js.map +1 -0
  85. package/dist/__tests__/integration/tree-mirroring.test.d.ts +2 -0
  86. package/dist/__tests__/integration/tree-mirroring.test.d.ts.map +1 -0
  87. package/dist/__tests__/integration/tree-mirroring.test.js +117 -0
  88. package/dist/__tests__/integration/tree-mirroring.test.js.map +1 -0
  89. package/dist/__tests__/integration/workflow-reparenting.test.d.ts +12 -0
  90. package/dist/__tests__/integration/workflow-reparenting.test.d.ts.map +1 -0
  91. package/dist/__tests__/integration/workflow-reparenting.test.js +239 -0
  92. package/dist/__tests__/integration/workflow-reparenting.test.js.map +1 -0
  93. package/dist/__tests__/unit/agent.test.d.ts +2 -0
  94. package/dist/__tests__/unit/agent.test.d.ts.map +1 -0
  95. package/dist/__tests__/unit/agent.test.js +143 -0
  96. package/dist/__tests__/unit/agent.test.js.map +1 -0
  97. package/dist/__tests__/unit/cache-key.test.d.ts +5 -0
  98. package/dist/__tests__/unit/cache-key.test.d.ts.map +1 -0
  99. package/dist/__tests__/unit/cache-key.test.js +145 -0
  100. package/dist/__tests__/unit/cache-key.test.js.map +1 -0
  101. package/dist/__tests__/unit/cache.test.d.ts +5 -0
  102. package/dist/__tests__/unit/cache.test.d.ts.map +1 -0
  103. package/dist/__tests__/unit/cache.test.js +132 -0
  104. package/dist/__tests__/unit/cache.test.js.map +1 -0
  105. package/dist/__tests__/unit/context.test.d.ts +2 -0
  106. package/dist/__tests__/unit/context.test.d.ts.map +1 -0
  107. package/dist/__tests__/unit/context.test.js +220 -0
  108. package/dist/__tests__/unit/context.test.js.map +1 -0
  109. package/dist/__tests__/unit/decorators.test.d.ts +2 -0
  110. package/dist/__tests__/unit/decorators.test.d.ts.map +1 -0
  111. package/dist/__tests__/unit/decorators.test.js +162 -0
  112. package/dist/__tests__/unit/decorators.test.js.map +1 -0
  113. package/dist/__tests__/unit/introspection-tools.test.d.ts +5 -0
  114. package/dist/__tests__/unit/introspection-tools.test.d.ts.map +1 -0
  115. package/dist/__tests__/unit/introspection-tools.test.js +191 -0
  116. package/dist/__tests__/unit/introspection-tools.test.js.map +1 -0
  117. package/dist/__tests__/unit/logger.test.d.ts +2 -0
  118. package/dist/__tests__/unit/logger.test.d.ts.map +1 -0
  119. package/dist/__tests__/unit/logger.test.js +241 -0
  120. package/dist/__tests__/unit/logger.test.js.map +1 -0
  121. package/dist/__tests__/unit/observable.test.d.ts +2 -0
  122. package/dist/__tests__/unit/observable.test.d.ts.map +1 -0
  123. package/dist/__tests__/unit/observable.test.js +251 -0
  124. package/dist/__tests__/unit/observable.test.js.map +1 -0
  125. package/dist/__tests__/unit/prompt.test.d.ts +2 -0
  126. package/dist/__tests__/unit/prompt.test.d.ts.map +1 -0
  127. package/dist/__tests__/unit/prompt.test.js +113 -0
  128. package/dist/__tests__/unit/prompt.test.js.map +1 -0
  129. package/dist/__tests__/unit/reflection.test.d.ts +5 -0
  130. package/dist/__tests__/unit/reflection.test.d.ts.map +1 -0
  131. package/dist/__tests__/unit/reflection.test.js +160 -0
  132. package/dist/__tests__/unit/reflection.test.js.map +1 -0
  133. package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts +2 -0
  134. package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts.map +1 -0
  135. package/dist/__tests__/unit/tree-debugger-incremental.test.js +136 -0
  136. package/dist/__tests__/unit/tree-debugger-incremental.test.js.map +1 -0
  137. package/dist/__tests__/unit/tree-debugger.test.d.ts +2 -0
  138. package/dist/__tests__/unit/tree-debugger.test.d.ts.map +1 -0
  139. package/dist/__tests__/unit/tree-debugger.test.js +69 -0
  140. package/dist/__tests__/unit/tree-debugger.test.js.map +1 -0
  141. package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts +2 -0
  142. package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts.map +1 -0
  143. package/dist/__tests__/unit/utils/workflow-error-utils.test.js +154 -0
  144. package/dist/__tests__/unit/utils/workflow-error-utils.test.js.map +1 -0
  145. package/dist/__tests__/unit/workflow-detachChild.test.d.ts +2 -0
  146. package/dist/__tests__/unit/workflow-detachChild.test.d.ts.map +1 -0
  147. package/dist/__tests__/unit/workflow-detachChild.test.js +76 -0
  148. package/dist/__tests__/unit/workflow-detachChild.test.js.map +1 -0
  149. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts +2 -0
  150. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts.map +1 -0
  151. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js +122 -0
  152. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js.map +1 -0
  153. package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts +2 -0
  154. package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts.map +1 -0
  155. package/dist/__tests__/unit/workflow-isDescendantOf.test.js +140 -0
  156. package/dist/__tests__/unit/workflow-isDescendantOf.test.js.map +1 -0
  157. package/dist/__tests__/unit/workflow.test.d.ts +2 -0
  158. package/dist/__tests__/unit/workflow.test.d.ts.map +1 -0
  159. package/dist/__tests__/unit/workflow.test.js +330 -0
  160. package/dist/__tests__/unit/workflow.test.js.map +1 -0
  161. package/dist/cache/cache-key.d.ts +66 -0
  162. package/dist/cache/cache-key.d.ts.map +1 -0
  163. package/dist/cache/cache-key.js +195 -0
  164. package/dist/cache/cache-key.js.map +1 -0
  165. package/dist/cache/cache.d.ts +104 -0
  166. package/dist/cache/cache.d.ts.map +1 -0
  167. package/dist/cache/cache.js +179 -0
  168. package/dist/cache/cache.js.map +1 -0
  169. package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
  170. package/dist/cache/index.d.ts.map +1 -0
  171. package/dist/cache/index.js +6 -0
  172. package/dist/cache/index.js.map +1 -0
  173. package/dist/core/agent.d.ts +112 -0
  174. package/dist/core/agent.d.ts.map +1 -0
  175. package/dist/core/agent.js +426 -0
  176. package/dist/core/agent.js.map +1 -0
  177. package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
  178. package/dist/core/context.d.ts.map +1 -0
  179. package/dist/core/context.js +80 -0
  180. package/dist/core/context.js.map +1 -0
  181. package/dist/core/event-tree.d.ts +72 -0
  182. package/dist/core/event-tree.d.ts.map +1 -0
  183. package/dist/core/event-tree.js +211 -0
  184. package/dist/core/event-tree.js.map +1 -0
  185. package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
  186. package/dist/core/factory.d.ts.map +1 -0
  187. package/dist/core/factory.js +110 -0
  188. package/dist/core/factory.js.map +1 -0
  189. package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
  190. package/dist/core/index.d.ts.map +1 -0
  191. package/dist/core/index.js +9 -0
  192. package/dist/core/index.js.map +1 -0
  193. package/dist/core/logger.d.ts +50 -0
  194. package/dist/core/logger.d.ts.map +1 -0
  195. package/dist/core/logger.js +91 -0
  196. package/dist/core/logger.js.map +1 -0
  197. package/dist/core/mcp-handler.d.ts +69 -0
  198. package/dist/core/mcp-handler.d.ts.map +1 -0
  199. package/dist/core/mcp-handler.js +143 -0
  200. package/dist/core/mcp-handler.js.map +1 -0
  201. package/dist/core/prompt.d.ts +80 -0
  202. package/dist/core/prompt.d.ts.map +1 -0
  203. package/dist/core/prompt.js +120 -0
  204. package/dist/core/prompt.js.map +1 -0
  205. package/dist/core/workflow-context.d.ts +57 -0
  206. package/dist/core/workflow-context.d.ts.map +1 -0
  207. package/dist/core/workflow-context.js +263 -0
  208. package/dist/core/workflow-context.js.map +1 -0
  209. package/dist/core/workflow.d.ts +241 -0
  210. package/dist/core/workflow.d.ts.map +1 -0
  211. package/dist/core/workflow.js +464 -0
  212. package/dist/core/workflow.js.map +1 -0
  213. package/dist/debugger/index.d.ts +2 -0
  214. package/dist/debugger/index.d.ts.map +1 -0
  215. package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
  216. package/dist/debugger/index.js.map +1 -0
  217. package/dist/debugger/tree-debugger.d.ts +71 -0
  218. package/dist/debugger/tree-debugger.d.ts.map +1 -0
  219. package/dist/debugger/tree-debugger.js +198 -0
  220. package/dist/debugger/tree-debugger.js.map +1 -0
  221. package/dist/decorators/index.d.ts +4 -0
  222. package/dist/decorators/index.d.ts.map +1 -0
  223. package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
  224. package/dist/decorators/index.js.map +1 -0
  225. package/dist/decorators/observed-state.d.ts +32 -0
  226. package/dist/decorators/observed-state.d.ts.map +1 -0
  227. package/dist/decorators/observed-state.js +79 -0
  228. package/dist/decorators/observed-state.js.map +1 -0
  229. package/dist/decorators/step.d.ts +15 -0
  230. package/dist/decorators/step.d.ts.map +1 -0
  231. package/dist/decorators/step.js +110 -0
  232. package/dist/decorators/step.js.map +1 -0
  233. package/dist/decorators/task.d.ts +50 -0
  234. package/dist/decorators/task.d.ts.map +1 -0
  235. package/dist/decorators/task.js +118 -0
  236. package/dist/decorators/task.js.map +1 -0
  237. package/dist/examples/index.d.ts +3 -0
  238. package/dist/examples/index.d.ts.map +1 -0
  239. package/{src/examples/index.ts → dist/examples/index.js} +1 -0
  240. package/dist/examples/index.js.map +1 -0
  241. package/dist/examples/tdd-orchestrator.d.ts +15 -0
  242. package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
  243. package/dist/examples/tdd-orchestrator.js +121 -0
  244. package/dist/examples/tdd-orchestrator.js.map +1 -0
  245. package/dist/examples/test-cycle-workflow.d.ts +14 -0
  246. package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
  247. package/dist/examples/test-cycle-workflow.js +116 -0
  248. package/dist/examples/test-cycle-workflow.js.map +1 -0
  249. package/dist/index.d.ts +27 -0
  250. package/dist/index.d.ts.map +1 -0
  251. package/dist/index.js +40 -0
  252. package/dist/index.js.map +1 -0
  253. package/dist/reflection/index.d.ts +5 -0
  254. package/dist/reflection/index.d.ts.map +1 -0
  255. package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
  256. package/dist/reflection/index.js.map +1 -0
  257. package/dist/reflection/reflection.d.ts +84 -0
  258. package/dist/reflection/reflection.d.ts.map +1 -0
  259. package/dist/reflection/reflection.js +329 -0
  260. package/dist/reflection/reflection.js.map +1 -0
  261. package/dist/tools/index.d.ts +6 -0
  262. package/dist/tools/index.d.ts.map +1 -0
  263. package/dist/tools/index.js +11 -0
  264. package/dist/tools/index.js.map +1 -0
  265. package/dist/tools/introspection.d.ts +165 -0
  266. package/dist/tools/introspection.d.ts.map +1 -0
  267. package/dist/tools/introspection.js +324 -0
  268. package/dist/tools/introspection.js.map +1 -0
  269. package/dist/types/agent.d.ts +66 -0
  270. package/dist/types/agent.d.ts.map +1 -0
  271. package/dist/types/agent.js +6 -0
  272. package/dist/types/agent.js.map +1 -0
  273. package/dist/types/decorators.d.ts +31 -0
  274. package/dist/types/decorators.d.ts.map +1 -0
  275. package/dist/types/decorators.js +2 -0
  276. package/dist/types/decorators.js.map +1 -0
  277. package/dist/types/error-strategy.d.ts +13 -0
  278. package/dist/types/error-strategy.d.ts.map +1 -0
  279. package/dist/types/error-strategy.js +2 -0
  280. package/dist/types/error-strategy.js.map +1 -0
  281. package/dist/types/error.d.ts +20 -0
  282. package/dist/types/error.d.ts.map +1 -0
  283. package/dist/types/error.js +2 -0
  284. package/dist/types/error.js.map +1 -0
  285. package/dist/types/events.d.ts +87 -0
  286. package/dist/types/events.d.ts.map +1 -0
  287. package/dist/types/events.js +2 -0
  288. package/dist/types/events.js.map +1 -0
  289. package/dist/types/index.d.ts +15 -0
  290. package/dist/types/index.d.ts.map +1 -0
  291. package/dist/types/index.js +2 -0
  292. package/dist/types/index.js.map +1 -0
  293. package/dist/types/logging.d.ts +24 -0
  294. package/dist/types/logging.d.ts.map +1 -0
  295. package/dist/types/logging.js +2 -0
  296. package/dist/types/logging.js.map +1 -0
  297. package/dist/types/observer.d.ts +18 -0
  298. package/dist/types/observer.d.ts.map +1 -0
  299. package/dist/types/observer.js +2 -0
  300. package/dist/types/observer.js.map +1 -0
  301. package/dist/types/prompt.d.ts +31 -0
  302. package/dist/types/prompt.d.ts.map +1 -0
  303. package/dist/types/prompt.js +6 -0
  304. package/dist/types/prompt.js.map +1 -0
  305. package/dist/types/reflection.d.ts +96 -0
  306. package/dist/types/reflection.d.ts.map +1 -0
  307. package/dist/types/reflection.js +24 -0
  308. package/dist/types/reflection.js.map +1 -0
  309. package/dist/types/sdk-primitives.d.ts +118 -0
  310. package/dist/types/sdk-primitives.d.ts.map +1 -0
  311. package/dist/types/sdk-primitives.js +6 -0
  312. package/dist/types/sdk-primitives.js.map +1 -0
  313. package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
  314. package/dist/types/snapshot.d.ts.map +1 -0
  315. package/dist/types/snapshot.js +2 -0
  316. package/dist/types/snapshot.js.map +1 -0
  317. package/dist/types/workflow-context.d.ts +139 -0
  318. package/dist/types/workflow-context.d.ts.map +1 -0
  319. package/dist/types/workflow-context.js +8 -0
  320. package/dist/types/workflow-context.js.map +1 -0
  321. package/dist/types/workflow.d.ts +30 -0
  322. package/dist/types/workflow.d.ts.map +1 -0
  323. package/dist/types/workflow.js +2 -0
  324. package/dist/types/workflow.js.map +1 -0
  325. package/dist/utils/id.d.ts +6 -0
  326. package/dist/utils/id.d.ts.map +1 -0
  327. package/dist/utils/id.js +12 -0
  328. package/dist/utils/id.js.map +1 -0
  329. package/{src/utils/index.ts → dist/utils/index.d.ts} +1 -0
  330. package/dist/utils/index.d.ts.map +1 -0
  331. package/dist/utils/index.js +4 -0
  332. package/dist/utils/index.js.map +1 -0
  333. package/dist/utils/observable.d.ts +54 -0
  334. package/dist/utils/observable.d.ts.map +1 -0
  335. package/dist/utils/observable.js +82 -0
  336. package/dist/utils/observable.js.map +1 -0
  337. package/dist/utils/workflow-error-utils.d.ts +22 -0
  338. package/dist/utils/workflow-error-utils.d.ts.map +1 -0
  339. package/dist/utils/workflow-error-utils.js +45 -0
  340. package/dist/utils/workflow-error-utils.js.map +1 -0
  341. package/package.json +5 -2
  342. package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
  343. package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
  344. package/.claude/commands/task-breakdown.md +0 -94
  345. package/.claude/settings.local.json +0 -9
  346. package/.claude/system_prompts/task-breakdown.md +0 -101
  347. package/PRD.md +0 -543
  348. package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
  349. package/PRPs/PRDs/002-agent-prompt.md +0 -390
  350. package/PRPs/PRDs/003-agent-prompt.md +0 -943
  351. package/PRPs/PRDs/004-agent-prompt.md +0 -1136
  352. package/PRPs/PRDs/tasks-001.json +0 -492
  353. package/PRPs/README.md +0 -83
  354. package/PRPs/templates/prp_base.md +0 -222
  355. package/docs/agent.md +0 -422
  356. package/docs/prompt.md +0 -419
  357. package/docs/workflow.md +0 -600
  358. package/examples/README.md +0 -258
  359. package/examples/examples/01-basic-workflow.ts +0 -100
  360. package/examples/examples/02-decorator-options.ts +0 -217
  361. package/examples/examples/03-parent-child.ts +0 -241
  362. package/examples/examples/04-observers-debugger.ts +0 -340
  363. package/examples/examples/05-error-handling.ts +0 -387
  364. package/examples/examples/06-concurrent-tasks.ts +0 -352
  365. package/examples/examples/07-agent-loops.ts +0 -432
  366. package/examples/examples/08-sdk-features.ts +0 -667
  367. package/examples/examples/09-reflection.ts +0 -573
  368. package/examples/examples/10-introspection.ts +0 -550
  369. package/examples/examples/11-reparenting-workflows.ts +0 -269
  370. package/examples/index.ts +0 -147
  371. package/examples/utils/helpers.ts +0 -57
  372. package/package-lock.json +0 -2398
  373. package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
  374. package/plan/001_d3bb02af4886/backlog.json +0 -867
  375. package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
  376. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
  377. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
  378. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
  379. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
  380. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
  381. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
  382. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
  383. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
  384. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
  385. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
  386. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
  387. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
  388. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
  389. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
  390. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
  391. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
  392. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
  393. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
  394. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
  395. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
  396. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
  397. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
  398. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
  399. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
  400. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
  401. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
  402. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
  403. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
  404. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
  405. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
  406. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
  407. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
  408. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
  409. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
  410. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
  411. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
  412. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
  413. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
  414. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
  415. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
  416. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
  417. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
  418. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
  419. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
  420. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
  421. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
  422. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
  423. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
  424. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
  425. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
  426. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
  427. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
  428. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
  429. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
  430. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
  431. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
  432. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
  433. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
  434. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
  435. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
  436. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
  437. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
  438. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
  439. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
  440. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
  441. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
  442. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
  443. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
  444. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
  445. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
  446. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
  447. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
  448. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
  449. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
  450. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
  451. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
  452. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
  453. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
  454. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
  455. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
  456. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
  457. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
  458. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
  459. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
  460. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
  461. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
  462. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
  463. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
  464. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
  465. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
  466. package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
  467. package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
  468. package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
  469. package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
  470. package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
  471. package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
  472. package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
  473. package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
  474. package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
  475. package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
  476. package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
  477. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
  478. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
  479. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
  480. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
  481. package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
  482. package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
  483. package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
  484. package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
  485. package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
  486. package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
  487. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
  488. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
  489. package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
  490. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
  491. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
  492. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
  493. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
  494. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
  495. package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
  496. package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
  497. package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
  498. package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
  499. package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
  500. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
  501. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
  502. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
  503. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
  504. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
  505. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
  506. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
  507. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
  508. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
  509. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
  510. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
  511. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
  512. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
  513. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
  514. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
  515. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
  516. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
  517. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
  518. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
  519. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
  520. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
  521. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
  522. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
  523. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
  524. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
  525. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
  526. package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
  527. package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
  528. package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
  529. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
  530. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
  531. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
  532. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
  533. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
  534. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
  535. package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
  536. package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
  537. package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
  538. package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
  539. package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
  540. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
  541. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
  542. package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
  543. package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
  544. package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
  545. package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
  546. package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
  547. package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
  548. package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
  549. package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
  550. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
  551. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
  552. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
  553. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
  554. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
  555. package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
  556. package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
  557. package/scripts/generate-llms-full.ts +0 -206
  558. package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
  559. package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
  560. package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
  561. package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
  562. package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
  563. package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
  564. package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
  565. package/src/__tests__/adversarial/edge-case.test.ts +0 -703
  566. package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
  567. package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
  568. package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
  569. package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
  570. package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
  571. package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
  572. package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
  573. package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
  574. package/src/__tests__/helpers/tree-verification.ts +0 -257
  575. package/src/__tests__/integration/agent-workflow.test.ts +0 -256
  576. package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
  577. package/src/__tests__/integration/observer-logging.test.ts +0 -643
  578. package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
  579. package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
  580. package/src/__tests__/unit/agent.test.ts +0 -169
  581. package/src/__tests__/unit/cache-key.test.ts +0 -182
  582. package/src/__tests__/unit/cache.test.ts +0 -172
  583. package/src/__tests__/unit/context.test.ts +0 -217
  584. package/src/__tests__/unit/decorators.test.ts +0 -100
  585. package/src/__tests__/unit/introspection-tools.test.ts +0 -277
  586. package/src/__tests__/unit/logger.test.ts +0 -293
  587. package/src/__tests__/unit/observable.test.ts +0 -321
  588. package/src/__tests__/unit/prompt.test.ts +0 -135
  589. package/src/__tests__/unit/reflection.test.ts +0 -210
  590. package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
  591. package/src/__tests__/unit/tree-debugger.test.ts +0 -85
  592. package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
  593. package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
  594. package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
  595. package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
  596. package/src/__tests__/unit/workflow.test.ts +0 -357
  597. package/src/cache/cache-key.ts +0 -244
  598. package/src/cache/cache.ts +0 -236
  599. package/src/core/agent.ts +0 -593
  600. package/src/core/event-tree.ts +0 -260
  601. package/src/core/logger.ts +0 -112
  602. package/src/core/mcp-handler.ts +0 -184
  603. package/src/core/prompt.ts +0 -150
  604. package/src/core/workflow-context.ts +0 -351
  605. package/src/core/workflow.ts +0 -540
  606. package/src/debugger/tree-debugger.ts +0 -255
  607. package/src/decorators/observed-state.ts +0 -95
  608. package/src/decorators/step.ts +0 -139
  609. package/src/decorators/task.ts +0 -159
  610. package/src/examples/tdd-orchestrator.ts +0 -65
  611. package/src/examples/test-cycle-workflow.ts +0 -64
  612. package/src/index.ts +0 -142
  613. package/src/reflection/reflection.ts +0 -407
  614. package/src/tools/index.ts +0 -36
  615. package/src/tools/introspection.ts +0 -464
  616. package/src/types/agent.ts +0 -90
  617. package/src/types/decorators.ts +0 -32
  618. package/src/types/error-strategy.ts +0 -13
  619. package/src/types/error.ts +0 -20
  620. package/src/types/events.ts +0 -75
  621. package/src/types/index.ts +0 -55
  622. package/src/types/logging.ts +0 -24
  623. package/src/types/observer.ts +0 -18
  624. package/src/types/prompt.ts +0 -40
  625. package/src/types/reflection.ts +0 -117
  626. package/src/types/sdk-primitives.ts +0 -128
  627. package/src/types/workflow-context.ts +0 -163
  628. package/src/types/workflow.ts +0 -37
  629. package/src/utils/id.ts +0 -11
  630. package/src/utils/observable.ts +0 -106
  631. package/src/utils/workflow-error-utils.ts +0 -56
  632. package/tsconfig.json +0 -22
  633. package/vitest.config.ts +0 -16
@@ -1,1574 +0,0 @@
1
- # Research: Testing Bidirectional Consistency Between Dual Tree Structures
2
-
3
- **Research Date:** 2026-01-12
4
- **Task:** P1M3T1S4 - Research external best practices for testing bidirectional consistency
5
- **Focus:** Workflow instance tree (parent/children) vs WorkflowNode tree (node.parent/node.children)
6
-
7
- ---
8
-
9
- ## Executive Summary
10
-
11
- This research document compiles best practices for testing bidirectional consistency between dual tree representations. While web search resources were limited due to service constraints, this document synthesizes patterns from:
12
-
13
- 1. **Existing codebase patterns** (workflow-reparenting.test.ts, tree-mirroring.test.ts, prd-compliance.test.ts)
14
- 2. **Established software engineering principles** for tree data structures
15
- 3. **Testing patterns** from well-known open-source projects
16
- 4. **Academic research** on invariant testing
17
-
18
- ---
19
-
20
- ## Table of Contents
21
-
22
- 1. [Core Testing Patterns](#core-testing-patterns)
23
- 2. [Bidirectional Consistency Validation](#bidirectional-consistency-validation)
24
- 3. [Tree Operation Testing](#tree-operation-testing)
25
- 4. [Invariant Testing Patterns](#invariant-testing-patterns)
26
- 5. [Adversarial Testing Approaches](#adversarial-testing-approaches)
27
- 6. [External Best Practices](#external-best-practices)
28
- 7. [Test Pattern Catalog](#test-pattern-catalog)
29
- 8. [Implementation Checklist](#implementation-checklist)
30
-
31
- ---
32
-
33
- ## 1. Core Testing Patterns
34
-
35
- ### 1.1 The AAA Pattern (Arrange-Act-Assert)
36
-
37
- **Pattern from:** `/home/dustin/projects/groundswell/src/__tests__/integration/workflow-reparenting.test.ts`
38
-
39
- ```typescript
40
- describe('Bidirectional Consistency', () => {
41
- it('should maintain consistency after reparenting', () => {
42
- // ============================================================
43
- // PHASE 1: ARRANGE - Set up test data
44
- // ============================================================
45
- const parent1 = new SimpleWorkflow('Parent1');
46
- const parent2 = new SimpleWorkflow('Parent2');
47
- const child = new SimpleWorkflow('Child', parent1);
48
-
49
- // ASSERT: Verify initial state
50
- expect(child.parent).toBe(parent1);
51
- expect(parent1.children).toContain(child);
52
- expect(parent2.children).not.toContain(child);
53
-
54
- // ============================================================
55
- // PHASE 2: ACT - Execute the behavior
56
- // ============================================================
57
- parent1.detachChild(child);
58
- parent2.attachChild(child);
59
-
60
- // ============================================================
61
- // PHASE 3: ASSERT - Verify the result
62
- // ============================================================
63
- // Workflow tree state
64
- expect(child.parent).toBe(parent2);
65
- expect(parent2.children).toContain(child);
66
- expect(parent1.children).not.toContain(child);
67
-
68
- // Node tree state (dual tree mirror)
69
- expect(child.node.parent).toBe(parent2.node);
70
- expect(parent2.node.children).toContain(child.node);
71
- expect(parent1.node.children).not.toContain(child.node);
72
- });
73
- });
74
- ```
75
-
76
- **Key Principles:**
77
- - Clear phase separation with comments
78
- - Multiple assertions per phase
79
- - Cross-tree verification (workflow tree + node tree)
80
- - State verification before and after operations
81
-
82
- ### 1.2 Test Naming Conventions
83
-
84
- **Pattern from:** `/home/dustin/projects/groundswell/src/__tests__/adversarial/prd-compliance.test.ts`
85
-
86
- ```typescript
87
- // Good: Descriptive, action-oriented
88
- describe('PRD: Perfect 1:1 Tree Mirror Requirement', () => {
89
- it('should maintain perfect tree structure in logs and events', async () => {
90
- // Test implementation
91
- });
92
- });
93
-
94
- // Good: Specific operation tested
95
- describe('Tree Integrity Tests', () => {
96
- it('should prevent attaching child with existing parent', () => {
97
- // Test implementation
98
- });
99
-
100
- it('should allow attaching child with null parent', () => {
101
- // Test implementation
102
- });
103
- });
104
- ```
105
-
106
- **Naming Template:**
107
- - `should [expected behavior]` - for positive cases
108
- - `should prevent [invalid behavior]` - for negative cases
109
- - `should maintain [invariant] after [operation]` - for consistency tests
110
-
111
- ---
112
-
113
- ## 2. Bidirectional Consistency Validation
114
-
115
- ### 2.1 The 1:1 Tree Mirror Invariant
116
-
117
- **Critical Pattern from:** `/home/dustin/projects/groundswell/src/__tests__/integration/workflow-reparenting.test.ts:280-302`
118
-
119
- This is the **core invariant** that must always be maintained:
120
-
121
- ```typescript
122
- describe('CRITICAL VALIDATION: 1:1 Tree Mirror Invariant', () => {
123
- it('should verify perfect synchronization between trees', () => {
124
- const parent = new SimpleWorkflow('Parent');
125
- const child = new SimpleWorkflow('Child', parent);
126
-
127
- // ============================================================
128
- // INVARIANT CHECK: For every relationship in workflow tree,
129
- // there must be an equivalent relationship in node tree
130
- // ============================================================
131
-
132
- // Workflow tree state:
133
- // - child.parent points to parent
134
- expect(child.parent).toBe(parent);
135
-
136
- // - parent.children contains child
137
- expect(parent.children).toEqual([child]);
138
-
139
- // Node tree state (MUST mirror workflow tree exactly):
140
- // - child.node.parent points to parent.node
141
- expect(child.node.parent).toBe(parent.node);
142
-
143
- // - parent.node.children contains child.node
144
- expect(parent.node.children).toEqual([child.node]);
145
-
146
- // ============================================================
147
- // CROSS-VERIFICATION: Debugger lookup matches direct access
148
- // ============================================================
149
- const debugger = new WorkflowTreeDebugger(parent);
150
-
151
- // Debugger should see same structure
152
- expect(debugger.getNode(child.id)).toBe(child.node);
153
- expect(debugger.getNode(parent.id)).toBe(parent.node);
154
- });
155
- });
156
- ```
157
-
158
- ### 2.2 Bidirectional Reference Verification Pattern
159
-
160
- **Purpose:** Ensure parent→child and child→parent links are mutually consistent
161
-
162
- ```typescript
163
- describe('Bidirectional Reference Verification', () => {
164
- /**
165
- * Core invariant: If A is B's parent, then:
166
- * 1. B must be in A's children list
167
- * 2. A must be B's parent reference
168
- * 3. Both must be true in BOTH trees (workflow + node)
169
- */
170
- function verifyBidirectionalLink(
171
- parent: Workflow,
172
- child: Workflow
173
- ): void {
174
- // Workflow tree checks
175
- expect(child.parent).toBe(parent);
176
- expect(parent.children).toContain(child);
177
-
178
- // Node tree checks (must mirror workflow tree)
179
- expect(child.node.parent).toBe(parent.node);
180
- expect(parent.node.children).toContain(child.node);
181
-
182
- // Verify no orphaned references
183
- expect(child.node.parent).toBeDefined();
184
- expect(parent.node.children).toHaveLengthGreaterThan(0);
185
- }
186
-
187
- it('should maintain bidirectional consistency after attach', () => {
188
- const parent = new SimpleWorkflow('Parent');
189
- const child = new SimpleWorkflow('Child'); // No parent
190
-
191
- parent.attachChild(child);
192
-
193
- verifyBidirectionalLink(parent, child);
194
- });
195
-
196
- it('should maintain bidirectional consistency after detach', () => {
197
- const parent = new SimpleWorkflow('Parent');
198
- const child = new SimpleWorkflow('Child', parent);
199
-
200
- parent.detachChild(child);
201
-
202
- // Verify complete detachment
203
- expect(child.parent).toBeNull();
204
- expect(parent.children).not.toContain(child);
205
-
206
- expect(child.node.parent).toBeNull();
207
- expect(parent.node.children).not.toContain(child.node);
208
- });
209
- });
210
- ```
211
-
212
- ### 2.3 Tree-Wide Consistency Validation
213
-
214
- **Purpose:** Verify consistency across entire tree hierarchy
215
-
216
- ```typescript
217
- describe('Tree-Wide Consistency', () => {
218
- /**
219
- * Validates entire tree structure for bidirectional consistency
220
- * Returns array of inconsistencies found
221
- */
222
- function validateTreeConsistency(root: Workflow): string[] {
223
- const inconsistencies: string[] = [];
224
- const visited = new Set<Workflow>();
225
-
226
- function traverse(node: Workflow, depth: number = 0): void {
227
- if (visited.has(node)) {
228
- inconsistencies.push(`Circular reference at ${node.node.name}`);
229
- return;
230
- }
231
- visited.add(node);
232
-
233
- // Check parent→child consistency
234
- if (node.parent) {
235
- if (!node.parent.children.includes(node)) {
236
- inconsistencies.push(
237
- `Orphaned child: ${node.node.name} not in parent's children`
238
- );
239
- }
240
- }
241
-
242
- // Check child→parent consistency
243
- node.children.forEach(child => {
244
- if (child.parent !== node) {
245
- inconsistencies.push(
246
- `Mismatched parent: ${child.node.name}.parent !== ${node.node.name}`
247
- );
248
- }
249
-
250
- // Check node tree mirrors workflow tree
251
- if (child.node.parent !== node.node) {
252
- inconsistencies.push(
253
- `Node tree mismatch: ${child.node.name}.node.parent !== ${node.node.name}.node`
254
- );
255
- }
256
-
257
- if (!node.node.children.includes(child.node)) {
258
- inconsistencies.push(
259
- `Node tree orphan: ${child.node.name}.node not in parent's node.children`
260
- );
261
- }
262
-
263
- traverse(child, depth + 1);
264
- });
265
- }
266
-
267
- traverse(root);
268
- return inconsistencies;
269
- }
270
-
271
- it('should maintain consistency across entire tree', () => {
272
- const root = new SimpleWorkflow('Root');
273
- const child1 = new SimpleWorkflow('Child1', root);
274
- const child2 = new SimpleWorkflow('Child2', root);
275
- const grandchild = new SimpleWorkflow('Grandchild', child1);
276
-
277
- const inconsistencies = validateTreeConsistency(root);
278
-
279
- expect(inconsistencies).toEqual([]);
280
- expect(inconsistencies.length).toBe(0);
281
- });
282
- });
283
- ```
284
-
285
- ---
286
-
287
- ## 3. Tree Operation Testing
288
-
289
- ### 3.1 Attach Operation Testing
290
-
291
- **Pattern from:** `/home/dustin/projects/groundswell/plan/docs/bugfix-architecture/implementation_patterns.md:274-313`
292
-
293
- ```typescript
294
- describe('attachChild() Bidirectional Consistency', () => {
295
- describe('Positive Cases', () => {
296
- it('should synchronize both trees on successful attach', () => {
297
- const parent = new SimpleWorkflow('Parent');
298
- const child = new SimpleWorkflow('Child'); // null parent
299
-
300
- parent.attachChild(child);
301
-
302
- // Workflow tree updated
303
- expect(child.parent).toBe(parent);
304
- expect(parent.children).toContain(child);
305
-
306
- // Node tree updated (must match)
307
- expect(child.node.parent).toBe(parent.node);
308
- expect(parent.node.children).toContain(child.node);
309
-
310
- // Verify event emission
311
- const events = parent.node.events.filter(e => e.type === 'childAttached');
312
- expect(events.length).toBeGreaterThan(0);
313
- });
314
-
315
- it('should handle idempotent attach to same parent', () => {
316
- const parent = new SimpleWorkflow('Parent');
317
- const child = new SimpleWorkflow('Child', parent); // Already attached
318
-
319
- // Should not throw (child.parent === this)
320
- parent.attachChild(child);
321
-
322
- // Structure should remain valid
323
- expect(parent.children).toEqual([child]);
324
- expect(parent.node.children).toEqual([child.node]);
325
- });
326
- });
327
-
328
- describe('Negative Cases', () => {
329
- it('should prevent attaching child with different parent', () => {
330
- const parent1 = new SimpleWorkflow('Parent1');
331
- const parent2 = new SimpleWorkflow('Parent2');
332
- const child = new SimpleWorkflow('Child', parent1);
333
-
334
- // Should throw - child already has parent
335
- expect(() => parent2.attachChild(child)).toThrow(/already has a parent/);
336
-
337
- // Trees should remain unchanged
338
- expect(child.parent).toBe(parent1);
339
- expect(parent1.children).toContain(child);
340
- expect(parent2.children).not.toContain(child);
341
-
342
- expect(child.node.parent).toBe(parent1.node);
343
- expect(parent1.node.children).toContain(child.node);
344
- expect(parent2.node.children).not.toContain(child.node);
345
- });
346
-
347
- it('should prevent circular references', () => {
348
- const root = new SimpleWorkflow('Root');
349
- const child = new SimpleWorkflow('Child', root);
350
-
351
- // Try to create cycle
352
- expect(() => {
353
- child.attachChild(root as any);
354
- }).toThrow(/circular|cycle/i);
355
-
356
- // Verify no corruption occurred
357
- expect(root.parent).toBeNull();
358
- expect(child.parent).toBe(root);
359
- });
360
-
361
- it('should prevent duplicate attachment', () => {
362
- const parent = new SimpleWorkflow('Parent');
363
- const child = new SimpleWorkflow('Child', parent);
364
-
365
- // Already attached - should throw
366
- expect(() => parent.attachChild(child)).toThrow(/already attached/);
367
-
368
- // Verify only one reference exists
369
- const childCount = parent.children.filter(c => c === child).length;
370
- expect(childCount).toBe(1);
371
-
372
- const nodeChildCount = parent.node.children.filter(c => c === child.node).length;
373
- expect(nodeChildCount).toBe(1);
374
- });
375
- });
376
- });
377
- ```
378
-
379
- ### 3.2 Detach Operation Testing
380
-
381
- ```typescript
382
- describe('detachChild() Bidirectional Consistency', () => {
383
- it('should remove from both trees completely', () => {
384
- const parent = new SimpleWorkflow('Parent');
385
- const child = new SimpleWorkflow('Child', parent);
386
-
387
- parent.detachChild(child);
388
-
389
- // Workflow tree: both directions cleared
390
- expect(child.parent).toBeNull();
391
- expect(parent.children).not.toContain(child);
392
-
393
- // Node tree: both directions cleared
394
- expect(child.node.parent).toBeNull();
395
- expect(parent.node.children).not.toContain(child.node);
396
-
397
- // Verify event emission
398
- const events = parent.node.events.filter(e => e.type === 'childDetached');
399
- expect(events.length).toBeGreaterThan(0);
400
- });
401
-
402
- it('should throw when detaching non-existent child', () => {
403
- const parent = new SimpleWorkflow('Parent');
404
- const child = new SimpleWorkflow('Child');
405
-
406
- expect(() => parent.detachChild(child)).toThrow(/not attached/);
407
- });
408
-
409
- it('should handle multiple children correctly', () => {
410
- const parent = new SimpleWorkflow('Parent');
411
- const child1 = new SimpleWorkflow('Child1', parent);
412
- const child2 = new SimpleWorkflow('Child2', parent);
413
- const child3 = new SimpleWorkflow('Child3', parent);
414
-
415
- // Detach middle child
416
- parent.detachChild(child2);
417
-
418
- // Verify correct structure
419
- expect(parent.children).toEqual([child1, child3]);
420
- expect(parent.node.children).toEqual([child1.node, child3.node]);
421
-
422
- // Verify detached child is orphaned
423
- expect(child2.parent).toBeNull();
424
- expect(child2.node.parent).toBeNull();
425
-
426
- // Verify other children unaffected
427
- expect(child1.parent).toBe(parent);
428
- expect(child3.parent).toBe(parent);
429
- });
430
- });
431
- ```
432
-
433
- ### 3.3 Reparenting Operation Testing
434
-
435
- **Pattern from:** `/home/dustin/projects/groundswell/src/__tests__/integration/workflow-reparenting.test.ts:77-127`
436
-
437
- ```typescript
438
- describe('Reparenting Bidirectional Consistency', () => {
439
- it('should maintain consistency during reparenting workflow', () => {
440
- const parent1 = new SimpleWorkflow('Parent1');
441
- const parent2 = new SimpleWorkflow('Parent2');
442
- const child = new SimpleWorkflow('Child', parent1);
443
-
444
- // Verify initial state
445
- expect(child.parent).toBe(parent1);
446
- expect(parent1.children).toContain(child);
447
- expect(child.node.parent).toBe(parent1.node);
448
- expect(parent1.node.children).toContain(child.node);
449
-
450
- // Execute reparenting
451
- parent1.detachChild(child);
452
- parent2.attachChild(child);
453
-
454
- // Verify workflow tree updated
455
- expect(child.parent).toBe(parent2);
456
- expect(parent2.children).toContain(child);
457
- expect(parent1.children).not.toContain(child);
458
-
459
- // Verify node tree updated (MUST match)
460
- expect(child.node.parent).toBe(parent2.node);
461
- expect(parent2.node.children).toContain(child.node);
462
- expect(parent1.node.children).not.toContain(child.node);
463
-
464
- // Verify no dangling references
465
- expect(child.node.parent).toBeDefined();
466
- expect(parent2.node.children).toContain(child.node);
467
- expect(parent1.node.children).not.toContain(child.node);
468
- });
469
-
470
- it('should handle multiple reparenting cycles', () => {
471
- const parentA = new SimpleWorkflow('ParentA');
472
- const parentB = new SimpleWorkflow('ParentB');
473
- const parentC = new SimpleWorkflow('ParentC');
474
- const child = new SimpleWorkflow('Child', parentA);
475
-
476
- // Cycle 1: A -> B
477
- parentA.detachChild(child);
478
- parentB.attachChild(child);
479
- expect(child.parent).toBe(parentB);
480
- expect(child.node.parent).toBe(parentB.node);
481
-
482
- // Cycle 2: B -> C
483
- parentB.detachChild(child);
484
- parentC.attachChild(child);
485
- expect(child.parent).toBe(parentC);
486
- expect(child.node.parent).toBe(parentC.node);
487
-
488
- // Cycle 3: C -> A (back to original)
489
- parentC.detachChild(child);
490
- parentA.attachChild(child);
491
- expect(child.parent).toBe(parentA);
492
- expect(child.node.parent).toBe(parentA.node);
493
- });
494
- });
495
- ```
496
-
497
- ---
498
-
499
- ## 4. Invariant Testing Patterns
500
-
501
- ### 4.1 Structural Invariants
502
-
503
- **Core invariants that must always hold:**
504
-
505
- ```typescript
506
- describe('Tree Structural Invariants', () => {
507
- /**
508
- * Invariant 1: Acyclicity
509
- * No cycles exist (every node has exactly one parent except root)
510
- */
511
- it('should maintain acyclicity invariant', () => {
512
- const root = new SimpleWorkflow('Root');
513
- const child = new SimpleWorkflow('Child', root);
514
-
515
- // Try to create cycle
516
- expect(() => root.attachChild(child as any)).toThrow();
517
-
518
- // Verify: following parent links eventually reaches null
519
- let current: Workflow | null = child;
520
- const visited = new Set<Workflow>();
521
-
522
- while (current !== null) {
523
- expect(visited.has(current)).toBe(false); // No cycles
524
- visited.add(current);
525
- current = current.parent;
526
- }
527
- });
528
-
529
- /**
530
- * Invariant 2: Single Root
531
- * Exactly one root node exists (parent == null)
532
- */
533
- it('should maintain single root invariant', () => {
534
- const root = new SimpleWorkflow('Root');
535
- const child1 = new SimpleWorkflow('Child1', root);
536
- const child2 = new SimpleWorkflow('Child2', root);
537
-
538
- // Count roots (nodes with null parent)
539
- const roots = collectAllNodes(root).filter(n => n.parent === null);
540
-
541
- expect(roots.length).toBe(1);
542
- expect(roots[0]).toBe(root);
543
- });
544
-
545
- /**
546
- * Invariant 3: Connectedness
547
- * All nodes are reachable from the root
548
- */
549
- it('should maintain connectedness invariant', () => {
550
- const root = new SimpleWorkflow('Root');
551
- const child1 = new SimpleWorkflow('Child1', root);
552
- const child2 = new SimpleWorkflow('Child2', root);
553
- const grandchild = new SimpleWorkflow('Grandchild', child1);
554
-
555
- const allNodes = collectAllNodes(root);
556
- const reachableFromRoot = new Set<Workflow>();
557
-
558
- function traverse(node: Workflow): void {
559
- reachableFromRoot.add(node);
560
- node.children.forEach(traverse);
561
- }
562
-
563
- traverse(root);
564
-
565
- // All nodes should be reachable
566
- allNodes.forEach(node => {
567
- expect(reachableFromRoot.has(node)).toBe(true);
568
- });
569
- });
570
-
571
- /**
572
- * Invariant 4: Parent-Child Consistency
573
- * If A is B's parent, then B must be in A's children list
574
- */
575
- it('should maintain parent-child consistency invariant', () => {
576
- const root = new SimpleWorkflow('Root');
577
- const child = new SimpleWorkflow('Child', root);
578
-
579
- // Forward direction: parent knows about child
580
- expect(root.children).toContain(child);
581
-
582
- // Reverse direction: child knows about parent
583
- expect(child.parent).toBe(root);
584
-
585
- // Both must be true (bidirectional)
586
- const forward = root.children.includes(child);
587
- const reverse = child.parent === root;
588
-
589
- expect(forward && reverse).toBe(true);
590
- });
591
-
592
- /**
593
- * Invariant 5: Tree Mirror Consistency
594
- * Workflow tree perfectly mirrors node tree
595
- */
596
- it('should maintain tree mirror invariant', () => {
597
- const root = new SimpleWorkflow('Root');
598
- const child = new SimpleWorkflow('Child', root);
599
-
600
- // For every workflow tree relationship, node tree must match
601
- function verifyMirror(workflowNode: Workflow): void {
602
- const node = workflowNode.node;
603
-
604
- // Verify parent relationship
605
- if (workflowNode.parent) {
606
- expect(node.parent).toBe(workflowNode.parent.node);
607
- } else {
608
- expect(node.parent).toBeNull();
609
- }
610
-
611
- // Verify children relationship
612
- expect(node.children.length).toBe(workflowNode.children.length);
613
-
614
- workflowNode.children.forEach((childWorkflow, index) => {
615
- expect(node.children[index]).toBe(childWorkflow.node);
616
- verifyMirror(childWorkflow);
617
- });
618
- }
619
-
620
- verifyMirror(root);
621
- });
622
- });
623
- ```
624
-
625
- ### 4.2 Counting Invariants
626
-
627
- ```typescript
628
- describe('Counting Invariants', () => {
629
- /**
630
- * Invariant: Edge Count
631
- * Exactly (n-1) edges for n nodes in a tree
632
- */
633
- it('should maintain correct edge count', () => {
634
- const root = new SimpleWorkflow('Root');
635
- const child1 = new SimpleWorkflow('Child1', root);
636
- const child2 = new SimpleWorkflow('Child2', root);
637
- const grandchild = new SimpleWorkflow('Grandchild', child1);
638
-
639
- const allNodes = collectAllNodes(root);
640
-
641
- // Count edges (each child has exactly one parent edge)
642
- let edgeCount = 0;
643
- allNodes.forEach(node => {
644
- if (node.parent !== null) {
645
- edgeCount++;
646
- }
647
- });
648
-
649
- // Tree with n nodes has exactly n-1 edges
650
- expect(edgeCount).toBe(allNodes.length - 1);
651
- });
652
-
653
- /**
654
- * Invariant: Node Count Consistency
655
- * Total nodes = sum of all subtree sizes + 1
656
- */
657
- it('should maintain consistent node counts', () => {
658
- const root = new SimpleWorkflow('Root');
659
- const child1 = new SimpleWorkflow('Child1', root);
660
- const child2 = new SimpleWorkflow('Child2', root);
661
-
662
- function countDescendants(node: Workflow): number {
663
- let count = 0;
664
- node.children.forEach(child => {
665
- count += 1 + countDescendants(child);
666
- });
667
- return count;
668
- }
669
-
670
- const totalNodes = collectAllNodes(root).length;
671
- const descendantCount = countDescendants(root);
672
-
673
- expect(totalNodes).toBe(descendantCount + 1); // +1 for root itself
674
- });
675
- });
676
- ```
677
-
678
- ### 4.3 Depth Invariants
679
-
680
- ```typescript
681
- describe('Depth Invariants', () => {
682
- /**
683
- * Invariant: Depth Consistency
684
- * Node depth = parent depth + 1
685
- */
686
- it('should maintain consistent depths', () => {
687
- const root = new SimpleWorkflow('Root');
688
- const child1 = new SimpleWorkflow('Child1', root);
689
- const child2 = new SimpleWorkflow('Child2', root);
690
- const grandchild = new SimpleWorkflow('Grandchild', child1);
691
-
692
- function getDepth(node: Workflow): number {
693
- let depth = 0;
694
- let current: Workflow | null = node;
695
-
696
- while (current !== null) {
697
- depth++;
698
- current = current.parent;
699
- }
700
-
701
- return depth - 1; // Subtract 1 because we counted the node itself
702
- }
703
-
704
- expect(getDepth(root)).toBe(0);
705
- expect(getDepth(child1)).toBe(1);
706
- expect(getDepth(child2)).toBe(1);
707
- expect(getDepth(grandchild)).toBe(2);
708
-
709
- // Verify: child depth = parent depth + 1
710
- expect(getDepth(child1)).toBe(getDepth(root) + 1);
711
- expect(getDepth(grandchild)).toBe(getDepth(child1) + 1);
712
- });
713
- });
714
- ```
715
-
716
- ---
717
-
718
- ## 5. Adversarial Testing Approaches
719
-
720
- ### 5.1 Manual Mutation Tests
721
-
722
- **Pattern from:** `/home/dustin/projects/groundswell/src/__tests__/adversarial/edge-case.test.ts:490-505`
723
-
724
- ```typescript
725
- describe('Adversarial: Manual Parent Mutation', () => {
726
- it('should detect inconsistency from manual parent mutation', () => {
727
- const parent1 = new SimpleWorkflow('Parent1');
728
- const parent2 = new SimpleWorkflow('Parent2');
729
- const child = new SimpleWorkflow('Child', parent1);
730
-
731
- // Manually mutate parent (bypassing attachChild)
732
- // This simulates a bug or malicious action
733
- (child as any).parent = parent2;
734
-
735
- // Now trees are inconsistent:
736
- // - workflow tree: child.parent === parent2
737
- // - parent1.children: still contains child
738
- // - parent2.children: does NOT contain child
739
-
740
- // Detect inconsistency
741
- const inconsistencies = validateTreeConsistency(parent1);
742
-
743
- expect(inconsistencies.length).toBeGreaterThan(0);
744
- expect(inconsistencies.some(i => i.includes('Mismatched parent'))).toBe(true);
745
- });
746
-
747
- it('should prevent manual parent mutation via TypeScript', () => {
748
- // TypeScript should prevent this at compile time
749
- // But if someone uses 'as any', we need runtime checks
750
-
751
- const parent = new SimpleWorkflow('Parent');
752
- const child = new SimpleWorkflow('Child', parent);
753
-
754
- // This should throw in attachChild due to validation
755
- const parent2 = new SimpleWorkflow('Parent2');
756
-
757
- expect(() => {
758
- (child as any).parent = parent2; // Manual mutation
759
- parent2.attachChild(child); // Should detect and throw
760
- }).toThrow();
761
- });
762
- });
763
- ```
764
-
765
- ### 5.2 Circular Reference Detection
766
-
767
- **Pattern from:** `/home/dustin/projects/groundswell/plan/docs/research/P1M2T1S4/existing_test_pattern.md:10-24`
768
-
769
- ```typescript
770
- describe('Adversarial: Circular References', () => {
771
- it('should detect simple circular reference', () => {
772
- const parent = new SimpleWorkflow('Parent');
773
- const child = new SimpleWorkflow('Child', parent);
774
-
775
- // Create circular reference manually
776
- parent.parent = child;
777
-
778
- // getRoot() should detect and throw
779
- expect(() => (parent as any).getRoot()).toThrow(
780
- 'Circular parent-child relationship detected'
781
- );
782
- });
783
-
784
- it('should detect complex circular references', () => {
785
- const root = new SimpleWorkflow('Root');
786
- const child1 = new SimpleWorkflow('Child1', root);
787
- const child2 = new SimpleWorkflow('Child2', child1);
788
- const child3 = new SimpleWorkflow('Child3', child2);
789
-
790
- // Try to create cycle: child3 -> root
791
- expect(() => {
792
- child3.attachChild(root as any);
793
- }).toThrow(/circular|cycle/i);
794
- });
795
-
796
- it('should prevent cycles in node tree', () => {
797
- const root = new SimpleWorkflow('Root');
798
- const child = new SimpleWorkflow('Child', root);
799
-
800
- // Try to manually mutate node tree
801
- expect(() => {
802
- root.node.parent = child.node;
803
- }).not.toThrow(); // TypeScript allows with 'as any'
804
-
805
- // But validation should detect it
806
- const debugger = new WorkflowTreeDebugger(root);
807
-
808
- // Try to traverse - should detect cycle
809
- expect(() => {
810
- debugger.toTreeString();
811
- }).toThrow(); // Or handle gracefully
812
- });
813
- });
814
- ```
815
-
816
- ### 5.3 Stress Testing
817
-
818
- **Pattern from:** `/home/dustin/projects/groundswell/src/__tests__/adversarial/edge-case.test.ts:262-295`
819
-
820
- ```typescript
821
- describe('Adversarial: Stress Tests', () => {
822
- it('should handle very deep hierarchies', () => {
823
- let lastWorkflow: Workflow | null = null;
824
-
825
- // Create 100 levels deep
826
- for (let i = 0; i < 100; i++) {
827
- const workflow = new SimpleWorkflow(`Level-${i}`);
828
- if (lastWorkflow) {
829
- lastWorkflow.attachChild(workflow);
830
- }
831
- lastWorkflow = workflow;
832
- }
833
-
834
- // Verify consistency at each level
835
- let current = lastWorkflow;
836
- let depth = 0;
837
-
838
- while (current && current.parent) {
839
- // Verify bidirectional link at each level
840
- expect(current.parent.children).toContain(current);
841
- expect(current.node.parent).toBe(current.parent.node);
842
-
843
- depth++;
844
- current = current.parent;
845
- }
846
-
847
- expect(depth).toBe(99);
848
- });
849
-
850
- it('should handle wide hierarchies (many siblings)', () => {
851
- const parent = new SimpleWorkflow('Parent');
852
- const children: Workflow[] = [];
853
-
854
- // Create 100 children
855
- for (let i = 0; i < 100; i++) {
856
- const child = new SimpleWorkflow(`Child-${i}`, parent);
857
- children.push(child);
858
- }
859
-
860
- // Verify all children are correctly attached
861
- expect(parent.children.length).toBe(100);
862
- expect(parent.node.children.length).toBe(100);
863
-
864
- // Verify each child has correct parent
865
- children.forEach(child => {
866
- expect(child.parent).toBe(parent);
867
- expect(child.node.parent).toBe(parent.node);
868
- expect(parent.children).toContain(child);
869
- expect(parent.node.children).toContain(child.node);
870
- });
871
- });
872
-
873
- it('should handle rapid attach/detach cycles', () => {
874
- const parent1 = new SimpleWorkflow('Parent1');
875
- const parent2 = new SimpleWorkflow('Parent2');
876
- const child = new SimpleWorkflow('Child', parent1);
877
-
878
- // Rapid reparenting
879
- for (let i = 0; i < 100; i++) {
880
- if (i % 2 === 0) {
881
- parent1.detachChild(child);
882
- parent2.attachChild(child);
883
- } else {
884
- parent2.detachChild(child);
885
- parent1.attachChild(child);
886
- }
887
-
888
- // Verify consistency after each cycle
889
- const expectedParent = i % 2 === 0 ? parent2 : parent1;
890
- expect(child.parent).toBe(expectedParent);
891
- expect(child.node.parent).toBe(expectedParent.node);
892
- }
893
- });
894
- });
895
- ```
896
-
897
- ---
898
-
899
- ## 6. External Best Practices
900
-
901
- ### 6.1 DOM Tree API Patterns
902
-
903
- **Reference:** [DOM Specification - Tree Concepts](https://dom.spec.whatwg.org/#concept-tree-parent)
904
-
905
- The DOM specification provides excellent patterns for tree structure validation:
906
-
907
- ```typescript
908
- /**
909
- * Pattern: DOM-style Tree Validation
910
- * Source: https://dom.spec.whatwg.org/#concept-tree-parent
911
- *
912
- * Key principles:
913
- * 1. Every node (except root) has exactly one parent
914
- * 2. Parent-child relationships are bidirectional
915
- * 3. Tree structure is maintained through mutation operations
916
- */
917
- describe('DOM-style Tree Validation', () => {
918
- it('should follow DOM tree mutation principles', () => {
919
- const parent = new SimpleWorkflow('Parent');
920
- const child = new SimpleWorkflow('Child', parent);
921
-
922
- // DOM principle:appendChild() updates both parent and child
923
- // Similar to our attachChild()
924
- const newChild = new SimpleWorkflow('NewChild');
925
- parent.attachChild(newChild);
926
-
927
- // Verify: parent knows about child (DOM: children list)
928
- expect(parent.children.includes(newChild)).toBe(true);
929
-
930
- // Verify: child knows about parent (DOM: parentNode property)
931
- expect(newChild.parent).toBe(parent);
932
-
933
- // Verify: node tree mirrors (DOM: ownerDocument relationship)
934
- expect(newChild.node.parent).toBe(parent.node);
935
- });
936
-
937
- it('should follow DOM removal principles', () => {
938
- const parent = new SimpleWorkflow('Parent');
939
- const child = new SimpleWorkflow('Child', parent);
940
-
941
- // DOM principle: removeChild() updates both parent and child
942
- parent.detachChild(child);
943
-
944
- // Verify: parent no longer references child
945
- expect(parent.children.includes(child)).toBe(false);
946
-
947
- // Verify: child parent is null (DOM: orphaned node)
948
- expect(child.parent).toBeNull();
949
-
950
- // Verify: node tree mirrors
951
- expect(child.node.parent).toBeNull();
952
- });
953
- });
954
- ```
955
-
956
- ### 6.2 React Fiber Tree Patterns
957
-
958
- **Reference:** [React Fiber Architecture](https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiber.js)
959
-
960
- React's Fiber tree maintains dual tree representation (current tree and work-in-progress tree):
961
-
962
- ```typescript
963
- /**
964
- * Pattern: React-style Dual Tree Consistency
965
- * Source: React Fiber Architecture
966
- *
967
- * Key principles:
968
- * 1. Dual tree representations must stay in sync
969
- * 2. Changes are batched and applied atomically
970
- * 3. Consistency is verified after each operation
971
- */
972
- describe('React Fiber-style Dual Tree', () => {
973
- it('should maintain dual tree consistency like React Fiber', () => {
974
- const parent = new SimpleWorkflow('Parent');
975
- const child = new SimpleWorkflow('Child', parent);
976
-
977
- // React Fiber: current tree and work-in-progress tree
978
- // Our equivalent: workflow tree and node tree
979
-
980
- // Verify both trees represent same structure
981
- function verifyFiberConsistency(workflow: Workflow): void {
982
- const fiberNode = workflow.node;
983
-
984
- // Check: parent pointers match
985
- if (workflow.parent) {
986
- expect(fiberNode.parent).toBe(workflow.parent.node);
987
- }
988
-
989
- // Check: child arrays match
990
- expect(fiberNode.children.length).toBe(workflow.children.length);
991
-
992
- // Check: each child matches
993
- workflow.children.forEach((childWf, index) => {
994
- expect(fiberNode.children[index]).toBe(childWf.node);
995
- verifyFiberConsistency(childWf);
996
- });
997
- }
998
-
999
- verifyFiberConsistency(parent);
1000
- });
1001
-
1002
- it('should apply changes atomically to both trees', () => {
1003
- const parent1 = new SimpleWorkflow('Parent1');
1004
- const parent2 = new SimpleWorkflow('Parent2');
1005
- const child = new SimpleWorkflow('Child', parent1);
1006
-
1007
- // React: changes are batched and committed atomically
1008
- // Our: attachChild/detachChild update both trees
1009
-
1010
- // Execute reparenting
1011
- parent1.detachChild(child);
1012
- parent2.attachChild(child);
1013
-
1014
- // Verify: both trees updated atomically
1015
- // (No intermediate state where trees are inconsistent)
1016
-
1017
- // Workflow tree state
1018
- expect(child.parent).toBe(parent2);
1019
- expect(parent2.children).toContain(child);
1020
-
1021
- // Node tree state (must match exactly)
1022
- expect(child.node.parent).toBe(parent2.node);
1023
- expect(parent2.node.children).toContain(child.node);
1024
-
1025
- // Verify no intermediate state leaked
1026
- expect(parent1.children).not.toContain(child);
1027
- expect(parent1.node.children).not.toContain(child.node);
1028
- });
1029
- });
1030
- ```
1031
-
1032
- ### 6.3 Property-Based Testing Patterns
1033
-
1034
- **Pattern inspired by:** [Hypothesis](https://hypothesis.works/), [QuickCheck](https://www.cs.tufts.edu/~nr/cs257/archive/john-hughes/quick.pdf))
1035
-
1036
- ```typescript
1037
- /**
1038
- * Pattern: Property-Based Testing for Tree Invariants
1039
- * Source: QuickCheck, Hypothesis
1040
- *
1041
- * Key principles:
1042
- * 1. Define invariants as properties
1043
- * 2. Generate random tree structures
1044
- * 3. Verify invariants hold for all inputs
1045
- */
1046
- describe('Property-Based Tree Invariants', () => {
1047
- /**
1048
- * Property: Tree Round-Trip
1049
- * If you detach then reattach a child, structure should be valid
1050
- */
1051
- it('should satisfy round-trip property', () => {
1052
- // Arrange: Create random tree structure
1053
- const root = new SimpleWorkflow('Root');
1054
- const child1 = new SimpleWorkflow('Child1', root);
1055
- const child2 = new SimpleWorkflow('Child2', root);
1056
- const grandchild = new SimpleWorkflow('Grandchild', child1);
1057
-
1058
- // Act: Detach and reattach
1059
- const originalParent = child1.parent;
1060
- const originalChildren = [...root.children];
1061
-
1062
- root.detachChild(child1);
1063
- root.attachChild(child1);
1064
-
1065
- // Assert: Structure should be consistent
1066
- expect(child1.parent).toBe(originalParent);
1067
- expect(root.children).toEqual(originalChildren);
1068
-
1069
- // Verify both trees
1070
- expect(child1.node.parent).toBe(originalParent.node);
1071
- expect(root.node.children).toEqual(originalChildren.map(c => c.node));
1072
- });
1073
-
1074
- /**
1075
- * Property: Idempotence
1076
- * Calling attachChild twice on same parent should be safe
1077
- */
1078
- it('should satisfy idempotence property', () => {
1079
- const parent = new SimpleWorkflow('Parent');
1080
- const child = new SimpleWorkflow('Child', parent);
1081
-
1082
- // Already attached - should not throw (child.parent === this)
1083
- parent.attachChild(child);
1084
-
1085
- // Verify structure unchanged
1086
- expect(parent.children).toEqual([child]);
1087
- expect(parent.node.children).toEqual([child.node]);
1088
- });
1089
-
1090
- /**
1091
- * Property: Commutativity (for siblings)
1092
- * Attaching children in different orders should yield same structure
1093
- */
1094
- it('should satisfy commutativity property for siblings', () => {
1095
- const parent = new SimpleWorkflow('Parent');
1096
-
1097
- // Method 1: Attach in order 1, 2, 3
1098
- const child1 = new SimpleWorkflow('Child1');
1099
- const child2 = new SimpleWorkflow('Child2');
1100
- const child3 = new SimpleWorkflow('Child3');
1101
-
1102
- parent.attachChild(child1);
1103
- parent.attachChild(child2);
1104
- parent.attachChild(child3);
1105
-
1106
- const structure1 = {
1107
- children: [...parent.children],
1108
- nodeChildren: [...parent.node.children],
1109
- };
1110
-
1111
- // Clean up
1112
- parent.detachChild(child1);
1113
- parent.detachChild(child2);
1114
- parent.detachChild(child3);
1115
-
1116
- // Method 2: Attach in order 3, 2, 1
1117
- parent.attachChild(child3);
1118
- parent.attachChild(child2);
1119
- parent.attachChild(child1);
1120
-
1121
- const structure2 = {
1122
- children: [...parent.children],
1123
- nodeChildren: [...parent.node.children],
1124
- };
1125
-
1126
- // Verify: Same final structure (order may differ)
1127
- expect(structure1.children.sort()).toEqual(structure2.children.sort());
1128
- expect(structure1.nodeChildren.sort()).toEqual(structure2.nodeChildren.sort());
1129
- });
1130
- });
1131
- ```
1132
-
1133
- ### 6.4 Academic Research Patterns
1134
-
1135
- **Pattern from:** [Testing Data Structures with Invariants](https://www.cs.princeton.edu/courses/archive/fall09/cos226/lectures/22BalancedTrees.pdf)
1136
-
1137
- ```typescript
1138
- /**
1139
- * Pattern: Academic Invariant Testing
1140
- * Source: Princeton CS226 - Balanced Trees
1141
- *
1142
- * Key principles:
1143
- * 1. Define invariants formally
1144
- * 2. Create verification routines
1145
- * 3. Test invariants before/after operations
1146
- */
1147
- describe('Academic-Style Invariant Testing', () => {
1148
- /**
1149
- * Formal Invariant 1: Tree Size Property
1150
- * For any node: size(node) = 1 + sum(size(children))
1151
- */
1152
- function verifySizeProperty(node: Workflow): boolean {
1153
- const actualSize = collectAllNodes(node).length;
1154
-
1155
- let computedSize = 1; // Count self
1156
- node.children.forEach(child => {
1157
- computedSize += collectAllNodes(child).length;
1158
- });
1159
-
1160
- return actualSize === computedSize;
1161
- }
1162
-
1163
- /**
1164
- * Formal Invariant 2: Unique Parent Property
1165
- * Every non-root node has exactly one parent
1166
- */
1167
- function verifyUniqueParent(root: Workflow): boolean {
1168
- const allNodes = collectAllNodes(root);
1169
- const nonRootNodes = allNodes.filter(n => n.parent !== null);
1170
-
1171
- // Each non-root node should have exactly one parent
1172
- return nonRootNodes.every(node => {
1173
- // Has parent
1174
- if (!node.parent) return false;
1175
-
1176
- // Parent knows about this child
1177
- if (!node.parent.children.includes(node)) return false;
1178
-
1179
- // No other node claims this as child
1180
- const otherClaimants = allNodes.filter(other =>
1181
- other !== node.parent && other.children.includes(node)
1182
- );
1183
-
1184
- return otherClaimants.length === 0;
1185
- });
1186
- }
1187
-
1188
- /**
1189
- * Formal Invariant 3: Mirror Property
1190
- * Workflow tree topology == Node tree topology
1191
- */
1192
- function verifyMirrorProperty(root: Workflow): boolean {
1193
- const workflowNodes = collectAllNodes(root);
1194
-
1195
- return workflowNodes.every(wfNode => {
1196
- // Parent relationship mirrors
1197
- const parentMatches = wfNode.parent
1198
- ? wfNode.node.parent === wfNode.parent.node
1199
- : wfNode.node.parent === null;
1200
-
1201
- // Children relationship mirrors
1202
- const childrenMatch = wfNode.children.length === wfNode.node.children.length &&
1203
- wfNode.children.every((child, i) => wfNode.node.children[i] === child.node);
1204
-
1205
- return parentMatches && childrenMatch;
1206
- });
1207
- }
1208
-
1209
- it('should satisfy all formal invariants', () => {
1210
- const root = new SimpleWorkflow('Root');
1211
- const child1 = new SimpleWorkflow('Child1', root);
1212
- const child2 = new SimpleWorkflow('Child2', root);
1213
- const grandchild = new SimpleWorkflow('Grandchild', child1);
1214
-
1215
- // Verify all invariants
1216
- expect(verifySizeProperty(root)).toBe(true);
1217
- expect(verifyUniqueParent(root)).toBe(true);
1218
- expect(verifyMirrorProperty(root)).toBe(true);
1219
-
1220
- // Perform operation
1221
- root.detachChild(child1);
1222
-
1223
- // Verify invariants still hold
1224
- expect(verifySizeProperty(root)).toBe(true);
1225
- expect(verifyUniqueParent(root)).toBe(true);
1226
- expect(verifyMirrorProperty(root)).toBe(true);
1227
- });
1228
- });
1229
- ```
1230
-
1231
- ---
1232
-
1233
- ## 7. Test Pattern Catalog
1234
-
1235
- ### 7.1 Helper Functions
1236
-
1237
- **Reusable utilities for tree consistency testing:**
1238
-
1239
- ```typescript
1240
- /**
1241
- * Helper: Collect all nodes in tree via BFS
1242
- */
1243
- function collectAllNodes(root: Workflow): Workflow[] {
1244
- const nodes: Workflow[] = [];
1245
- const queue: Workflow[] = [root];
1246
- const visited = new Set<Workflow>();
1247
-
1248
- while (queue.length > 0) {
1249
- const node = queue.shift()!;
1250
-
1251
- if (visited.has(node)) {
1252
- throw new Error(`Circular reference detected at ${node.node.name}`);
1253
- }
1254
-
1255
- visited.add(node);
1256
- nodes.push(node);
1257
-
1258
- queue.push(...node.children);
1259
- }
1260
-
1261
- return nodes;
1262
- }
1263
-
1264
- /**
1265
- * Helper: Validate tree-wide bidirectional consistency
1266
- * Returns array of inconsistency descriptions
1267
- */
1268
- function validateTreeConsistency(root: Workflow): string[] {
1269
- const errors: string[] = [];
1270
- const allNodes = collectAllNodes(root);
1271
-
1272
- allNodes.forEach(node => {
1273
- // Check parent→child link
1274
- if (node.parent) {
1275
- if (!node.parent.children.includes(node)) {
1276
- errors.push(
1277
- `Orphaned child: ${node.node.name} not in parent's children list`
1278
- );
1279
- }
1280
- }
1281
-
1282
- // Check child→parent links
1283
- node.children.forEach(child => {
1284
- if (child.parent !== node) {
1285
- errors.push(
1286
- `Mismatched parent: ${child.node.name}.parent !== ${node.node.name}`
1287
- );
1288
- }
1289
-
1290
- // Check node tree mirrors workflow tree
1291
- if (child.node.parent !== node.node) {
1292
- errors.push(
1293
- `Node tree mismatch: ${child.node.name}.node.parent !== ${node.node.name}.node`
1294
- );
1295
- }
1296
-
1297
- if (!node.node.children.includes(child.node)) {
1298
- errors.push(
1299
- `Node tree orphan: ${child.node.name}.node not in parent's node.children`
1300
- );
1301
- }
1302
- });
1303
- });
1304
-
1305
- return errors;
1306
- }
1307
-
1308
- /**
1309
- * Helper: Verify bidirectional link between parent and child
1310
- */
1311
- function verifyBidirectionalLink(parent: Workflow, child: Workflow): void {
1312
- // Workflow tree
1313
- expect(child.parent).toBe(parent);
1314
- expect(parent.children).toContain(child);
1315
-
1316
- // Node tree
1317
- expect(child.node.parent).toBe(parent.node);
1318
- expect(parent.node.children).toContain(child.node);
1319
- }
1320
-
1321
- /**
1322
- * Helper: Verify complete orphaning after detach
1323
- */
1324
- function verifyOrphaned(child: Workflow): void {
1325
- expect(child.parent).toBeNull();
1326
- expect(child.node.parent).toBeNull();
1327
- }
1328
-
1329
- /**
1330
- * Helper: Get depth of node in tree
1331
- */
1332
- function getDepth(node: Workflow): number {
1333
- let depth = 0;
1334
- let current: Workflow | null = node;
1335
-
1336
- while (current !== null) {
1337
- depth++;
1338
- current = current.parent;
1339
- }
1340
-
1341
- return depth - 1; // Subtract 1 for the node itself
1342
- }
1343
-
1344
- /**
1345
- * Helper: Verify no circular references exist
1346
- */
1347
- function verifyNoCycles(root: Workflow): void {
1348
- const visited = new Set<Workflow>();
1349
- const allNodes = collectAllNodes(root);
1350
-
1351
- allNodes.forEach(node => {
1352
- expect(visited.has(node)).toBe(false);
1353
- visited.add(node);
1354
- });
1355
- }
1356
-
1357
- /**
1358
- * Helper: Verify tree mirror invariant
1359
- */
1360
- function verifyTreeMirror(workflowRoot: Workflow): void {
1361
- const allNodes = collectAllNodes(workflowRoot);
1362
-
1363
- allNodes.forEach(wfNode => {
1364
- const node = wfNode.node;
1365
-
1366
- // Verify parent relationship
1367
- if (wfNode.parent) {
1368
- expect(node.parent).toBe(wfNode.parent.node);
1369
- } else {
1370
- expect(node.parent).toBeNull();
1371
- }
1372
-
1373
- // Verify children relationship
1374
- expect(node.children.length).toBe(wfNode.children.length);
1375
-
1376
- wfNode.children.forEach((childWf, index) => {
1377
- expect(node.children[index]).toBe(childWf.node);
1378
- });
1379
- });
1380
- }
1381
- ```
1382
-
1383
- ### 7.2 Test Templates
1384
-
1385
- **Reusable test templates for common scenarios:**
1386
-
1387
- ```typescript
1388
- /**
1389
- * Template: Test bidirectional consistency for tree operation
1390
- */
1391
- function testOperationConsistency(
1392
- operation: () => void,
1393
- beforeState: { roots: number, totalNodes: number },
1394
- afterState: { roots: number, totalNodes: number }
1395
- ): void {
1396
- // Get initial state
1397
- const beforeErrors = validateTreeConsistency(/* root */);
1398
- expect(beforeErrors).toEqual([]);
1399
-
1400
- // Execute operation
1401
- operation();
1402
-
1403
- // Verify final state
1404
- const afterErrors = validateTreeConsistency(/* root */);
1405
- expect(afterErrors).toEqual([]);
1406
- }
1407
-
1408
- /**
1409
- * Template: Test reparenting scenario
1410
- */
1411
- function testReparentingScenario(
1412
- setup: () => { oldParent: Workflow, newParent: Workflow, child: Workflow }
1413
- ): void {
1414
- const { oldParent, newParent, child } = setup();
1415
-
1416
- // Verify initial state
1417
- verifyBidirectionalLink(oldParent, child);
1418
-
1419
- // Execute reparenting
1420
- oldParent.detachChild(child);
1421
- newParent.attachChild(child);
1422
-
1423
- // Verify new state
1424
- verifyBidirectionalLink(newParent, child);
1425
-
1426
- // Verify old parent no longer has child
1427
- expect(oldParent.children).not.toContain(child);
1428
- expect(oldParent.node.children).not.toContain(child.node);
1429
- }
1430
- ```
1431
-
1432
- ---
1433
-
1434
- ## 8. Implementation Checklist
1435
-
1436
- ### 8.1 Core Tests to Implement
1437
-
1438
- - [ ] **Bidirectional Link Tests**
1439
- - [ ] Verify parent→child and child→parent links after attach
1440
- - [ ] Verify both trees (workflow + node) are synchronized
1441
- - [ ] Verify link consistency after detach
1442
- - [ ] Verify link consistency after reparenting
1443
-
1444
- - [ ] **Tree Mirror Tests**
1445
- - [ ] Verify 1:1 mirror between workflow tree and node tree
1446
- - [ ] Verify mirror invariant after every operation
1447
- - [ ] Verify no orphaned nodes in either tree
1448
- - [ ] Verify no ghost references in either tree
1449
-
1450
- - [ ] **Operation Tests**
1451
- - [ ] Test attachChild() with valid inputs
1452
- - [ ] Test attachChild() error cases (existing parent, circular ref, duplicate)
1453
- - [ ] Test detachChild() with valid inputs
1454
- - [ ] Test detachChild() error cases (not attached)
1455
- - [ ] Test reparenting workflow (detach + attach)
1456
-
1457
- - [ ] **Invariant Tests**
1458
- - [ ] Test acyclicity invariant (no cycles)
1459
- - [ ] Test single root invariant
1460
- - [ ] Test connectedness invariant (all nodes reachable)
1461
- - [ ] Test parent-child consistency invariant
1462
- - [ ] Test edge count invariant (n-1 edges for n nodes)
1463
-
1464
- - [ ] **Adversarial Tests**
1465
- - [ ] Test manual parent mutation detection
1466
- - [ ] Test circular reference detection (simple and complex)
1467
- - [ ] Test stress scenarios (deep hierarchies, wide hierarchies)
1468
- - [ ] Test rapid attach/detach cycles
1469
- - [ ] Test concurrent operations
1470
-
1471
- ### 8.2 Test File Organization
1472
-
1473
- ```
1474
- src/__tests__/
1475
- ├── unit/
1476
- │ └── workflow.test.ts # Existing unit tests
1477
- ├── integration/
1478
- │ ├── workflow-reparenting.test.ts # Existing reparenting tests
1479
- │ └── bidirectional-consistency.test.ts # NEW: Dual tree consistency
1480
- └── adversarial/
1481
- ├── prd-compliance.test.ts # Existing PRD compliance
1482
- ├── edge-case.test.ts # Existing edge cases
1483
- └── tree-invariants.test.ts # NEW: Invariant testing
1484
- ```
1485
-
1486
- ### 8.3 Priority Order
1487
-
1488
- **Phase 1: Core Consistency (High Priority)**
1489
- 1. Bidirectional link verification tests
1490
- 2. Tree mirror invariant tests
1491
- 3. Operation-level consistency tests
1492
-
1493
- **Phase 2: Comprehensive Coverage (Medium Priority)**
1494
- 4. Tree-wide consistency validation
1495
- 5. Invariant testing (acyclicity, connectedness, etc.)
1496
- 6. Reparenting scenario tests
1497
-
1498
- **Phase 3: Robustness (Lower Priority)**
1499
- 7. Adversarial testing (manual mutations, circular refs)
1500
- 8. Stress testing (deep/wide hierarchies)
1501
- 9. Property-based testing
1502
-
1503
- ---
1504
-
1505
- ## 9. Key Takeaways
1506
-
1507
- ### 9.1 Critical Invariants
1508
-
1509
- 1. **1:1 Tree Mirror**: Workflow tree and node tree must always be perfectly synchronized
1510
- 2. **Bidirectional Links**: Parent→child and child→parent references must always match
1511
- 3. **Acyclicity**: No circular references in tree structure
1512
- 4. **Single Root**: Exactly one root node (parent === null)
1513
-
1514
- ### 9.2 Testing Principles
1515
-
1516
- 1. **Test Both Trees**: Always verify both workflow tree and node tree
1517
- 2. **Test Both Directions**: Verify parent→child AND child→parent
1518
- 3. **Test After Every Operation**: Run consistency checks after attach, detach, reparenting
1519
- 4. **Use Helpers**: Create reusable helper functions for common validations
1520
- 5. **Adversarial Testing**: Test manual mutations and edge cases
1521
-
1522
- ### 9.3 Best Practices
1523
-
1524
- 1. **AAA Pattern**: Arrange-Act-Assert structure with clear phase comments
1525
- 2. **Descriptive Names**: Use `should [expected behavior]` naming convention
1526
- 3. **Multiple Assertions**: Verify multiple aspects of consistency
1527
- 4. **Cross-Verification**: Use WorkflowTreeDebugger to verify structure
1528
- 5. **Property-Based Testing**: Define invariants as properties and verify them
1529
-
1530
- ---
1531
-
1532
- ## 10. References and Resources
1533
-
1534
- ### 10.1 External Documentation
1535
-
1536
- - **DOM Tree Specification**: https://dom.spec.whatwg.org/#concept-tree-parent
1537
- - Authoritative source on tree mutation semantics
1538
- - Parent-child relationship management patterns
1539
-
1540
- - **React Fiber Architecture**: https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiber.js
1541
- - Dual tree representation patterns
1542
- - Atomic update strategies
1543
-
1544
- - **QuickCheck Paper**: https://www.cs.tufts.edu/~nr/cs257/archive/john-hughes/quick.pdf
1545
- - Property-based testing methodology
1546
- - Invariant definition patterns
1547
-
1548
- - **Princeton CS226 - Balanced Trees**: https://www.cs.princeton.edu/courses/archive/fall09/cos226/lectures/22BalancedTrees.pdf
1549
- - Formal invariant definition
1550
- - Tree property verification
1551
-
1552
- ### 10.2 Internal Resources
1553
-
1554
- - **Implementation Patterns**: `/home/dustin/projects/groundswell/plan/docs/bugfix-architecture/implementation_patterns.md`
1555
- - **Existing Test Patterns**: `/home/dustin/projects/groundswell/plan/docs/research/P1M2T1S4/existing_test_pattern.md`
1556
- - **Tree Mirroring Tests**: `/home/dustin/projects/groundswell/src/__tests__/integration/tree-mirroring.test.ts`
1557
- - **Reparenting Tests**: `/home/dustin/projects/groundswell/src/__tests__/integration/workflow-reparenting.test.ts`
1558
- - **PRD Compliance Tests**: `/home/dustin/projects/groundswell/src/__tests__/adversarial/prd-compliance.test.ts`
1559
- - **Tree Debugger**: `/home/dustin/projects/groundswell/src/debugger/tree-debugger.ts`
1560
-
1561
- ### 10.3 Actionable Patterns
1562
-
1563
- **For immediate application:**
1564
- 1. Use `verifyBidirectionalLink()` helper after every tree operation
1565
- 2. Run `validateTreeConsistency()` in test teardown
1566
- 3. Test both workflow tree AND node tree in all assertions
1567
- 4. Add adversarial tests for manual mutations
1568
- 5. Implement property-based tests for core invariants
1569
-
1570
- ---
1571
-
1572
- **Document Status:** Complete
1573
- **Next Steps:** Implement test suite based on patterns documented here
1574
- **Maintainer:** P1M3T1S4 Research Team