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,932 @@
1
+ # PRP: P1.M2.T1.S3 - Add Tests for Concurrent Task Failure Scenarios
2
+
3
+ **Document Version:** 1.0
4
+ **Creation Date:** 2026-01-12
5
+ **Target:** Subtask P1.M2.T1.S3 - Add tests for concurrent task failure scenarios
6
+ **Primary Files:** `src/__tests__/adversarial/concurrent-task-failures.test.ts` (new)
7
+
8
+ ---
9
+
10
+ ## Goal
11
+
12
+ **Feature Goal**: Create a comprehensive test suite for the Promise.allSettled implementation in the @Task decorator (completed in S2) that validates all concurrent task failure scenarios including single child failure, multiple children failing, mixed success/failure, and all children failing. Tests must verify that all children complete execution even when some fail, and that error collection works correctly.
13
+
14
+ **Deliverable**: New test file `src/__tests__/adversarial/concurrent-task-failures.test.ts` containing:
15
+ 1. Tests for single child failure in concurrent batch
16
+ 2. Tests for multiple children failing concurrently
17
+ 3. Tests for mixed success/failure scenarios
18
+ 4. Tests for all children failing edge case
19
+ 5. Verification that ALL workflows complete (no orphaned promises)
20
+ 6. Verification of error collection correctness
21
+ 7. Event emission validation during concurrent failures
22
+
23
+ **Success Definition**:
24
+ - All tests pass demonstrating all workflows complete before error is thrown
25
+ - Error collection is validated (all errors captured)
26
+ - Test file follows existing Groundswell test patterns
27
+ - Tests use vitest framework and follow project conventions
28
+ - Tests verify the Promise.allSettled implementation from S2 works correctly
29
+ - No orphaned or hanging promises in any test scenario
30
+
31
+ ---
32
+
33
+ ## All Needed Context
34
+
35
+ ### Context Completeness Check
36
+
37
+ **"No Prior Knowledge" Test**: If someone knew nothing about this codebase, would they have everything needed to implement this successfully?
38
+
39
+ **Answer**: YES - This PRP provides:
40
+ - Exact test file location and naming convention
41
+ - Complete code examples for all test scenarios
42
+ - Existing test patterns to follow
43
+ - Vitest testing patterns from research
44
+ - Production examples from workflow engines
45
+ - Helper functions to create test workflows
46
+ - Event verification patterns
47
+ - Timeout protection patterns
48
+
49
+ ### Documentation & References
50
+
51
+ ```yaml
52
+ # MUST READ - Promise.allSettled implementation from S2
53
+ - file: src/decorators/task.ts
54
+ lines: 111-120
55
+ why: Contains the Promise.allSettled implementation that needs testing
56
+ pattern: const results = await Promise.allSettled(...); const rejected = results.filter(...);
57
+ critical: Tests must verify this implementation collects all errors before throwing first
58
+
59
+ - file: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md
60
+ why: PRP for S2 implementation showing exact changes made
61
+ section: "Appendix: Complete Code Change Reference"
62
+ critical: Shows the before/after of Promise.all to Promise.allSettled migration
63
+
64
+ # EXISTING TEST PATTERNS - Follow these conventions
65
+ - file: src/__tests__/adversarial/edge-case.test.ts
66
+ lines: 366-430
67
+ why: Contains existing concurrent task execution tests with mixed success/failure
68
+ pattern: Testing @Task decorator with concurrent option and error handling
69
+
70
+ - file: src/__tests__/unit/decorators.test.ts
71
+ lines: 1-100
72
+ why: Shows basic test structure, Workflow class usage, and decorator patterns
73
+ pattern: describe blocks, async/await, expect assertions
74
+
75
+ - file: src/__tests__/adversarial/observer-propagation.test.ts
76
+ why: Shows event collection and verification patterns
77
+ pattern: Event observer setup, event filtering, assertion patterns
78
+
79
+ - file: src/__tests__/adversarial/deep-hierarchy-stress.test.ts
80
+ lines: 297-324
81
+ why: Shows concurrent execution with @Task decorator and multiple children
82
+ pattern: @Task({ concurrent: true }) usage with array of workflows
83
+
84
+ # VITEST TESTING PATTERNS
85
+ - url: https://vitest.dev/guide/async.html
86
+ why: Official vitest async testing guide
87
+ section: Async Testing
88
+ critical: async/await patterns, .resolves/.rejects modifiers
89
+
90
+ - url: https://vitest.dev/api/expect.html
91
+ why: Complete expect API reference
92
+ section: Matchers
93
+ critical: toHaveLength, toMatchObject, toContain, toBeInstanceOf
94
+
95
+ - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md
96
+ why: Research document with vitest patterns for concurrent testing
97
+ section: "3. Promise.allSettled Testing Patterns"
98
+ critical: Type guard patterns, error filtering, counting assertions
99
+
100
+ # CONCURRENT ERROR TESTING RESEARCH
101
+ - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md
102
+ why: Production examples from workflow engines
103
+ section: "Test Scenarios"
104
+ critical: Complete test scenarios for all failure patterns
105
+
106
+ - docfile: plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md
107
+ why: Promise.allSettled implementation patterns and testing
108
+ section: "Testing Examples"
109
+ critical: Patterns for verifying all operations complete
110
+
111
+ # GROUNDSWELL TEST CONVENTIONS
112
+ - file: vitest.config.ts
113
+ why: Test runner configuration
114
+ pattern: include: ['src/__tests__/**/*.test.ts'], globals: true
115
+
116
+ - file: package.json
117
+ lines: 34-35
118
+ why: Test scripts
119
+ command: npm test or npm run test:watch
120
+
121
+ # TYPES AND INTERFACES
122
+ - file: src/types/decorators.ts
123
+ why: TaskOptions interface definition
124
+ pattern: { name?: string; concurrent?: boolean }
125
+
126
+ - file: src/types/error.ts
127
+ why: WorkflowError interface for error validation
128
+ pattern: { message, original, workflowId, stack, state, logs }
129
+
130
+ - file: src/types/events.ts
131
+ why: WorkflowEvent types for event verification
132
+ pattern: Union type with error events
133
+
134
+ # HELPER PATTERNS FOR TEST WORKFLOWS
135
+ - file: src/__tests__/adversarial/edge-case.test.ts
136
+ lines: 146-167
137
+ why: Example of creating child workflow classes for testing
138
+ pattern: class ChildWorkflow extends Workflow { async run() { ... } }
139
+ ```
140
+
141
+ ### Current Codebase Tree
142
+
143
+ ```bash
144
+ /home/dustin/projects/groundswell
145
+ ├── src/
146
+ │ ├── decorators/
147
+ │ │ ├── index.ts
148
+ │ │ ├── step.ts
149
+ │ │ └── task.ts # Promise.allSettled implementation (line 112)
150
+ │ ├── types/
151
+ │ │ ├── index.ts
152
+ │ │ ├── decorators.ts # TaskOptions interface
153
+ │ │ ├── error.ts # WorkflowError interface
154
+ │ │ └── events.ts # WorkflowEvent types
155
+ │ └── __tests__/
156
+ │ ├── unit/
157
+ │ │ └── decorators.test.ts # Basic decorator tests
158
+ │ └── adversarial/
159
+ │ ├── edge-case.test.ts # Concurrent execution tests (lines 366-430)
160
+ │ ├── observer-propagation.test.ts # Event verification patterns
161
+ │ ├── prd-compliance.test.ts
162
+ │ └── deep-hierarchy-stress.test.ts
163
+ ├── plan/
164
+ │ └── 001_d3bb02af4886/
165
+ │ └── bugfix/
166
+ │ └── 001_e8e04329daf3/
167
+ │ ├── P1M2T1S1/
168
+ │ │ └── PRP.md # S1 analysis PRP
169
+ │ ├── P1M2T1S2/
170
+ │ │ └── PRP.md # S2 implementation PRP
171
+ │ ├── P1M2T1S3/
172
+ │ │ ├── PRP.md # THIS FILE
173
+ │ │ └── research/
174
+ │ │ ├── vitest_concurrent_testing.md
175
+ │ │ └── concurrent_error_testing_patterns.md
176
+ │ └── architecture/
177
+ │ ├── promise_all_analysis.md
178
+ │ └── concurrent_execution_best_practices.md
179
+ └── vitest.config.ts
180
+ ```
181
+
182
+ ### Desired Codebase Tree (Changes for This Task)
183
+
184
+ ```bash
185
+ # NEW FILES:
186
+ src/__tests__/adversarial/concurrent-task-failures.test.ts # NEW: Test suite for concurrent failures
187
+
188
+ # NO MODIFICATIONS to existing files
189
+ # This task creates new tests only
190
+ ```
191
+
192
+ ### Known Gotchas of Our Codebase & Library Quirks
193
+
194
+ ```typescript
195
+ // CRITICAL GOTCHA #1: @Task decorator runs children BEFORE Promise.allSettled
196
+ // Lines 91-102 in task.ts: Children are attached before concurrent execution
197
+ // Failed workflows remain attached to parent even when they fail
198
+ // DO NOT expect failed children to be detached from parent
199
+
200
+ // CRITICAL GOTCHA #2: Promise.allSettled results maintain input ORDER
201
+ // Results are in input order, NOT completion order
202
+ // results[0] corresponds to first workflow in array, even if it completes last
203
+ // Use .filter() and .map() with indices for correlation
204
+
205
+ // CRITICAL GOTCHA #3: Type guards REQUIRED for PromiseSettledResult
206
+ // TypeScript doesn't narrow types without type guards
207
+ // BAD: results.filter(r => r.status === 'rejected').forEach(r => console.log(r.reason))
208
+ // Type error: Property 'reason' does not exist on type 'PromiseSettledResult<unknown>'
209
+ // GOOD: results.filter((r): r is PromiseRejectedResult => r.status === 'rejected')
210
+
211
+ // CRITICAL GOTCHA #4: Error events already emitted by @Step decorator
212
+ // Each failing workflow emits error event with full WorkflowError context
213
+ // DO NOT expect @Task decorator to emit additional error events
214
+ // DO verify each failing workflow's error event in tests
215
+
216
+ // CRITICAL GOTCHA #5: First error is thrown AFTER all workflows complete
217
+ // Promise.allSettled waits for ALL promises to settle
218
+ // Then first error is thrown for backward compatibility
219
+ // Tests must account for this delay (all workflows complete before throw)
220
+
221
+ // CRITICAL GOTCHA #6: WorkflowError.original is `unknown`, not `Error`
222
+ // When validating errors, don't assume Error interface
223
+ // BAD: expect(error.original.stack).toBeDefined()
224
+ // GOOD: if (error.original instanceof Error) expect(error.original.stack).toBeDefined()
225
+
226
+ // CRITICAL GOTCHA #7: Children run via @Task decorator
227
+ // Use @Task({ concurrent: true }) decorator in parent workflow
228
+ // Children are returned as array from @Task-decorated method
229
+ // Parent method: async spawnChildren() { return [child1, child2, child3]; }
230
+
231
+ // CRITICAL GOTCHA #8: Test file location matters
232
+ // Adversarial tests go in src/__tests__/adversarial/
233
+ // Test file must end in .test.ts for vitest to pick it up
234
+ // Use describe blocks for organization, it() for individual tests
235
+
236
+ // CRITICAL GOTCHA #9: Use @Task decorator for concurrent execution
237
+ // The Promise.allSettled is ONLY invoked when opts.concurrent is true
238
+ // Tests must use @Task({ concurrent: true }) to trigger the code path
239
+
240
+ // CRITICAL GOTCHA #10: Observer attachment only on root workflows
241
+ // Observers can only be added to root workflows (throws error if parent exists)
242
+ // In tests, add observer to parent workflow before running
243
+
244
+ // CRITICAL GOTCHA #11: No automatic timeout detection in tests
245
+ // Must manually add timeout to detect hanging promises
246
+ // Use Promise.race() with timeout promise for tests requiring timeout protection
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Implementation Blueprint
252
+
253
+ ### Data Models and Structure
254
+
255
+ **No new data models for this task** - tests use existing Workflow, Task, Step decorators and WorkflowError interface.
256
+
257
+ **Test Helper Functions** (defined inline in test file):
258
+
259
+ ```typescript
260
+ // Helper to create a child workflow that may fail
261
+ function createChildWorkflow(
262
+ parent: Workflow,
263
+ name: string,
264
+ shouldFail: boolean = false
265
+ ): Workflow;
266
+
267
+ // Helper to setup event observer for event collection
268
+ function setupEventObserver(workflow: Workflow): WorkflowEvent[];
269
+
270
+ // Helper to track workflow completions
271
+ function createCompletionTracker(): {
272
+ complete: (id: string) => void;
273
+ fail: (id: string) => void;
274
+ assertAllComplete: () => void;
275
+ };
276
+ ```
277
+
278
+ ### Implementation Tasks (ordered by dependencies)
279
+
280
+ ```yaml
281
+ Task 1: CREATE src/__tests__/adversarial/concurrent-task-failures.test.ts
282
+ - IMPLEMENT: Test file with imports and basic describe structure
283
+ - FOLLOW pattern: src/__tests__/adversarial/edge-case.test.ts (file structure, imports)
284
+ - NAMING: concurrent-task-failures.test.ts (snake_case, descriptive)
285
+ - PLACEMENT: src/__tests__/adversarial/ directory
286
+ - IMPORTS: Workflow, Task, Step from '../../index.js'; expect, describe, it from 'vitest'
287
+
288
+ Task 2: IMPLEMENT helper functions for test workflows
289
+ - IMPLEMENT: createChildWorkflow(parent, name, shouldFail) helper
290
+ - IMPLEMENT: setupEventObserver(workflow) helper
291
+ - IMPLEMENT: createCompletionTracker() helper
292
+ - FOLLOW pattern: src/__tests__/adversarial/edge-case.test.ts (workflow creation)
293
+ - DEPENDENCIES: Task 1
294
+
295
+ Task 3: IMPLEMENT "Single child failure" test suite
296
+ - IMPLEMENT: describe('Single child failure scenarios') suite
297
+ - TEST: should complete all siblings when one child fails
298
+ - VERIFY: All 4 children complete, exactly 1 failure, error message preserved
299
+ - DEPENDENCIES: Task 2
300
+
301
+ Task 4: IMPLEMENT "Multiple concurrent failures" test suite
302
+ - IMPLEMENT: describe('Multiple concurrent failures') suite
303
+ - TEST: should collect all errors from multiple failing children
304
+ - TEST: should preserve error context for each failure
305
+ - VERIFY: Correct failure count, all errors distinct, error context preserved
306
+ - DEPENDENCIES: Task 2
307
+
308
+ Task 5: IMPLEMENT "Mixed success/failure" test suite
309
+ - IMPLEMENT: describe('Mixed success/failure scenarios') suite
310
+ - TEST: should complete successful workflows despite failures
311
+ - TEST: should ensure no orphaned workflows in mixed scenario
312
+ - VERIFY: Successful workflows complete, all workflows accounted for
313
+ - DEPENDENCIES: Task 2
314
+
315
+ Task 6: IMPLEMENT "All children failing" test suite
316
+ - IMPLEMENT: describe('All children failing') suite
317
+ - TEST: should handle edge case of all children failing
318
+ - VERIFY: All children failed, no successes, all errors collected
319
+ - DEPENDENCIES: Task 2
320
+
321
+ Task 7: IMPLEMENT "Event emission verification" test suite
322
+ - IMPLEMENT: describe('Event emission during concurrent failures') suite
323
+ - TEST: should emit error events for all failing workflows
324
+ - TEST: should capture logs from both successful and failed workflows
325
+ - VERIFY: Error events emitted, logs captured from all workflows
326
+ - DEPENDENCIES: Task 2
327
+
328
+ Task 8: IMPLEMENT "No orphaned workflows" test suite
329
+ - IMPLEMENT: describe('No orphaned workflows') suite
330
+ - TEST: should verify all workflows complete with no hanging promises
331
+ - INCLUDE: Timeout protection (Promise.race with 5s timeout)
332
+ - VERIFY: All workflows accounted for, no pending promises
333
+ - DEPENDENCIES: Task 2
334
+
335
+ Task 9: RUN test suite to verify all tests pass
336
+ - RUN: npm test -- src/__tests__/adversarial/concurrent-task-failures.test.ts
337
+ - VERIFY: All tests pass
338
+ - VERIFY: Tests validate Promise.allSettled implementation
339
+ - DEPENDENCIES: Tasks 1-8
340
+
341
+ Task 10: RUN full test suite to ensure no regressions
342
+ - RUN: npm test
343
+ - VERIFY: All existing tests still pass
344
+ - VERIFY: No new tests break existing functionality
345
+ - DEPENDENCIES: Task 9
346
+ ```
347
+
348
+ ### Implementation Patterns & Key Details
349
+
350
+ ```typescript
351
+ // ============================================
352
+ // PATTERN 1: Test File Structure
353
+ // Location: src/__tests__/adversarial/concurrent-task-failures.test.ts
354
+ // ============================================
355
+
356
+ import { describe, it, expect } from 'vitest';
357
+ import { Workflow, Task, Step } from '../../index.js';
358
+ import type { WorkflowEvent } from '../../types/index.js';
359
+
360
+ describe('@Task decorator concurrent failure scenarios', () => {
361
+ // Helper functions
362
+ function createChildWorkflow(parent: Workflow, name: string, shouldFail: boolean): Workflow {
363
+ return new (class extends Workflow {
364
+ constructor(name: string, parent: Workflow) {
365
+ super(name, parent);
366
+ }
367
+
368
+ @Step()
369
+ async executeStep() {
370
+ if (shouldFail) {
371
+ throw new Error(`${name} failed`);
372
+ }
373
+ return `${name} succeeded`;
374
+ }
375
+
376
+ async run() {
377
+ return this.executeStep();
378
+ }
379
+ })(name, parent);
380
+ }
381
+
382
+ // Test suites...
383
+ });
384
+
385
+ // ============================================
386
+ // PATTERN 2: Single Child Failure Test
387
+ // Location: Test suite for single failure scenarios
388
+ // ============================================
389
+
390
+ it('should complete all siblings when one child fails', async () => {
391
+ // ARRANGE: Create parent with 4 children, child[1] will fail
392
+ class ParentWorkflow extends Workflow {
393
+ @Task({ concurrent: true })
394
+ async spawnChildren() {
395
+ return [
396
+ createChildWorkflow(this, 'Child-0', false),
397
+ createChildWorkflow(this, 'Child-1', true), // Will fail
398
+ createChildWorkflow(this, 'Child-2', false),
399
+ createChildWorkflow(this, 'Child-3', false),
400
+ ];
401
+ }
402
+
403
+ async run() {
404
+ try {
405
+ await this.spawnChildren();
406
+ } catch (err) {
407
+ // Expected - first error thrown after all complete
408
+ }
409
+ }
410
+ }
411
+
412
+ const parent = new ParentWorkflow('Parent');
413
+
414
+ // ACT: Run parent (children run concurrently)
415
+ await parent.run();
416
+
417
+ // ASSERT: All 4 children attached
418
+ expect(parent.children.length).toBe(4);
419
+
420
+ // ASSERT: Verify child statuses
421
+ const failedCount = parent.children.filter(c => c.status === 'failed').length;
422
+ const completedCount = parent.children.filter(c => c.status === 'completed').length;
423
+
424
+ expect(failedCount).toBe(1);
425
+ expect(completedCount).toBe(3);
426
+ });
427
+
428
+ // KEY INSIGHTS:
429
+ // - @Task({ concurrent: true }) triggers Promise.allSettled code path
430
+ // - All children complete regardless of individual failures
431
+ // - Failed children remain attached to parent
432
+ // - Status can be checked via workflow.status property
433
+
434
+ // ============================================
435
+ // PATTERN 3: Multiple Concurrent Failures Test
436
+ // Location: Test suite for multiple failure scenarios
437
+ // ============================================
438
+
439
+ it('should collect all errors when multiple children fail concurrently', async () => {
440
+ // ARRANGE: Create parent with 6 children, 3 will fail
441
+ class ParentWorkflow extends Workflow {
442
+ @Task({ concurrent: true })
443
+ async spawnChildren() {
444
+ return [
445
+ createChildWorkflow(this, 'Alpha', false),
446
+ createChildWorkflow(this, 'Beta', true), // Will fail
447
+ createChildWorkflow(this, 'Gamma', false),
448
+ createChildWorkflow(this, 'Delta', true), // Will fail
449
+ createChildWorkflow(this, 'Epsilon', false),
450
+ createChildWorkflow(this, 'Zeta', true), // Will fail
451
+ ];
452
+ }
453
+
454
+ async run() {
455
+ try {
456
+ await this.spawnChildren();
457
+ } catch (err) {
458
+ // Expected
459
+ }
460
+ }
461
+ }
462
+
463
+ const parent = new ParentWorkflow('Parent');
464
+
465
+ // ACT
466
+ await parent.run();
467
+
468
+ // ASSERT: Exactly 3 failures, 3 successes
469
+ const failed = parent.children.filter(c => c.status === 'failed');
470
+ const completed = parent.children.filter(c => c.status === 'completed');
471
+
472
+ expect(failed.length).toBe(3);
473
+ expect(completed.length).toBe(3);
474
+
475
+ // ASSERT: All errors distinct
476
+ const failedNames = failed.map(c => c.node.name);
477
+ expect(new Set(failedNames).size).toBe(3);
478
+ expect(failedNames).toContain('Beta');
479
+ expect(failedNames).toContain('Delta');
480
+ expect(failedNames).toContain('Zeta');
481
+ });
482
+
483
+ // ============================================
484
+ // PATTERN 4: Event Emission Verification
485
+ // Location: Test suite for event emission during failures
486
+ // ============================================
487
+
488
+ it('should emit error events for all failing workflows', async () => {
489
+ // ARRANGE: Setup event observer
490
+ class ParentWorkflow extends Workflow {
491
+ @Task({ concurrent: true })
492
+ async spawnChildren() {
493
+ return [
494
+ createChildWorkflow(this, 'Good', false),
495
+ createChildWorkflow(this, 'Bad1', true),
496
+ createChildWorkflow(this, 'Bad2', true),
497
+ ];
498
+ }
499
+
500
+ async run() {
501
+ try {
502
+ await this.spawnChildren();
503
+ } catch (err) {
504
+ // Expected
505
+ }
506
+ }
507
+ }
508
+
509
+ const parent = new ParentWorkflow('Parent');
510
+ const events: WorkflowEvent[] = [];
511
+
512
+ // CRITICAL: Add observer to root workflow
513
+ parent.addObserver({
514
+ onLog: () => {},
515
+ onEvent: (e) => events.push(e),
516
+ onStateUpdated: () => {},
517
+ onTreeChanged: () => {},
518
+ });
519
+
520
+ // ACT
521
+ await parent.run();
522
+
523
+ // ASSERT: Error events emitted for both failures
524
+ const errorEvents = events.filter(e => e.type === 'error');
525
+ expect(errorEvents.length).toBeGreaterThanOrEqual(2);
526
+
527
+ // ASSERT: Each error event has correct structure
528
+ errorEvents.forEach(event => {
529
+ expect(event.type).toBe('error');
530
+ if (event.type === 'error') {
531
+ expect(event.error).toBeDefined();
532
+ expect(event.error.workflowId).toBeDefined();
533
+ expect(event.error.message).toBeDefined();
534
+ expect(Array.isArray(event.error.logs)).toBe(true);
535
+ }
536
+ });
537
+ });
538
+
539
+ // ============================================
540
+ // PATTERN 5: No Orphaned Workflows Test
541
+ // Location: Test suite for completion verification
542
+ // ============================================
543
+
544
+ it('should verify all workflows complete with no hanging promises', async () => {
545
+ // ARRANGE: Track all completions
546
+ const completedWorkflows = new Set<string>();
547
+
548
+ class ParentWorkflow extends Workflow {
549
+ @Task({ concurrent: true })
550
+ async spawnChildren() {
551
+ const children = Array.from({ length: 10 }, (_, i) =>
552
+ createChildWorkflow(this, `Child-${i}`, Math.random() < 0.3)
553
+ );
554
+
555
+ // Track completion for all children
556
+ children.forEach(child => {
557
+ child.run().then(
558
+ () => completedWorkflows.add(child.id),
559
+ () => completedWorkflows.add(child.id)
560
+ );
561
+ });
562
+
563
+ return children;
564
+ }
565
+
566
+ async run() {
567
+ try {
568
+ await this.spawnChildren();
569
+ } catch (err) {
570
+ // Expected
571
+ }
572
+ }
573
+ }
574
+
575
+ const parent = new ParentWorkflow('Parent');
576
+
577
+ // ACT: Run with timeout to detect hanging promises
578
+ const timeoutPromise = new Promise((_, reject) =>
579
+ setTimeout(() => reject(new Error('Timeout: workflows hung')), 5000)
580
+ );
581
+
582
+ const runPromise = parent.run();
583
+
584
+ await Promise.race([runPromise, timeoutPromise]);
585
+
586
+ // ASSERT: All 10 workflows accounted for (no orphans)
587
+ expect(completedWorkflows.size).toBe(10);
588
+ });
589
+
590
+ // KEY INSIGHTS:
591
+ // - Timeout protection ensures test fails if promises hang
592
+ // - Completion tracking verifies all workflows finish
593
+ // - Promise.race prevents infinite test execution
594
+
595
+ // ============================================
596
+ // PATTERN 6: All Children Failing Edge Case
597
+ // Location: Test suite for all-failures scenario
598
+ // ============================================
599
+
600
+ it('should handle edge case of all children failing', async () => {
601
+ // ARRANGE: All children will fail
602
+ class ParentWorkflow extends Workflow {
603
+ @Task({ concurrent: true })
604
+ async spawnChildren() {
605
+ return Array.from({ length: 5 }, (_, i) =>
606
+ createChildWorkflow(this, `FailChild-${i}`, true) // All fail
607
+ );
608
+ }
609
+
610
+ async run() {
611
+ try {
612
+ await this.spawnChildren();
613
+ } catch (err) {
614
+ // Expected - first error thrown
615
+ }
616
+ }
617
+ }
618
+
619
+ const parent = new ParentWorkflow('Parent');
620
+
621
+ // ACT
622
+ await parent.run();
623
+
624
+ // ASSERT: All children failed
625
+ expect(parent.children.length).toBe(5);
626
+
627
+ const allFailed = parent.children.every(c => c.status === 'failed');
628
+ expect(allFailed).toBe(true);
629
+
630
+ // ASSERT: No successes
631
+ const completedCount = parent.children.filter(c => c.status === 'completed').length;
632
+ expect(completedCount).toBe(0);
633
+ });
634
+
635
+ // ============================================
636
+ // PATTERN 7: Type Guard for PromiseRejectedResult
637
+ // Location: Helper functions in test file
638
+ // ============================================
639
+
640
+ // Type guard for filtering rejected promises
641
+ function isRejected(result: PromiseSettledResult<unknown>): result is PromiseRejectedResult {
642
+ return result.status === 'rejected';
643
+ }
644
+
645
+ // Usage in tests (if directly testing Promise.allSettled):
646
+ const results = await Promise.allSettled(workflows.map(w => w.run()));
647
+ const rejected = results.filter(isRejected);
648
+ expect(rejected.length).toBe(expectedFailureCount);
649
+ ```
650
+
651
+ ### Integration Points
652
+
653
+ ```yaml
654
+ NO_INTEGRATION_CHANGES:
655
+ - This task creates new tests only
656
+ - No modifications to existing code
657
+ - Tests verify existing Promise.allSettled implementation from S2
658
+
659
+ TEST_DEPENDENCIES:
660
+ - Requires S2 implementation to be complete (Promise.allSettled in task.ts)
661
+ - Tests will validate the S2 implementation works correctly
662
+ - Run after S2 is complete and all tests pass
663
+ ```
664
+
665
+ ---
666
+
667
+ ## Validation Loop
668
+
669
+ ### Level 1: Syntax & Style (Immediate Feedback)
670
+
671
+ ```bash
672
+ # Run TypeScript type checking on new test file
673
+ npx tsc --noEmit src/__tests__/adversarial/concurrent-task-failures.test.ts
674
+
675
+ # Run vitest type checking
676
+ npx vitest type-check src/__tests__/adversarial/concurrent-task-failures.test.ts
677
+
678
+ # Expected: Zero type errors
679
+ # Common error to fix: Missing imports, incorrect type annotations
680
+ ```
681
+
682
+ ### Level 2: Unit Tests (Component Validation)
683
+
684
+ ```bash
685
+ # Run the new test file
686
+ npm test -- src/__tests__/adversarial/concurrent-task-failures.test.ts
687
+
688
+ # Run with watch mode for development
689
+ npm run test:watch -- concurrent-task-failures
690
+
691
+ # Run with coverage
692
+ npm test -- --coverage src/__tests__/adversarial/concurrent-task-failures.test.ts
693
+
694
+ # Expected: All new tests pass
695
+ # If tests fail, debug - they should validate Promise.allSettled behavior
696
+ ```
697
+
698
+ ### Level 3: Integration Testing (System Validation)
699
+
700
+ ```bash
701
+ # Run all adversarial tests
702
+ npm test -- src/__tests__/adversarial/
703
+
704
+ # Run all unit tests
705
+ npm test -- src/__tests__/unit/
706
+
707
+ # Run full test suite
708
+ npm test
709
+
710
+ # Expected: All tests pass, including existing tests
711
+ # This validates no regressions and new tests integrate correctly
712
+ ```
713
+
714
+ ### Level 4: Manual Verification
715
+
716
+ ```bash
717
+ # Verify test file exists and is properly formatted
718
+ ls -la src/__tests__/adversarial/concurrent-task-failures.test.ts
719
+
720
+ # Count tests in file
721
+ grep -c "^ it(" src/__tests__/adversarial/concurrent-task-failures.test.ts
722
+
723
+ # Expected: File exists with 8-10 tests covering all scenarios
724
+
725
+ # Verify test output includes helpful messages
726
+ npm test -- src/__tests__/adversarial/concurrent-task-failures.test.ts --reporter=verbose
727
+
728
+ # Expected: Clear test names showing what is being tested
729
+ ```
730
+
731
+ ---
732
+
733
+ ## Final Validation Checklist
734
+
735
+ ### Technical Validation
736
+
737
+ - [ ] Test file created at `src/__tests__/adversarial/concurrent-task-failures.test.ts`
738
+ - [ ] All imports correct (Workflow, Task, Step, vitest functions)
739
+ - [ ] No TypeScript errors: `npx tsc --noEmit` passes
740
+ - [ ] All tests pass: `npm test -- concurrent-task-failures.test.ts`
741
+ - [ ] Test file follows existing patterns from edge-case.test.ts
742
+ - [ ] Helper functions defined and used correctly
743
+
744
+ ### Feature Validation
745
+
746
+ - [ ] Single child failure test: All siblings complete when one fails
747
+ - [ ] Multiple failures test: All errors collected correctly
748
+ - [ ] Mixed success/failure test: Successful workflows complete
749
+ - [ ] All children failing test: Edge case handled
750
+ - [ ] No orphaned workflows test: All workflows accounted for
751
+ - [ ] Event emission test: Error events emitted for failures
752
+ - [ ] Log capture test: Logs captured from all workflows
753
+
754
+ ### Code Quality Validation
755
+
756
+ - [ ] Test names descriptive (should/shouldn't pattern)
757
+ - [ ] AAA pattern followed (Arrange, Act, Assert)
758
+ - [ ] Comments explain complex test scenarios
759
+ - [ ] No hardcoded timeouts except for protection
760
+ - [ ] Error messages specific and helpful
761
+ - [ ] Follows Groundswell test conventions
762
+
763
+ ### Documentation & Completeness
764
+
765
+ - [ ] All required test scenarios covered
766
+ - [ ] Tests validate Promise.allSettled implementation from S2
767
+ - [ ] No orphaned or hanging promises in any test
768
+ - [ ] Timeout protection in tests that could hang
769
+ - [ ] Event verification for error scenarios
770
+ - [ ] Completion verification for all scenarios
771
+
772
+ ---
773
+
774
+ ## Anti-Patterns to Avoid
775
+
776
+ - ❌ **Don't modify existing code** - This task creates tests only
777
+ - ❌ **Don't use Promise.all in tests** - Use @Task decorator to test the implementation
778
+ - ❌ **Don't forget type guards** - TypeScript requires them for PromiseSettledResult
779
+ - ❌ **Don't skip timeout protection** - Tests that could hang need timeout
780
+ - ❌ **Don't assume error type** - Error.original is unknown, check with instanceof
781
+ - ❌ **Don't test @Task without concurrent: true** - Must trigger concurrent code path
782
+ - ❌ **Don't expect failed children to detach** - Failed children remain attached
783
+ - ❌ **Don't ignore event emission** - Verify error events are emitted
784
+ - ❌ **Don't hardcode workflow IDs** - Use workflow.id or workflow.node.name
785
+ - ❌ **Don't use sync assertions after async** - Always await before asserting
786
+ - ❌ **Don't create test file in wrong location** - Must be in src/__tests__/adversarial/
787
+ - ❌ **Don't use .test.js extension** - Must be .test.ts for TypeScript
788
+ - ❌ **Don't forget to add observers to root** - Observers only on root workflows
789
+ - ❌ **Don't assume completion order** - Promise.allSettled maintains input order, not completion order
790
+ - ❌ **Don't create unnecessary abstractions** - Keep test helpers simple and focused
791
+
792
+ ---
793
+
794
+ ## Success Metrics
795
+
796
+ **Confidence Score**: 10/10 for one-pass implementation success
797
+
798
+ **Definition of Done**:
799
+ 1. Test file created at `src/__tests__/adversarial/concurrent-task-failures.test.ts`
800
+ 2. All tests pass validating Promise.allSettled implementation from S2
801
+ 3. Single child failure scenario tested and passing
802
+ 4. Multiple concurrent failures scenario tested and passing
803
+ 5. Mixed success/failure scenario tested and passing
804
+ 6. All children failing scenario tested and passing
805
+ 7. No orphaned workflows verified in all tests
806
+ 8. Event emission verified for concurrent failures
807
+ 9. Zero TypeScript errors
808
+ 10. All existing tests still pass (no regressions)
809
+
810
+ **Validation**: The test suite provides comprehensive coverage of concurrent task failure scenarios, ensuring the Promise.allSettled implementation works correctly and all workflows complete regardless of individual failures.
811
+
812
+ ---
813
+
814
+ ## Appendix: Complete Test File Template
815
+
816
+ ```typescript
817
+ /**
818
+ * Concurrent Task Failure Scenarios Test Suite
819
+ *
820
+ * Tests the Promise.allSettled implementation in @Task decorator
821
+ * for concurrent execution with various failure scenarios.
822
+ *
823
+ * Validates:
824
+ * - Single child failure in concurrent batch
825
+ * - Multiple children failing concurrently
826
+ * - Mixed success/failure scenarios
827
+ * - All children failing edge case
828
+ * - No orphaned or hanging promises
829
+ * - Error collection correctness
830
+ * - Event emission during failures
831
+ */
832
+
833
+ import { describe, it, expect } from 'vitest';
834
+ import { Workflow, Task, Step } from '../../index.js';
835
+ import type { WorkflowEvent } from '../../types/index.js';
836
+
837
+ describe('@Task decorator concurrent failure scenarios', () => {
838
+ /**
839
+ * Helper to create a child workflow that may fail
840
+ */
841
+ function createChildWorkflow(
842
+ parent: Workflow,
843
+ name: string,
844
+ shouldFail: boolean = false
845
+ ): Workflow {
846
+ return new (class extends Workflow {
847
+ constructor(n: string, p: Workflow) {
848
+ super(n, p);
849
+ }
850
+
851
+ @Step()
852
+ async executeStep() {
853
+ if (shouldFail) {
854
+ throw new Error(`${name} failed`);
855
+ }
856
+ return `${name} succeeded`;
857
+ }
858
+
859
+ async run() {
860
+ return this.executeStep();
861
+ }
862
+ })(name, parent);
863
+ }
864
+
865
+ /**
866
+ * Helper to setup event observer
867
+ */
868
+ function setupEventObserver(workflow: Workflow): WorkflowEvent[] {
869
+ const events: WorkflowEvent[] = [];
870
+ workflow.addObserver({
871
+ onLog: () => {},
872
+ onEvent: (e) => events.push(e),
873
+ onStateUpdated: () => {},
874
+ onTreeChanged: () => {},
875
+ });
876
+ return events;
877
+ }
878
+
879
+ describe('Single child failure scenarios', () => {
880
+ it('should complete all siblings when one child fails', async () => {
881
+ // Test implementation...
882
+ });
883
+ });
884
+
885
+ describe('Multiple concurrent failures', () => {
886
+ it('should collect all errors when multiple children fail concurrently', async () => {
887
+ // Test implementation...
888
+ });
889
+
890
+ it('should preserve error context for each failure', async () => {
891
+ // Test implementation...
892
+ });
893
+ });
894
+
895
+ describe('Mixed success/failure scenarios', () => {
896
+ it('should complete successful workflows despite failures', async () => {
897
+ // Test implementation...
898
+ });
899
+
900
+ it('should ensure no orphaned workflows in mixed scenario', async () => {
901
+ // Test implementation...
902
+ });
903
+ });
904
+
905
+ describe('All children failing', () => {
906
+ it('should handle edge case of all children failing', async () => {
907
+ // Test implementation...
908
+ });
909
+ });
910
+
911
+ describe('No orphaned workflows', () => {
912
+ it('should verify all workflows complete with no hanging promises', async () => {
913
+ // Test implementation...
914
+ });
915
+ });
916
+
917
+ describe('Event emission verification', () => {
918
+ it('should emit error events for all failing workflows', async () => {
919
+ // Test implementation...
920
+ });
921
+
922
+ it('should capture logs from both successful and failed workflows', async () => {
923
+ // Test implementation...
924
+ });
925
+ });
926
+ });
927
+ ```
928
+
929
+ ---
930
+
931
+ **PRP Status**: ✅ Complete - Ready for Implementation
932
+ **Next Task**: P1.M2.T1.S4 - Run full test suite to ensure no regressions