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,741 @@
1
+ # Promise.all Implementation Analysis for @Task Decorator
2
+
3
+ **Document Version:** 1.0
4
+ **Analysis Date:** 2026-01-12
5
+ **Target Implementation Task:** P1.M2.T1.S2 (Promise.allSettled Migration)
6
+ **Primary File:** `src/decorators/task.ts` (lines 104-114)
7
+
8
+ ---
9
+
10
+ ## 1. Current Implementation Overview
11
+
12
+ ### 1.1 Promise.all Execution Code
13
+
14
+ **Location:** `src/decorators/task.ts:104-114`
15
+
16
+ ```typescript
17
+ // If concurrent option is set and we have multiple workflows, run them in parallel
18
+ if (opts.concurrent && Array.isArray(result)) {
19
+ const runnable = workflows.filter(
20
+ (w): w is WorkflowClass =>
21
+ w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
22
+ );
23
+
24
+ if (runnable.length > 0) {
25
+ await Promise.all(runnable.map((w) => w.run())); // ← CRITICAL: Line 112
26
+ }
27
+ }
28
+ ```
29
+
30
+ ### 1.2 Context: Full @Task Decorator Structure
31
+
32
+ **Location:** `src/decorators/task.ts:1-129`
33
+
34
+ The @Task decorator performs three main operations:
35
+
36
+ 1. **Child Attachment** (lines 91-102): Attaches returned workflows as children
37
+ 2. **Concurrent Execution** (lines 104-114): Runs workflows in parallel when `concurrent: true`
38
+ 3. **Event Emission** (lines 79-83, 117-121): Emits taskStart/taskEnd events
39
+
40
+ **CRITICAL:** Child attachment happens BEFORE concurrent execution, establishing parent-child relationships regardless of execution success.
41
+
42
+ ### 1.3 Local Type Definitions
43
+
44
+ **Location:** `src/decorators/task.ts:4-16`
45
+
46
+ ```typescript
47
+ // Type for workflow-like objects
48
+ interface WorkflowLike {
49
+ id: string;
50
+ node: WorkflowNode;
51
+ emitEvent(event: WorkflowEvent): void;
52
+ attachChild(child: WorkflowLike): void;
53
+ }
54
+
55
+ // Minimal Workflow type for checking if something is a workflow
56
+ interface WorkflowClass {
57
+ id: string;
58
+ parent: WorkflowLike | null;
59
+ run(...args: unknown[]): Promise<unknown>;
60
+ }
61
+ ```
62
+
63
+ **NOTE:** These are local to the task.ts file - not exported from the types module.
64
+
65
+ ---
66
+
67
+ ## 2. Runnable Workflow Filtering Logic
68
+
69
+ ### 2.1 Type Guard Implementation
70
+
71
+ **Location:** `src/decorators/task.ts:106-109`
72
+
73
+ ```typescript
74
+ const runnable = workflows.filter(
75
+ (w): w is WorkflowClass =>
76
+ w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
77
+ );
78
+ ```
79
+
80
+ ### 2.2 Type Predicate Explanation
81
+
82
+ The `(w): w is WorkflowClass` syntax is a **TypeScript Type Predicate** (Type Guard):
83
+
84
+ | Check | Purpose |
85
+ |-------|---------|
86
+ | `w` | Truthiness check - filters out null/undefined |
87
+ | `typeof w === 'object'` | Ensures w is an object (not string, number, etc.) |
88
+ | `'run' in w` | Checks if 'run' property exists on object |
89
+ | `typeof w.run === 'function'` | Verifies run is callable |
90
+
91
+ ### 2.3 What Gets Included/Excluded
92
+
93
+ **Included in runnable:**
94
+ - Workflow instances (with `run()` method)
95
+ - Plain objects with a `run()` method (duck typing)
96
+ - Workflow-like objects satisfying the type guard
97
+
98
+ **Excluded from runnable:**
99
+ - `null` and `undefined`
100
+ - Primitive values (strings, numbers, booleans)
101
+ - Objects without a `run()` method
102
+ - Objects with `run` property that isn't a function
103
+
104
+ ### 2.4 Critical Gotchas
105
+
106
+ **Gotcha #1: No duplicate prevention**
107
+ - The filter does NOT check if a workflow is already running
108
+ - Same workflow instance could theoretically be executed twice
109
+ - Relies on user code to not return duplicates
110
+
111
+ **Gotcha #2: No running state check**
112
+ - Does NOT verify workflow's current execution status
113
+ - Would attempt to run an already-running workflow if present
114
+ - No safeguard against race conditions in user code
115
+
116
+ **Gotcha #3: Non-workflow return values silently skipped**
117
+ - Worksflows are filtered out without warning
118
+ - Original return value is preserved (line 123)
119
+ - Lenient validation allows flexible signatures
120
+
121
+ ---
122
+
123
+ ## 3. Error Propagation Flow (Step-by-Step)
124
+
125
+ ### 3.1 Complete Error Flow Diagram
126
+
127
+ ```
128
+ ┌─────────────────────────────────────────────────────────────────────────────┐
129
+ │ ERROR PROPAGATION FLOW │
130
+ ├─────────────────────────────────────────────────────────────────────────────┤
131
+ │ │
132
+ │ 1. @Step Method Throws Error │
133
+ │ ↓ │
134
+ │ Location: Any @Step decorated method │
135
+ │ Action: Method throws Error or rejects Promise │
136
+ │ │
137
+ │ 2. @Step Decorator Catch Block │
138
+ │ ↓ │
139
+ │ Location: src/decorators/step.ts:109-134 │
140
+ │ Action: │
141
+ │ - Captures error state via getObservedState(this) │
142
+ │ - Creates WorkflowError object with full context: │
143
+ │ * message: error?.message ?? 'Unknown error' │
144
+ │ * original: err (preserves original thrown error) │
145
+ │ * workflowId: wf.id │
146
+ │ * stack: error?.stack │
147
+ │ * state: snap (observed state snapshot) │
148
+ │ * logs: [...wf.node.logs] (copies current logs) │
149
+ │ - Emits error event: { type: 'error', node: wf.node, error: ... } │
150
+ │ - Re-throws WorkflowError │
151
+ │ │
152
+ │ 3. Workflow.run() Method │
153
+ │ ↓ │
154
+ │ Location: src/core/workflow.ts │
155
+ │ Action: Error propagates naturally through call stack │
156
+ │ NOTE: No automatic catching in run() - error passes through │
157
+ │ │
158
+ │ 4. Promise.all in @Task Decorator │
159
+ │ ↓ │
160
+ │ Location: src/decorators/task.ts:112 │
161
+ │ Action: │
162
+ │ - await Promise.all(runnable.map((w) => w.run())) │
163
+ │ - FIRST ERROR WINS - immediately rejects on first rejection │
164
+ │ - Other in-flight promises continue but results are LOST │
165
+ │ - Parent workflow only receives FIRST error │
166
+ │ │
167
+ │ 5. Workflow.runFunctional() Error Handler │
168
+ │ ↓ │
169
+ │ Location: src/core/workflow.ts:470-488 │
170
+ │ Action: │
171
+ │ - Catches error in functional workflow executor │
172
+ │ - Sets status to 'failed' │
173
+ │ - Emits error event with WorkflowError context │
174
+ │ - Re-throws original error │
175
+ │ │
176
+ │ 6. Parent Workflow or Root Handler │
177
+ │ ↓ │
178
+ │ Action: │
179
+ │ - Parent may catch for custom handling │
180
+ │ - Otherwise propagates to root │
181
+ │ - Application-level error handling takes over │
182
+ │ │
183
+ └─────────────────────────────────────────────────────────────────────────────┘
184
+ ```
185
+
186
+ ### 3.2 WorkflowError Interface Structure
187
+
188
+ **Location:** `src/types/error.ts:7-20`
189
+
190
+ ```typescript
191
+ export interface WorkflowError {
192
+ message: string; // Error message from thrown error
193
+ original: unknown; // Original thrown error (preserved)
194
+ workflowId: string; // ID of workflow where error occurred
195
+ stack?: string; // Stack trace if available
196
+ state: SerializedWorkflowState; // State snapshot at error time
197
+ logs: LogEntry[]; // Logs from the failing workflow node
198
+ }
199
+ ```
200
+
201
+ **Key Characteristic:** Interface-based (not a class), allowing flexible error object creation while ensuring complete context capture.
202
+
203
+ ### 3.3 Error Context Capture Points
204
+
205
+ | Context | Where Captured | How |
206
+ |---------|----------------|-----|
207
+ | Error message | step.ts:117 | `error?.message ?? 'Unknown error'` |
208
+ | Original error | step.ts:118 | Preserved as `original: err` |
209
+ | Workflow ID | step.ts:119 | `wf.id` from workflow instance |
210
+ | Stack trace | step.ts:120 | `error?.stack` if Error instance |
211
+ | State snapshot | step.ts:114, 121 | `getObservedState(this as object)` |
212
+ | Logs | step.ts:122 | `[...wf.node.logs]` (copied) |
213
+
214
+ ---
215
+
216
+ ## 4. Concurrent Failure Behavior Analysis
217
+
218
+ ### 4.1 What Happens When ONE Concurrent Workflow Fails
219
+
220
+ **Scenario:** Two concurrent workflows, one fails
221
+
222
+ ```typescript
223
+ class GoodChild extends Workflow {
224
+ async run() {
225
+ return 'good'; // Succeeds
226
+ }
227
+ }
228
+
229
+ class BadChild extends Workflow {
230
+ @Step()
231
+ async run() {
232
+ throw new Error('Bad child error'); // Fails
233
+ }
234
+ }
235
+
236
+ class ParentWorkflow extends Workflow {
237
+ @Task({ concurrent: true })
238
+ async spawnMixed() {
239
+ return [
240
+ new GoodChild('Good', this),
241
+ new BadChild('Bad', this),
242
+ ];
243
+ }
244
+ }
245
+ ```
246
+
247
+ **Execution Timeline:**
248
+
249
+ ```
250
+ Time T0: Promise.all([
251
+ run(GoodChild) → Promise<pending>,
252
+ run(BadChild) → Promise<pending>
253
+ ])
254
+
255
+ Time T1: BadChild @Step throws error
256
+ → Wrapped as WorkflowError
257
+ → Promise.all REJECTS IMMEDIATELY
258
+ → GoodChild result LOST
259
+
260
+ Time T2: Parent receives WorkflowError from BadChild
261
+ → No knowledge of GoodChild result
262
+ → No knowledge that GoodChild succeeded
263
+ ```
264
+
265
+ ### 4.2 What Happens to OTHER Concurrent Workflows
266
+
267
+ **CRITICAL BEHAVIOR:** When one workflow fails:
268
+
269
+ 1. **Promise.all rejects immediately** - No waiting for other promises
270
+ 2. **In-flight workflows continue executing** - They're not cancelled
271
+ 3. **Results from other workflows are LOST** - Never captured
272
+ 4. **Parent only sees first error** - No error aggregation
273
+
274
+ ### 4.3 Can Parent See ALL Errors?
275
+
276
+ **Answer:** NO - Parent only sees the FIRST error that causes Promise.all to reject.
277
+
278
+ **Evidence from test code:**
279
+
280
+ **Location:** `src/__tests__/adversarial/edge-case.test.ts:366-403`
281
+
282
+ ```typescript
283
+ it('should handle concurrent task execution with errors', async () => {
284
+ // Test shows mixed success/failure in concurrent execution
285
+ // Both children are attached (line 402: expect(workflow.children.length).toBe(2))
286
+ // But error handling only catches first error
287
+ });
288
+ ```
289
+
290
+ ### 4.4 Current Error Semantics
291
+
292
+ | Aspect | Behavior |
293
+ |--------|----------|
294
+ | Fail-fast | YES - Immediate rejection on first error |
295
+ | Error aggregation | NO - Only first error visible |
296
+ | Partial results | NO - Success results are lost |
297
+ | Error context | FULL - WorkflowError captures complete context |
298
+ | Race condition preservation | YES - Whichever error arrives first wins |
299
+
300
+ ---
301
+
302
+ ## 5. Promise.allSettled Migration Requirements
303
+
304
+ ### 5.1 Core Code Changes Required
305
+
306
+ #### Change 1: Replace Promise.all with Promise.allSettled
307
+
308
+ **Current (src/decorators/task.ts:112):**
309
+ ```typescript
310
+ await Promise.all(runnable.map((w) => w.run()));
311
+ ```
312
+
313
+ **Required:**
314
+ ```typescript
315
+ const results = await Promise.allSettled(runnable.map((w) => w.run()));
316
+ ```
317
+
318
+ #### Change 2: Add Error Strategy Configuration
319
+
320
+ **Location:** `src/types/decorators.ts` (TaskOptions interface)
321
+
322
+ **Current:**
323
+ ```typescript
324
+ export interface TaskOptions {
325
+ name?: string;
326
+ concurrent?: boolean;
327
+ }
328
+ ```
329
+
330
+ **Required:**
331
+ ```typescript
332
+ export interface TaskOptions {
333
+ name?: string;
334
+ concurrent?: boolean;
335
+ errorStrategy?: 'fail-fast' | 'complete-all'; // NEW
336
+ }
337
+ ```
338
+
339
+ **ALTERNATIVE:** Use existing ErrorMergeStrategy interface
340
+
341
+ ```typescript
342
+ export interface TaskOptions {
343
+ name?: string;
344
+ concurrent?: boolean;
345
+ errorMergeStrategy?: ErrorMergeStrategy; // Use existing type
346
+ }
347
+ ```
348
+
349
+ ### 5.2 Type Guard Requirements
350
+
351
+ **Need to create:** Type guards for PromiseSettledResult
352
+
353
+ **Location:** `src/utils/promise-utils.ts` (NEW FILE)
354
+
355
+ ```typescript
356
+ import type { WorkflowError } from '../types/error.js';
357
+
358
+ // Type guard for fulfilled results
359
+ export function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
360
+ return result.status === 'fulfilled';
361
+ }
362
+
363
+ // Type guard for rejected results
364
+ export function isRejected(result: PromiseSettledResult<unknown>): result is PromiseRejectedResult {
365
+ return result.status === 'rejected';
366
+ }
367
+
368
+ // Check if result is WorkflowError
369
+ export function isWorkflowError(error: unknown): error is WorkflowError {
370
+ return (
371
+ typeof error === 'object' &&
372
+ error !== null &&
373
+ 'message' in error &&
374
+ 'workflowId' in error &&
375
+ 'state' in error &&
376
+ 'logs' in error
377
+ );
378
+ }
379
+ ```
380
+
381
+ ### 5.3 Error Aggregation Pattern Requirements
382
+
383
+ **Required:** Logic to collect and process errors from Promise.allSettled results
384
+
385
+ ```typescript
386
+ // After Promise.allSettled, separate successes and failures
387
+ const errors = results
388
+ .filter((r): r is PromiseRejectedResult => r.status === 'rejected')
389
+ .map((r) => r.reason as WorkflowError);
390
+
391
+ // If there are errors and we're in complete-all mode
392
+ if (errors.length > 0 && opts.errorStrategy === 'complete-all') {
393
+ // Aggregate errors
394
+ const mergedError: WorkflowError = {
395
+ message: `${errors.length} concurrent workflows failed`,
396
+ original: errors.map(e => e.original),
397
+ workflowId: wf.id,
398
+ stack: errors.map(e => e.stack).filter(Boolean).join('\n---\n'),
399
+ state: getObservedState(this),
400
+ logs: errors.flatMap(e => e.logs),
401
+ };
402
+
403
+ // Emit aggregated error
404
+ wf.emitEvent({
405
+ type: 'error',
406
+ node: wf.node,
407
+ error: mergedError,
408
+ });
409
+
410
+ throw mergedError;
411
+ }
412
+
413
+ // Otherwise, if fail-fast mode, throw first error
414
+ if (errors.length > 0) {
415
+ throw errors[0];
416
+ }
417
+ ```
418
+
419
+ ### 5.4 Backward Compatibility Requirements
420
+
421
+ **CRITICAL:** Must preserve existing behavior when `errorStrategy` is not specified:
422
+
423
+ | Configuration | Behavior |
424
+ |---------------|----------|
425
+ | No errorStrategy | Fail-fast (current Promise.all behavior) |
426
+ | errorStrategy: 'fail-fast' | Fail-fast (Promise.all semantics) |
427
+ | errorStrategy: 'complete-all' | Wait for all, aggregate errors |
428
+
429
+ **Implementation approach:**
430
+ ```typescript
431
+ if (opts.concurrent && Array.isArray(result)) {
432
+ const runnable = workflows.filter(/* ... */);
433
+
434
+ if (runnable.length > 0) {
435
+ if (opts.errorStrategy === 'complete-all') {
436
+ // New behavior: Promise.allSettled with error aggregation
437
+ const results = await Promise.allSettled(runnable.map((w) => w.run()));
438
+ // ... error aggregation logic
439
+ } else {
440
+ // Default: maintain current Promise.all behavior
441
+ await Promise.all(runnable.map((w) => w.run()));
442
+ }
443
+ }
444
+ }
445
+ ```
446
+
447
+ ### 5.5 Integration with Existing ErrorMergeStrategy
448
+
449
+ **Location:** `src/types/error-strategy.ts`
450
+
451
+ **Current State:** Interface exists but is completely unused
452
+
453
+ ```typescript
454
+ export interface ErrorMergeStrategy {
455
+ enabled: boolean;
456
+ maxMergeDepth?: number;
457
+ combine?(errors: WorkflowError[]): WorkflowError;
458
+ }
459
+ ```
460
+
461
+ **Migration Decision Point:**
462
+
463
+ **Option A:** Create new `errorStrategy?: 'fail-fast' | 'complete-all'` option
464
+ - Pro: Simpler, more explicit
465
+ - Pro: Easier to understand for users
466
+ - Con: Doesn't leverage existing ErrorMergeStrategy interface
467
+
468
+ **Option B:** Add `errorMergeStrategy?: ErrorMergeStrategy` to TaskOptions
469
+ - Pro: Leverages existing design intent
470
+ - Pro: Supports custom combine() functions
471
+ - Pro: More flexible for advanced use cases
472
+ - Con: More complex configuration
473
+
474
+ **RECOMMENDATION for P1.M2.T1.S2:** Use Option A initially, can add Option B as enhancement
475
+
476
+ ### 5.6 File Structure Changes
477
+
478
+ **New File to Create:**
479
+ ```
480
+ src/utils/promise-utils.ts
481
+ ```
482
+
483
+ **Files to Modify:**
484
+ 1. `src/types/decorators.ts` - Add errorStrategy option
485
+ 2. `src/decorators/task.ts` - Implement Promise.allSettled logic
486
+ 3. `src/utils/index.ts` - Export new promise utilities (if created)
487
+
488
+ ---
489
+
490
+ ## 6. Edge Cases and Gotchas
491
+
492
+ ### 6.1 Promise.allSettled Gotchas
493
+
494
+ #### Gotcha #1: Promise.allSettled Never Rejects
495
+
496
+ **CRITICAL:** Unlike Promise.all, Promise.allSettled ALWAYS resolves
497
+
498
+ ```typescript
499
+ // This NEVER throws
500
+ const results = await Promise.allSettled([runnable1, runnable2]);
501
+
502
+ // You MUST check for errors manually
503
+ const errors = results.filter(r => r.status === 'rejected');
504
+ if (errors.length > 0) {
505
+ throw errors[0].reason; // Manual error propagation
506
+ }
507
+ ```
508
+
509
+ #### Gotcha #2: Type Narrowing Required
510
+
511
+ **Without type guards, TypeScript doesn't know result types:**
512
+
513
+ ```typescript
514
+ // ❌ BAD: Type error
515
+ results.forEach(r => {
516
+ if (r.status === 'fulfilled') {
517
+ console.log(r.value); // Error: Property 'value' does not exist
518
+ }
519
+ });
520
+
521
+ // ✅ GOOD: With type guard
522
+ const isFulfilled = <T>(r: PromiseSettledResult<T>): r is PromiseFulfilledResult<T> =>
523
+ r.status === 'fulfilled';
524
+
525
+ results.forEach(r => {
526
+ if (isFulfilled(r)) {
527
+ console.log(r.value); // OK: Type narrowed
528
+ }
529
+ });
530
+ ```
531
+
532
+ #### Gotcha #3: Order is Preserved But Results Aren't
533
+
534
+ **Promise.allSettled preserves array order, but workflow completion order is non-deterministic:**
535
+
536
+ ```typescript
537
+ const workflows = [wf1, wf2, wf3];
538
+ const results = await Promise.allSettled(workflows.map(w => w.run()));
539
+
540
+ // results[0] always corresponds to wf1
541
+ // results[1] always corresponds to wf2
542
+ // results[2] always corresponds to wf3
543
+
544
+ // But wf2 might complete BEFORE wf1 - order of completion != order of results
545
+ ```
546
+
547
+ ### 6.2 Child Attachment Gotchas
548
+
549
+ #### Gotcha #4: Children Attach BEFORE Execution
550
+
551
+ **Location:** `src/decorators/task.ts:91-102`
552
+
553
+ **CRITICAL:** Parent-child relationship is established BEFORE concurrent execution:
554
+
555
+ ```typescript
556
+ // Step 1: Attach children (lines 91-102)
557
+ for (const workflow of workflows) {
558
+ if (workflow && typeof workflow === 'object' && 'id' in workflow) {
559
+ const childWf = workflow as WorkflowClass;
560
+ if (!childWf.parent) {
561
+ childWf.parent = wf;
562
+ wf.attachChild(childWf as unknown as WorkflowLike);
563
+ }
564
+ }
565
+ }
566
+
567
+ // Step 2: Run concurrently (lines 104-114)
568
+ if (opts.concurrent && Array.isArray(result)) {
569
+ // Children already attached at this point
570
+ await Promise.all(runnable.map((w) => w.run()));
571
+ }
572
+ ```
573
+
574
+ **Implication:** Failed workflows remain attached to parent even after errors.
575
+
576
+ ### 6.3 Runnable Filter Gotchas
577
+
578
+ #### Gotcha #5: No Duplicate Prevention
579
+
580
+ **The runnable filter does NOT prevent duplicate workflow execution:**
581
+
582
+ ```typescript
583
+ @Task({ concurrent: true })
584
+ async spawnDuplicate() {
585
+ const child = new ChildWorkflow('same', this);
586
+ return [child, child]; // Same workflow twice
587
+ }
588
+
589
+ // Result: child.run() is called twice
590
+ // Potential: Race conditions, duplicate side effects
591
+ ```
592
+
593
+ #### Gotcha #6: Non-Workflow Returns Are Silently Skipped
594
+
595
+ **Lenient validation allows flexible signatures:**
596
+
597
+ ```typescript
598
+ @Task()
599
+ async mixedReturn() {
600
+ return [
601
+ new ChildWorkflow('child1', this), // Attached & run
602
+ 'some string', // Silently skipped
603
+ 42, // Silently skipped
604
+ null, // Silently skipped
605
+ new ChildWorkflow('child2', this), // Attached & run
606
+ ];
607
+ }
608
+
609
+ // Original return value preserved (line 123)
610
+ // Only workflow-like objects are filtered for execution
611
+ ```
612
+
613
+ ### 6.4 Error Context Gotchas
614
+
615
+ #### Gotcha #7: WorkflowError May Contain Non-Error Objects
616
+
617
+ **The `original` property is `unknown`, not `Error`:**
618
+
619
+ ```typescript
620
+ export interface WorkflowError {
621
+ original: unknown; // Could be anything thrown
622
+ }
623
+ ```
624
+
625
+ **Implication:** When aggregating errors, don't assume Error interface:
626
+
627
+ ```typescript
628
+ // ❌ BAD: Assumes Error interface
629
+ errors.forEach(e => {
630
+ console.log(e.original.stack); // Error if original isn't Error
631
+ });
632
+
633
+ // ✅ GOOD: Type guard first
634
+ if (error.original instanceof Error) {
635
+ console.log(error.original.stack);
636
+ }
637
+ ```
638
+
639
+ ### 6.5 Event Emission Gotchas
640
+
641
+ #### Gotcha #8: Error Events Emitted Per Workflow
642
+
643
+ **Each failing workflow emits its own error event:**
644
+
645
+ ```typescript
646
+ // In @Step decorator (step.ts:126-130)
647
+ wf.emitEvent({
648
+ type: 'error',
649
+ node: wf.node,
650
+ error: workflowError,
651
+ });
652
+ ```
653
+
654
+ **Implication:** With Promise.allSettled, observers see multiple error events for concurrent failures.
655
+
656
+ **Migration consideration:** May want to emit aggregated error event after collection.
657
+
658
+ ### 6.6 Testing Gotchas
659
+
660
+ #### Gotcha #9: Concurrent Execution Order is Non-Deterministic
661
+
662
+ **From test file (`src/__tests__/adversarial/prd-compliance.test.ts:421-460`):**
663
+
664
+ ```typescript
665
+ it('should run workflows concurrently when concurrent: true', async () => {
666
+ // Test comment acknowledges non-deterministic order:
667
+ // "With concurrent execution, we can't guarantee order, but all should be present"
668
+ expect(executionOrder).toContain('Child1');
669
+ expect(executionOrder).toContain('Child2');
670
+ expect(executionOrder).toContain('Child3');
671
+ });
672
+ ```
673
+
674
+ **Implication:** Tests cannot assume specific execution order with concurrent workflows.
675
+
676
+ ---
677
+
678
+ ## 7. Cross-References to Existing Research
679
+
680
+ ### 7.1 Related Documents
681
+
682
+ | Document | Location | Relevance |
683
+ |----------|----------|-----------|
684
+ | Error Handling Patterns | `plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md` | Documents Promise.all location and ErrorMergeStrategy |
685
+ | Promise.allSettled Research | `plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md` | Comprehensive best practices and migration strategies |
686
+ | Promise.allSettled Quick Ref | `plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md` | Quick reference for implementation |
687
+
688
+ ### 7.2 Related Code Files
689
+
690
+ | File | Lines | Purpose |
691
+ |------|-------|---------|
692
+ | `src/decorators/task.ts` | 104-114 | Promise.all implementation (primary target) |
693
+ | `src/decorators/step.ts` | 109-134 | Error wrapping and WorkflowError creation |
694
+ | `src/core/workflow.ts` | 470-488 | runFunctional error handling |
695
+ | `src/types/error-strategy.ts` | All | ErrorMergeStrategy interface (currently unused) |
696
+ | `src/types/error.ts` | All | WorkflowError interface definition |
697
+ | `src/types/decorators.ts` | All | TaskOptions interface (needs extension) |
698
+
699
+ ### 7.3 Related Test Files
700
+
701
+ | File | Lines | Test Coverage |
702
+ |------|-------|---------------|
703
+ | `src/__tests__/adversarial/edge-case.test.ts` | 366-403 | Concurrent execution with errors |
704
+ | `src/__tests__/adversarial/prd-compliance.test.ts` | 421-460 | Concurrent execution order |
705
+ | `src/__tests__/adversarial/deep-analysis.test.ts` | 473 | Promise.all in test code |
706
+
707
+ ---
708
+
709
+ ## 8. Summary for P1.M2.T1.S2 Implementation
710
+
711
+ ### 8.1 Key Findings
712
+
713
+ 1. **Promise.all fails fast** - Only first error is visible to parent
714
+ 2. **Child attachment is separate** - Happens before execution, regardless of success
715
+ 3. **Error context is complete** - WorkflowError captures all needed information
716
+ 4. **ErrorMergeStrategy exists but unused** - Requires Promise.allSettled to function
717
+ 5. **Type guards are required** - PromiseSettledResult needs type narrowing
718
+
719
+ ### 8.2 Implementation Checklist for P1.M2.T1.S2
720
+
721
+ - [ ] Add `errorStrategy?: 'fail-fast' | 'complete-all'` to TaskOptions
722
+ - [ ] Create type guards in `src/utils/promise-utils.ts`
723
+ - [ ] Replace Promise.all with conditional Promise.allSettled logic
724
+ - [ ] Implement error aggregation for 'complete-all' mode
725
+ - [ ] Ensure backward compatibility (default = fail-fast)
726
+ - [ ] Add tests for both error strategies
727
+ - [ ] Update documentation and examples
728
+
729
+ ### 8.3 Critical Success Factors
730
+
731
+ 1. **Maintain backward compatibility** - Default behavior must remain unchanged
732
+ 2. **Type safety** - Use proper type guards for PromiseSettledResult
733
+ 3. **Complete error context** - Aggregate errors must preserve WorkflowError structure
734
+ 4. **Clear semantics** - 'fail-fast' vs 'complete-all' should be unambiguous
735
+ 5. **Test coverage** - Cover mixed success/failure scenarios
736
+
737
+ ---
738
+
739
+ **Document Status:** ✅ Complete - Ready for P1.M2.T1.S2 Implementation
740
+
741
+ **Next Step:** Proceed to P1.M2.T1.S2 - Implement Promise.allSettled migration with error aggregation