groundswell 0.0.1 → 0.0.2

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 (242) hide show
  1. package/.claude/commands/subtask-planning/prp-base-create.md +120 -0
  2. package/.claude/commands/subtask-planning/prp-base-execute.md +65 -0
  3. package/.claude/commands/task-breakdown.md +94 -0
  4. package/.claude/system_prompts/task-breakdown.md +1 -0
  5. package/CHANGELOG.md +188 -0
  6. package/PRD.md +543 -0
  7. package/README.md +99 -5
  8. package/examples/README.md +15 -1
  9. package/examples/examples/11-reparenting-workflows.ts +269 -0
  10. package/examples/index.ts +4 -0
  11. package/package-lock.json +2398 -0
  12. package/package.json +3 -1
  13. package/plan/001_d3bb02af4886/TEST_RESULTS.md +259 -0
  14. package/plan/001_d3bb02af4886/bug_fix_tasks.json +484 -0
  15. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +488 -0
  16. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +581 -0
  17. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +687 -0
  18. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +492 -0
  19. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +932 -0
  20. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +1109 -0
  21. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +802 -0
  22. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +603 -0
  23. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +564 -0
  24. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +518 -0
  25. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +1252 -0
  26. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +364 -0
  27. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +114 -0
  28. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +205 -0
  29. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +199 -0
  30. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +134 -0
  31. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +495 -0
  32. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +435 -0
  33. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +506 -0
  34. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +612 -0
  35. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +558 -0
  36. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +788 -0
  37. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +460 -0
  38. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +454 -0
  39. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +520 -0
  40. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +417 -0
  41. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +760 -0
  42. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +245 -0
  43. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +792 -0
  44. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +535 -0
  45. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +190 -0
  46. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +654 -0
  47. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +227 -0
  48. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +345 -0
  49. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +193 -0
  50. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +1323 -0
  51. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +1011 -0
  52. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +927 -0
  53. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +505 -0
  54. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +401 -0
  55. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +142 -0
  56. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +112 -0
  57. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +159 -0
  58. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +549 -0
  59. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +368 -0
  60. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +172 -0
  61. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +175 -0
  62. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +696 -0
  63. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +860 -0
  64. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +1066 -0
  65. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +1103 -0
  66. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +789 -0
  67. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +1098 -0
  68. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +1037 -0
  69. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +916 -0
  70. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +1045 -0
  71. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +890 -0
  72. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +822 -0
  73. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +668 -0
  74. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +706 -0
  75. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +265 -0
  76. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +655 -0
  77. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +1103 -0
  78. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +426 -0
  79. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +506 -0
  80. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +114 -0
  81. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +316 -0
  82. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +754 -0
  83. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +612 -0
  84. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +719 -0
  85. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +215 -0
  86. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +765 -0
  87. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +718 -0
  88. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +149 -0
  89. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +470 -0
  90. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +332 -0
  91. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +167 -0
  92. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +265 -0
  93. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +273 -0
  94. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +760 -0
  95. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +434 -0
  96. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +717 -0
  97. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +472 -0
  98. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +125 -0
  99. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +301 -0
  100. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +1170 -0
  101. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +940 -0
  102. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +151 -0
  103. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +650 -0
  104. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +259 -0
  105. package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +457 -0
  106. package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +346 -0
  107. package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +311 -0
  108. package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +1565 -0
  109. package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +288 -0
  110. package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +741 -0
  111. package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +652 -0
  112. package/plan/001_d3bb02af4886/docs/PRP/PRP.md +527 -0
  113. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +415 -0
  114. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +378 -0
  115. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +713 -0
  116. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +370 -0
  117. package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +499 -0
  118. package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +230 -0
  119. package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +1134 -0
  120. package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +179 -0
  121. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +629 -0
  122. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +214 -0
  123. package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +629 -0
  124. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +529 -0
  125. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +142 -0
  126. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +304 -0
  127. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +558 -0
  128. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +256 -0
  129. package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +346 -0
  130. package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +415 -0
  131. package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +489 -0
  132. package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +218 -0
  133. package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +380 -0
  134. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +1923 -0
  135. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +319 -0
  136. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +115 -0
  137. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +134 -0
  138. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +153 -0
  139. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +132 -0
  140. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +716 -0
  141. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +186 -0
  142. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +604 -0
  143. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +213 -0
  144. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +30 -0
  145. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +56 -0
  146. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +53 -0
  147. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +49 -0
  148. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +958 -0
  149. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +339 -0
  150. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +305 -0
  151. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +433 -0
  152. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +1574 -0
  153. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +1014 -0
  154. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +376 -0
  155. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +1507 -0
  156. package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +949 -0
  157. package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +619 -0
  158. package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +723 -0
  159. package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-security-guide.md +56 -0
  160. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +460 -0
  161. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +324 -0
  162. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +175 -0
  163. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +499 -0
  164. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +163 -0
  165. package/plan/bugfix/BUG_FIX_SUMMARY.md +961 -0
  166. package/src/__tests__/adversarial/attachChild-performance.test.ts +216 -0
  167. package/src/__tests__/adversarial/circular-reference.test.ts +101 -0
  168. package/src/__tests__/adversarial/complex-circular-reference.test.ts +139 -0
  169. package/src/__tests__/adversarial/concurrent-task-failures.test.ts +571 -0
  170. package/src/__tests__/adversarial/deep-analysis.test.ts +729 -0
  171. package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +213 -0
  172. package/src/__tests__/adversarial/e2e-prd-validation.test.ts +448 -0
  173. package/src/__tests__/adversarial/edge-case.test.ts +703 -0
  174. package/src/__tests__/adversarial/error-merge-strategy.test.ts +760 -0
  175. package/src/__tests__/adversarial/incremental-performance.test.ts +140 -0
  176. package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +457 -0
  177. package/src/__tests__/adversarial/observer-propagation.test.ts +487 -0
  178. package/src/__tests__/adversarial/parent-validation.test.ts +143 -0
  179. package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +611 -0
  180. package/src/__tests__/adversarial/prd-compliance.test.ts +731 -0
  181. package/src/__tests__/compatibility/backward-compatibility.test.ts +1572 -0
  182. package/src/__tests__/helpers/index.ts +18 -0
  183. package/src/__tests__/helpers/tree-verification.ts +257 -0
  184. package/src/__tests__/integration/bidirectional-consistency.test.ts +847 -0
  185. package/src/__tests__/integration/observer-logging.test.ts +643 -0
  186. package/src/__tests__/integration/tree-mirroring.test.ts +37 -0
  187. package/src/__tests__/integration/workflow-reparenting.test.ts +303 -0
  188. package/src/__tests__/unit/context.test.ts +79 -0
  189. package/src/__tests__/unit/logger.test.ts +293 -0
  190. package/src/__tests__/unit/observable.test.ts +321 -0
  191. package/src/__tests__/unit/tree-debugger-incremental.test.ts +170 -0
  192. package/src/__tests__/unit/utils/workflow-error-utils.test.ts +209 -0
  193. package/src/__tests__/unit/workflow-detachChild.test.ts +100 -0
  194. package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +153 -0
  195. package/src/__tests__/unit/workflow-isDescendantOf.test.ts +180 -0
  196. package/src/__tests__/unit/workflow.test.ts +277 -1
  197. package/src/core/agent.ts +21 -1
  198. package/src/core/logger.ts +27 -2
  199. package/src/core/workflow-context.ts +6 -4
  200. package/src/core/workflow.ts +252 -14
  201. package/src/debugger/tree-debugger.ts +52 -7
  202. package/src/decorators/task.ts +65 -2
  203. package/src/index.ts +4 -2
  204. package/src/types/decorators.ts +8 -1
  205. package/src/types/events.ts +1 -0
  206. package/src/utils/index.ts +1 -0
  207. package/src/utils/observable.ts +32 -3
  208. package/src/utils/workflow-error-utils.ts +56 -0
  209. package/tsconfig.json +1 -1
  210. package/llms_full.txt +0 -5890
  211. package/tasks.json +0 -0
  212. /package/plan/{backlog.json → 001_d3bb02af4886/backlog.json} +0 -0
  213. /package/plan/{P1P2/PRP.md → 001_d3bb02af4886/docs/PRP/P1P2-PRP.md} +0 -0
  214. /package/plan/{P3P4/PRP.md → 001_d3bb02af4886/docs/PRP/P3P4-PRP.md} +0 -0
  215. /package/plan/{P4P5/PRP.md → 001_d3bb02af4886/docs/PRP/P4P5-PRP.md} +0 -0
  216. /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/external_deps.md +0 -0
  217. /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/system_context.md +0 -0
  218. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_BEST_PRACTICES.md +0 -0
  219. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_CODE_PATTERNS.md +0 -0
  220. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_INTEGRATION_GUIDE.md +0 -0
  221. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_RESEARCH_INDEX.md +0 -0
  222. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_INDEX.md +0 -0
  223. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_RESEARCH_REPORT.md +0 -0
  224. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/RESEARCH_SUMMARY.md +0 -0
  225. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/anthropic-sdk.md +0 -0
  226. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/async-local-storage.md +0 -0
  227. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-code-patterns.md +0 -0
  228. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-decision-matrix.md +0 -0
  229. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-implementation-guide.md +0 -0
  230. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-integration-guide.md +0 -0
  231. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-patterns.md +0 -0
  232. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-quick-reference.md +0 -0
  233. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/zod-schema.md +0 -0
  234. /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/caching-lru.md +0 -0
  235. /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/introspection-tools.md +0 -0
  236. /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/reflection-patterns.md +0 -0
  237. /package/plan/{P4P5/research → 001_d3bb02af4886/docs/research/P4P5}/RESEARCH_SUMMARY.md +0 -0
  238. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/INTROSPECTION_RESEARCH_SUMMARY.md +0 -0
  239. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/README-INTROSPECTION.md +0 -0
  240. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/agent-introspection-patterns.md +0 -0
  241. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-tool-examples.md +0 -0
  242. /package/{PRPs/PRDs/001-hierarchical-workflow-engine.md → plan/001_d3bb02af4886/prd_snapshot.md} +0 -0
@@ -0,0 +1,603 @@
1
+ # Workflow Engine Test References for Concurrent Failures
2
+
3
+ ## Repository Quick Links
4
+
5
+ ### Apache Airflow
6
+ - **Main Repo**: https://github.com/apache/airflow
7
+ - **Key Test Files**:
8
+ - `tests/models/test_taskinstance.py` - Task failure states
9
+ - `tests/executors/test_local_executor.py` - Concurrent task execution
10
+ - `tests/dag_processing/test_dag_run.py` - DAG-level failures
11
+ - `tests/www/views/test_views.py` - UI error display
12
+
13
+ ### Temporal
14
+ - **Main Repo**: https://github.com/temporalio/sdk-python
15
+ - **Key Test Files**:
16
+ - `tests/worker/workflow_tests/test_child_workflow.py` - Child workflows
17
+ - `tests/worker/workflow_tests/test_workflow_replay.py` - Failure recovery
18
+ - `tests/worker/activity_tests/test_activity.py` - Activity failures
19
+
20
+ ### Prefect
21
+ - **Main Repo**: https://github.com/PrefectHQ/prefect
22
+ - **Key Test Files**:
23
+ - `tests/tasks/test_task_runners.py` - Concurrent execution
24
+ - `tests/orchestration/test_task_runs.py` - State tracking
25
+ - `tests/engine/test_execution.py` - Engine failure handling
26
+
27
+ ### Dagster
28
+ - **Main Repo**: https://github.com/dagster-io/dagster
29
+ - **Key Test Files**:
30
+ - `dagster_tests/core_tests/execution_tests/` - Execution patterns
31
+ - `dagster_tests/core_tests/composite_tests/` - Composite solids
32
+
33
+ ### Node.js Promise Tests
34
+ - **Main Repo**: https://github.com/nodejs/node
35
+ - **Key Test Files**:
36
+ - `test/parallel/test-promise-all-settled.js` - allSettled behavior
37
+ - `test/parallel/test-promise-any.js` - Promise.any patterns
38
+
39
+ ---
40
+
41
+ ## Common Testing Patterns by Engine
42
+
43
+ ### 1. Airflow: TaskInstance State Tracking
44
+
45
+ **Location**: `tests/models/test_taskinstance.py`
46
+
47
+ ```python
48
+ def test_concurrent_task_failure_states(self):
49
+ """
50
+ Test that multiple task instances can fail concurrently
51
+ while others succeed, and all states are tracked correctly.
52
+ """
53
+ dag = DAG(
54
+ 'test_concurrent_failures',
55
+ default_args={
56
+ 'owner': 'airflow',
57
+ 'start_date': datetime(2024, 1, 1),
58
+ 'retries': 0,
59
+ }
60
+ )
61
+
62
+ # Create tasks with different outcomes
63
+ tasks = []
64
+ for i in range(10):
65
+ task = PythonOperator(
66
+ task_id=f'task_{i}',
67
+ python_callable=execute_task,
68
+ op_args=[i],
69
+ dag=dag
70
+ )
71
+ tasks.append(task)
72
+
73
+ # Execute
74
+ dr = dag.create_dagrun(
75
+ run_id='test_run',
76
+ execution_date=datetime(2024, 1, 1),
77
+ state=State.RUNNING
78
+ )
79
+
80
+ # Run tasks
81
+ for task in tasks:
82
+ ti = TaskInstance(task, run_id=dr.run_id)
83
+ ti.run(ignore_ti_state=True)
84
+
85
+ # Assert: All task instances have a state
86
+ tis = dr.get_task_instances()
87
+ assert len(tis) == 10
88
+
89
+ # Assert: Count failures and successes
90
+ failed = [ti for ti in tis if ti.state == State.FAILED]
91
+ success = [ti for ti in tis if ti.state == State.SUCCESS]
92
+
93
+ assert len(failed) == expected_failures
94
+ assert len(success) == expected_successes
95
+
96
+ # Assert: No task instances in RUNNING state (all settled)
97
+ running = [ti for ti in tis if ti.state == State.RUNNING]
98
+ assert len(running) == 0
99
+ ```
100
+
101
+ **Key Assertions**:
102
+ - All task instances have a terminal state
103
+ - Correct count of failures vs successes
104
+ - No tasks left in RUNNING state
105
+
106
+ ---
107
+
108
+ ### 2. Temporal: Child Workflow Error Collection
109
+
110
+ **Location**: `tests/worker/workflow_tests/test_child_workflow.py`
111
+
112
+ ```python
113
+ @workflow.defn
114
+ class ParentWorkflow:
115
+ @workflow.run
116
+ async def run(self) -> dict[str, Any]:
117
+ # Start multiple child workflows
118
+ handles = [
119
+ workflow.start_child_workflow(
120
+ ChildWorkflow,
121
+ id=f"child-{i}",
122
+ task_queue="test-queue"
123
+ )
124
+ for i in range(5)
125
+ ]
126
+
127
+ # Wait for all children with exception collection
128
+ results = []
129
+ errors = []
130
+
131
+ for handle in handles:
132
+ try:
133
+ result = await handle.result()
134
+ results.append(result)
135
+ except ApplicationError as e:
136
+ errors.append({
137
+ 'child_id': handle.id,
138
+ 'error': e.message,
139
+ 'details': e.details
140
+ })
141
+
142
+ # Return aggregated results
143
+ return {
144
+ 'results': results,
145
+ 'errors': errors,
146
+ 'total': len(handles)
147
+ }
148
+
149
+ # Test
150
+ async def test_child_workflow_error_collection():
151
+ # Create a workflow that will fail specific children
152
+ async def test_workflow():
153
+ result = await ParentWorkflow.run()
154
+ assert result['total'] == 5
155
+ assert len(result['results']) + len(result['errors']) == 5
156
+ assert all('child_id' in e for e in result['errors'])
157
+
158
+ # Execute test
159
+ await execute_workflow(test_workflow)
160
+ ```
161
+
162
+ **Key Assertions**:
163
+ - Total children = results + errors (all accounted for)
164
+ - Each error has child identifier
165
+ - No orphaned child workflows
166
+
167
+ ---
168
+
169
+ ### 3. Prefect: State Aggregation for Concurrent Tasks
170
+
171
+ **Location**: `tests/tasks/test_task_runners.py`
172
+
173
+ ```python
174
+ async def test_concurrent_task_state_aggregation():
175
+ """
176
+ Test that all task states are aggregated correctly
177
+ when multiple tasks run concurrently with mixed outcomes.
178
+ """
179
+
180
+ @task
181
+ async def failing_task(task_id: str):
182
+ raise ValueError(f"Task {task_id} failed")
183
+
184
+ @task
185
+ async def succeeding_task(task_id: str):
186
+ return f"Task {task_id} succeeded"
187
+
188
+ # Create task runs with mixed outcomes
189
+ task_runs = []
190
+
191
+ for i in range(10):
192
+ if i % 3 == 0:
193
+ # Every 3rd task fails
194
+ task_runs.append(failing_task(f"task-{i}"))
195
+ else:
196
+ task_runs.append(succeeding_task(f"task-{i}"))
197
+
198
+ # Run all tasks concurrently
199
+ results = await asyncio.gather(
200
+ *task_runs,
201
+ return_exceptions=True
202
+ )
203
+
204
+ # Aggregate states
205
+ failed = [r for r in results if isinstance(r, Exception)]
206
+ succeeded = [r for r in results if not isinstance(r, Exception)]
207
+
208
+ # Assert: All tasks completed
209
+ assert len(failed) + len(succeeded) == 10
210
+
211
+ # Assert: Expected failure count
212
+ assert len(failed) == 4 # 0, 3, 6, 9
213
+
214
+ # Assert: Expected success count
215
+ assert len(succeeded) == 6
216
+
217
+ # Assert: All error messages are distinct
218
+ error_messages = [str(e) for e in failed]
219
+ assert len(set(error_messages)) == 4
220
+ ```
221
+
222
+ **Key Assertions**:
223
+ - Total results = failed + succeeded
224
+ - Correct counts for each state
225
+ - Distinct error messages
226
+
227
+ ---
228
+
229
+ ### 4. Node.js: Promise.allSettled Edge Cases
230
+
231
+ **Location**: `test/parallel/test-promise-all-settled.js`
232
+
233
+ ```javascript
234
+ // Test 1: All promises rejected
235
+ assert.rejects(
236
+ Promise.all([
237
+ Promise.reject(1),
238
+ Promise.reject(2),
239
+ Promise.reject(3)
240
+ ]),
241
+ { 1: 1 }
242
+ );
243
+
244
+ // Test 2: Mixed rejection/fulfillment
245
+ const input = [
246
+ Promise.resolve(1),
247
+ Promise.reject('err1'),
248
+ Promise.resolve(2),
249
+ Promise.reject('err2'),
250
+ Promise.resolve(3)
251
+ ];
252
+
253
+ Promise.allSettled(input).then((results) => {
254
+ // Assert: All promises settled
255
+ assert.strictEqual(results.length, 5);
256
+
257
+ // Assert: Verify status distribution
258
+ const fulfilled = results.filter(r => r.status === 'fulfilled');
259
+ const rejected = results.filter(r => r.status === 'rejected');
260
+
261
+ assert.strictEqual(fulfilled.length, 3);
262
+ assert.strictEqual(rejected.length, 2);
263
+
264
+ // Assert: Values preserved in order
265
+ assert.deepStrictEqual(
266
+ fulfilled.map(r => r.value),
267
+ [1, 2, 3]
268
+ );
269
+
270
+ // Assert: Reasons preserved in order
271
+ assert.deepStrictEqual(
272
+ rejected.map(r => r.reason),
273
+ ['err1', 'err2']
274
+ );
275
+ });
276
+
277
+ // Test 3: Empty input
278
+ Promise.allSettled([]).then((results) => {
279
+ assert.deepStrictEqual(results, []);
280
+ assert.strictEqual(results.length, 0);
281
+ });
282
+
283
+ // Test 4: All non-thenables
284
+ Promise.allSettled([1, 2, 3]).then((results) => {
285
+ assert.strictEqual(results.length, 3);
286
+ results.forEach((result) => {
287
+ assert.strictEqual(result.status, 'fulfilled');
288
+ });
289
+ });
290
+
291
+ // Test 5: Already settled promises
292
+ const settledPromise = Promise.resolve('already settled');
293
+ Promise.allSettled([settledPromise]).then((results) => {
294
+ assert.strictEqual(results[0].status, 'fulfilled');
295
+ assert.strictEqual(results[0].value, 'already settled');
296
+ });
297
+ ```
298
+
299
+ **Key Assertions**:
300
+ - All promises in result array
301
+ - Statuses correct (fulfilled vs rejected)
302
+ - Values/reasons preserved
303
+ - Handles empty and non-thenable inputs
304
+
305
+ ---
306
+
307
+ ## Test Helpers by Engine
308
+
309
+ ### Airflow: State Verification Helper
310
+
311
+ ```python
312
+ def verify_dag_run_states(dag_run: DagRun, expected: Dict[str, int]):
313
+ """
314
+ Helper to verify DAG run has expected state distribution.
315
+
316
+ Args:
317
+ dag_run: DAG run to verify
318
+ expected: Dict mapping state to expected count
319
+ e.g., {'success': 7, 'failed': 3}
320
+ """
321
+ tis = dag_run.get_task_instances()
322
+
323
+ # Count actual states
324
+ actual_counts = {}
325
+ for ti in tis:
326
+ state = ti.state
327
+ actual_counts[state] = actual_counts.get(state, 0) + 1
328
+
329
+ # Verify each expected state count
330
+ for state, expected_count in expected.items():
331
+ actual_count = actual_counts.get(state, 0)
332
+ assert actual_count == expected_count, (
333
+ f"Expected {expected_count} tasks in state {state}, "
334
+ f"but found {actual_count}"
335
+ )
336
+
337
+ # Verify all tasks accounted for
338
+ total_expected = sum(expected.values())
339
+ total_actual = len(tis)
340
+ assert total_actual == total_expected, (
341
+ f"Expected {total_expected} task instances, "
342
+ f"but found {total_actual}"
343
+ )
344
+
345
+ # Verify no tasks in non-terminal states
346
+ non_terminal = [
347
+ state for state in actual_counts.keys()
348
+ if state not in [State.SUCCESS, State.FAILED, State.SKIPPED]
349
+ ]
350
+ assert len(non_terminal) == 0, (
351
+ f"Found tasks in non-terminal states: {non_terminal}"
352
+ )
353
+ ```
354
+
355
+ ---
356
+
357
+ ### Temporal: Error Aggregation Helper
358
+
359
+ ```python
360
+ @dataclass
361
+ class ChildWorkflowError:
362
+ child_id: str
363
+ error_type: str
364
+ message: str
365
+ details: Dict[str, Any]
366
+
367
+ @dataclass
368
+ class ChildWorkflowResult:
369
+ child_id: str
370
+ result: Any
371
+ status: str
372
+
373
+ def aggregate_child_results(
374
+ handles: List[ChildWorkflowHandle]
375
+ ) -> Dict[str, Any]:
376
+ """
377
+ Aggregate results from multiple child workflows,
378
+ collecting both successes and failures.
379
+
380
+ Returns:
381
+ Dict with 'results', 'errors', and 'total' keys
382
+ """
383
+ results = []
384
+ errors = []
385
+
386
+ for handle in handles:
387
+ try:
388
+ result = handle.result()
389
+ results.append(ChildWorkflowResult(
390
+ child_id=handle.id,
391
+ result=result,
392
+ status='completed'
393
+ ))
394
+ except Exception as e:
395
+ errors.append(ChildWorkflowError(
396
+ child_id=handle.id,
397
+ error_type=type(e).__name__,
398
+ message=str(e),
399
+ details=getattr(e, 'details', {})
400
+ ))
401
+
402
+ return {
403
+ 'results': results,
404
+ 'errors': errors,
405
+ 'total': len(handles),
406
+ 'success_count': len(results),
407
+ 'error_count': len(errors)
408
+ }
409
+
410
+ # Test helper
411
+ def assert_child_execution_complete(aggregation: Dict[str, Any]):
412
+ """
413
+ Assert that all child workflows completed.
414
+ """
415
+ assert aggregation['total'] > 0, "No child workflows executed"
416
+
417
+ total_accounted = aggregation['success_count'] + aggregation['error_count']
418
+ assert total_accounted == aggregation['total'], (
419
+ f"Not all children accounted for: "
420
+ f"{aggregation['total']} total, {total_accounted} accounted"
421
+ )
422
+
423
+ # Verify all errors have child_id
424
+ for error in aggregation['errors']:
425
+ assert error.child_id, "Error missing child_id"
426
+ assert error.message, "Error missing message"
427
+ ```
428
+
429
+ ---
430
+
431
+ ### Prefect: Promise.allSettled-like Helper
432
+
433
+ ```python
434
+ from typing import Any, List, Tuple
435
+ from prefect import task
436
+
437
+ async def run_tasks_with_settlement(
438
+ tasks: List[Coroutine]
439
+ ) -> Tuple[List[Any], List[Exception]]:
440
+ """
441
+ Run all tasks to completion, collecting both
442
+ successful results and failures.
443
+
444
+ Similar to Promise.allSettled in JavaScript.
445
+
446
+ Returns:
447
+ Tuple of (successful_results, failures)
448
+ """
449
+ # Run all tasks, catching exceptions
450
+ results = await asyncio.gather(
451
+ *tasks,
452
+ return_exceptions=True
453
+ )
454
+
455
+ # Separate successes from failures
456
+ successes = []
457
+ failures = []
458
+
459
+ for result in results:
460
+ if isinstance(result, Exception):
461
+ failures.append(result)
462
+ else:
463
+ successes.append(result)
464
+
465
+ return successes, failures
466
+
467
+ # Test helper
468
+ def assert_settlement_counts(
469
+ successes: List[Any],
470
+ failures: List[Exception],
471
+ expected_successes: int,
472
+ expected_failures: int
473
+ ):
474
+ """
475
+ Assert expected counts of successes and failures.
476
+ """
477
+ assert len(successes) == expected_successes, (
478
+ f"Expected {expected_successes} successes, "
479
+ f"got {len(successes)}"
480
+ )
481
+
482
+ assert len(failures) == expected_failures, (
483
+ f"Expected {expected_failures} failures, "
484
+ f"got {len(failures)}"
485
+ )
486
+
487
+ # Assert all error messages are unique
488
+ error_messages = [str(e) for e in failures]
489
+ assert len(set(error_messages)) == len(error_messages), (
490
+ "Some error messages are duplicates"
491
+ )
492
+ ```
493
+
494
+ ---
495
+
496
+ ## Observable Testing Patterns
497
+
498
+ ### Event Tracking Template
499
+
500
+ ```python
501
+ class EventTracker:
502
+ """
503
+ Helper to track events during concurrent workflow execution.
504
+ """
505
+
506
+ def __init__(self):
507
+ self.events = []
508
+
509
+ def track_event(self, event_type: str, **kwargs):
510
+ """Record an event with timestamp and metadata."""
511
+ self.events.append({
512
+ 'type': event_type,
513
+ 'timestamp': time.time(),
514
+ **kwargs
515
+ })
516
+
517
+ def get_events_by_type(self, event_type: str) -> List[Dict]:
518
+ """Get all events of a specific type."""
519
+ return [e for e in self.events if e['type'] == event_type]
520
+
521
+ def assert_event_count(self, event_type: str, expected_count: int):
522
+ """Assert expected number of events of a type."""
523
+ actual = len(self.get_events_by_type(event_type))
524
+ assert actual == expected_count, (
525
+ f"Expected {expected_count} {event_type} events, "
526
+ f"got {actual}"
527
+ )
528
+
529
+ def assert_event_sequence(self, expected_sequence: List[str]):
530
+ """Assert events occurred in expected order."""
531
+ actual_sequence = [e['type'] for e in self.events]
532
+ assert actual_sequence == expected_sequence, (
533
+ f"Event sequence mismatch.\n"
534
+ f"Expected: {expected_sequence}\n"
535
+ f"Actual: {actual_sequence}"
536
+ )
537
+
538
+ def assert_all_children_accounted(self, child_count: int):
539
+ """Assert all child workflows have terminal events."""
540
+ completed = len(self.get_events_by_type('child_completed'))
541
+ failed = len(self.get_events_by_type('child_failed'))
542
+
543
+ assert completed + failed == child_count, (
544
+ f"Not all children accounted for. "
545
+ f"Expected {child_count}, got {completed + failed}"
546
+ )
547
+ ```
548
+
549
+ ---
550
+
551
+ ## Performance Testing Patterns
552
+
553
+ ### Timeout Protection Template
554
+
555
+ ```typescript
556
+ /**
557
+ * Helper to run workflows with timeout protection
558
+ * to detect hanging promises.
559
+ */
560
+ async function runWithTimeout<T>(
561
+ promise: Promise<T>,
562
+ timeoutMs: number,
563
+ errorMessage: string = 'Operation timed out'
564
+ ): Promise<T> {
565
+ const timeout = new Promise<never>((_, reject) =>
566
+ setTimeout(() => reject(new Error(errorMessage)), timeoutMs)
567
+ );
568
+
569
+ return Promise.race([promise, timeout]);
570
+ }
571
+
572
+ // Usage in test
573
+ it('should complete all workflows without hanging', async () => {
574
+ const children = createChildren(10);
575
+
576
+ const results = await runWithTimeout(
577
+ Promise.allSettled(children.map(c => c.run())),
578
+ 5000, // 5 second timeout
579
+ 'Workflows hung - some promises did not settle'
580
+ );
581
+
582
+ expect(results.length).toBe(10);
583
+ });
584
+ ```
585
+
586
+ ---
587
+
588
+ ## Summary of Key Patterns
589
+
590
+ | Pattern | Purpose | Example From |
591
+ |---------|---------|--------------|
592
+ | **Promise.allSettled** | Ensure all tasks complete regardless of failures | Node.js, Prefect |
593
+ | **Event Tracking** | Verify errors are emitted and captured | Airflow, Temporal |
594
+ | **State Aggregation** | Collect final states of all concurrent tasks | Prefect, Temporal |
595
+ | **Count Assertions** | Verify expected failure/success counts | All engines |
596
+ | **Timeout Protection** | Detect hanging or orphaned workflows | Temporal, Node.js |
597
+ | **Error Context** | Preserve workflow info in errors | Temporal, Airflow |
598
+ | **Distinct Errors** | Ensure multiple failures create distinct errors | All engines |
599
+ | **Completion Verification** | Explicitly verify all tasks complete | All engines |
600
+
601
+ ---
602
+
603
+ This document provides a reference guide for finding specific test implementations in major workflow engines. Each engine has extensive test suites that demonstrate these patterns in production code.