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.
- package/.claude/commands/subtask-planning/prp-base-create.md +120 -0
- package/.claude/commands/subtask-planning/prp-base-execute.md +65 -0
- package/.claude/commands/task-breakdown.md +94 -0
- package/.claude/system_prompts/task-breakdown.md +1 -0
- package/CHANGELOG.md +188 -0
- package/PRD.md +543 -0
- package/README.md +99 -5
- package/examples/README.md +15 -1
- package/examples/examples/11-reparenting-workflows.ts +269 -0
- package/examples/index.ts +4 -0
- package/package-lock.json +2398 -0
- package/package.json +3 -1
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +259 -0
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +484 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +488 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +581 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +687 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +492 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +932 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +1109 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +802 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +603 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +564 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +518 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +1252 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +364 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +114 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +205 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +199 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +134 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +495 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +435 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +506 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +612 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +558 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +788 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +460 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +454 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +520 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +417 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +760 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +245 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +792 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +535 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +190 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +654 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +227 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +345 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +193 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +1323 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +1011 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +927 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +505 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +401 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +142 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +112 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +159 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +549 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +368 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +172 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +175 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +696 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +860 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +1066 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +1103 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +789 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +1098 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +1037 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +916 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +1045 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +890 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +822 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +668 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +706 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +265 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +655 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +1103 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +426 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +506 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +114 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +316 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +754 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +612 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +719 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +215 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +765 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +718 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +149 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +470 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +332 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +167 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +265 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +273 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +760 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +434 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +717 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +472 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +125 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +301 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +1170 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +940 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +151 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +650 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +259 -0
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +457 -0
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +346 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +311 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +1565 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +288 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +741 -0
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +652 -0
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +527 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +415 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +378 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +713 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +370 -0
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +499 -0
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +230 -0
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +1134 -0
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +179 -0
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +629 -0
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +214 -0
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +629 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +529 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +142 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +304 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +558 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +256 -0
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +346 -0
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +415 -0
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +489 -0
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +218 -0
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +380 -0
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +1923 -0
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +319 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +115 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +134 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +153 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +132 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +716 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +186 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +604 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +213 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +30 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +56 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +53 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +49 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +958 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +339 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +305 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +433 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +1574 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +1014 -0
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +376 -0
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +1507 -0
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +949 -0
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +619 -0
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +723 -0
- package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-security-guide.md +56 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +460 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +324 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +175 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +499 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +163 -0
- package/plan/bugfix/BUG_FIX_SUMMARY.md +961 -0
- package/src/__tests__/adversarial/attachChild-performance.test.ts +216 -0
- package/src/__tests__/adversarial/circular-reference.test.ts +101 -0
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +139 -0
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +571 -0
- package/src/__tests__/adversarial/deep-analysis.test.ts +729 -0
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +213 -0
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +448 -0
- package/src/__tests__/adversarial/edge-case.test.ts +703 -0
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +760 -0
- package/src/__tests__/adversarial/incremental-performance.test.ts +140 -0
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +457 -0
- package/src/__tests__/adversarial/observer-propagation.test.ts +487 -0
- package/src/__tests__/adversarial/parent-validation.test.ts +143 -0
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +611 -0
- package/src/__tests__/adversarial/prd-compliance.test.ts +731 -0
- package/src/__tests__/compatibility/backward-compatibility.test.ts +1572 -0
- package/src/__tests__/helpers/index.ts +18 -0
- package/src/__tests__/helpers/tree-verification.ts +257 -0
- package/src/__tests__/integration/bidirectional-consistency.test.ts +847 -0
- package/src/__tests__/integration/observer-logging.test.ts +643 -0
- package/src/__tests__/integration/tree-mirroring.test.ts +37 -0
- package/src/__tests__/integration/workflow-reparenting.test.ts +303 -0
- package/src/__tests__/unit/context.test.ts +79 -0
- package/src/__tests__/unit/logger.test.ts +293 -0
- package/src/__tests__/unit/observable.test.ts +321 -0
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +170 -0
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +209 -0
- package/src/__tests__/unit/workflow-detachChild.test.ts +100 -0
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +153 -0
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +180 -0
- package/src/__tests__/unit/workflow.test.ts +277 -1
- package/src/core/agent.ts +21 -1
- package/src/core/logger.ts +27 -2
- package/src/core/workflow-context.ts +6 -4
- package/src/core/workflow.ts +252 -14
- package/src/debugger/tree-debugger.ts +52 -7
- package/src/decorators/task.ts +65 -2
- package/src/index.ts +4 -2
- package/src/types/decorators.ts +8 -1
- package/src/types/events.ts +1 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/observable.ts +32 -3
- package/src/utils/workflow-error-utils.ts +56 -0
- package/tsconfig.json +1 -1
- package/llms_full.txt +0 -5890
- package/tasks.json +0 -0
- /package/plan/{backlog.json → 001_d3bb02af4886/backlog.json} +0 -0
- /package/plan/{P1P2/PRP.md → 001_d3bb02af4886/docs/PRP/P1P2-PRP.md} +0 -0
- /package/plan/{P3P4/PRP.md → 001_d3bb02af4886/docs/PRP/P3P4-PRP.md} +0 -0
- /package/plan/{P4P5/PRP.md → 001_d3bb02af4886/docs/PRP/P4P5-PRP.md} +0 -0
- /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/external_deps.md +0 -0
- /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/system_context.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_BEST_PRACTICES.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_CODE_PATTERNS.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_INTEGRATION_GUIDE.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_RESEARCH_INDEX.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_INDEX.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_RESEARCH_REPORT.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/RESEARCH_SUMMARY.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/anthropic-sdk.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/async-local-storage.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-code-patterns.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-decision-matrix.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-implementation-guide.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-integration-guide.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-patterns.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-quick-reference.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/zod-schema.md +0 -0
- /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/caching-lru.md +0 -0
- /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/introspection-tools.md +0 -0
- /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/reflection-patterns.md +0 -0
- /package/plan/{P4P5/research → 001_d3bb02af4886/docs/research/P4P5}/RESEARCH_SUMMARY.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/INTROSPECTION_RESEARCH_SUMMARY.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/README-INTROSPECTION.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/agent-introspection-patterns.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-tool-examples.md +0 -0
- /package/{PRPs/PRDs/001-hierarchical-workflow-engine.md → plan/001_d3bb02af4886/prd_snapshot.md} +0 -0
package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md
ADDED
|
@@ -0,0 +1,655 @@
|
|
|
1
|
+
# Testing Error Aggregation Research Report
|
|
2
|
+
|
|
3
|
+
**Research Date:** 2026-01-12
|
|
4
|
+
**Task:** P1.M2.T2.S2 - Implement error aggregation logic in @Task decorator
|
|
5
|
+
**Bug ID:** 001_e8e04329daf3
|
|
6
|
+
**Project:** groundswell - Hierarchical workflow orchestration engine
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Executive Summary
|
|
11
|
+
|
|
12
|
+
Comprehensive research has been conducted on testing patterns for error aggregation in TypeScript/JavaScript workflow engines. This research provides complete implementation guidance for adding error merge strategy support to the groundswell project's @Task decorator.
|
|
13
|
+
|
|
14
|
+
### Key Deliverables
|
|
15
|
+
|
|
16
|
+
1. **Comprehensive Testing Guide** - Complete patterns for testing aggregated errors
|
|
17
|
+
2. **Implementation Guide** - Step-by-step error merger implementation
|
|
18
|
+
3. **Promise.allSettled Patterns** - Specific patterns for concurrent workflow testing
|
|
19
|
+
4. **Quick Reference** - Copy-paste test templates and helper functions
|
|
20
|
+
5. **Research Index** - Organized navigation of all research materials
|
|
21
|
+
|
|
22
|
+
### Files Created
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S2/research/
|
|
26
|
+
├── INDEX.md # Master index and quick reference
|
|
27
|
+
├── README.md # Original research summary
|
|
28
|
+
├── 01-testing-aggregated-errors.md # Comprehensive testing guide (29.5 KB)
|
|
29
|
+
├── 02-error-merge-strategy-testing-guide.md # Implementation & testing guide (30.9 KB)
|
|
30
|
+
├── 03-promise-allsettled-testing-patterns.md # Promise.allSettled patterns (24.4 KB)
|
|
31
|
+
├── 01_typescript_error_aggregation_patterns.md # TypeScript-specific patterns (20.9 KB)
|
|
32
|
+
├── 02_aggregate_error_patterns.md # Aggregate error design patterns (27.3 KB)
|
|
33
|
+
├── 03_error_merging_strategies.md # Error merging strategies (24.8 KB)
|
|
34
|
+
└── 04_github_stackoverflow_examples.md # Community examples (24.1 KB)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Research Findings
|
|
40
|
+
|
|
41
|
+
### 1. Testing Aggregated Errors
|
|
42
|
+
|
|
43
|
+
**Key Patterns Identified:**
|
|
44
|
+
|
|
45
|
+
- **ARRANGE-ACT-ASSERT Structure**: Consistent test organization for clarity
|
|
46
|
+
- **Type Guards**: Essential for type-safe error handling in TypeScript
|
|
47
|
+
- **Partial Object Matching**: Using `toMatchObject` for complex error validation
|
|
48
|
+
- **Event Observer Setup**: Capturing error events for verification
|
|
49
|
+
- **Factory Functions**: Consistent mock error creation
|
|
50
|
+
|
|
51
|
+
**Best Practices:**
|
|
52
|
+
1. Test empty, single, and multiple error scenarios
|
|
53
|
+
2. Verify all error properties are preserved (message, stack, logs, state)
|
|
54
|
+
3. Test both default and custom error mergers
|
|
55
|
+
4. Ensure backward compatibility
|
|
56
|
+
5. Use descriptive test names
|
|
57
|
+
|
|
58
|
+
**Code Example:**
|
|
59
|
+
```typescript
|
|
60
|
+
describe('Error Aggregation', () => {
|
|
61
|
+
it('should aggregate errors from multiple concurrent workflows', async () => {
|
|
62
|
+
// ARRANGE: Create workflows that will fail
|
|
63
|
+
const parent = new ParentWorkflow('Parent');
|
|
64
|
+
|
|
65
|
+
// ACT: Run the workflow
|
|
66
|
+
const result = await parent.run();
|
|
67
|
+
|
|
68
|
+
// ASSERT: Verify error aggregation
|
|
69
|
+
expect(result.message).toContain('3 concurrent errors');
|
|
70
|
+
expect(result.logs).toHaveLength(3);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### 2. Promise.allSettled Error Scenarios
|
|
78
|
+
|
|
79
|
+
**Key Patterns:**
|
|
80
|
+
|
|
81
|
+
- **Type Guards for PromiseSettledResult**:
|
|
82
|
+
```typescript
|
|
83
|
+
function isRejected(result: PromiseSettledResult<unknown>): result is PromiseRejectedResult {
|
|
84
|
+
return result.status === 'rejected';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
|
|
88
|
+
return result.status === 'fulfilled';
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- **Error Extraction**:
|
|
93
|
+
```typescript
|
|
94
|
+
const errors = results
|
|
95
|
+
.filter(isRejected)
|
|
96
|
+
.map(r => r.reason);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- **Orphan Prevention**: Tracking all workflow completions to ensure no hanging promises
|
|
100
|
+
|
|
101
|
+
**Test Scenarios:**
|
|
102
|
+
- Single child failure
|
|
103
|
+
- Multiple concurrent failures (2, 3, 5, 10+)
|
|
104
|
+
- Mixed success/failure scenarios
|
|
105
|
+
- All workflows failing
|
|
106
|
+
- Empty workflow array
|
|
107
|
+
- Performance with large batches (100+ workflows)
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### 3. Testing Error Event Emissions
|
|
112
|
+
|
|
113
|
+
**Key Patterns:**
|
|
114
|
+
|
|
115
|
+
- **Event Observer Setup**:
|
|
116
|
+
```typescript
|
|
117
|
+
function setupEventObserver(workflow: Workflow): WorkflowEvent[] {
|
|
118
|
+
const events: WorkflowEvent[] = [];
|
|
119
|
+
workflow.addObserver({
|
|
120
|
+
onLog: () => {},
|
|
121
|
+
onEvent: (e) => events.push(e),
|
|
122
|
+
onStateUpdated: () => {},
|
|
123
|
+
onTreeChanged: () => {},
|
|
124
|
+
});
|
|
125
|
+
return events;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- **Event Verification**:
|
|
130
|
+
```typescript
|
|
131
|
+
const errorEvents = events.filter(e => e.type === 'error');
|
|
132
|
+
expect(errorEvents.length).toBeGreaterThan(0);
|
|
133
|
+
expect(errorEvents[0].error.message).toContain('concurrent errors');
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
- **Event Propagation**: Verifying events reach parent observers
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### 4. Mock Patterns for Error Scenarios
|
|
141
|
+
|
|
142
|
+
**Key Patterns:**
|
|
143
|
+
|
|
144
|
+
- **Error Factory Function**:
|
|
145
|
+
```typescript
|
|
146
|
+
function createMockError(overrides?: Partial<WorkflowError>): WorkflowError {
|
|
147
|
+
return {
|
|
148
|
+
message: 'Mock error',
|
|
149
|
+
original: new Error('Mock'),
|
|
150
|
+
workflowId: 'mock-workflow',
|
|
151
|
+
state: {} as any,
|
|
152
|
+
logs: [],
|
|
153
|
+
...overrides
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- **Scenario-Based Mocking**: Enum of common error scenarios
|
|
159
|
+
- **Spying on Error Handling**: Using Vitest's `vi.fn()` for tracking
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### 5. Assertion Patterns for Complex Error Objects
|
|
164
|
+
|
|
165
|
+
**Key Patterns:**
|
|
166
|
+
|
|
167
|
+
- **Type Guard Assertions**:
|
|
168
|
+
```typescript
|
|
169
|
+
function isWorkflowError(error: unknown): error is WorkflowError {
|
|
170
|
+
return (
|
|
171
|
+
typeof error === 'object' &&
|
|
172
|
+
error !== null &&
|
|
173
|
+
'message' in error &&
|
|
174
|
+
'workflowId' in error &&
|
|
175
|
+
'logs' in error
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- **Partial Object Matching**:
|
|
181
|
+
```typescript
|
|
182
|
+
expect(result).toMatchObject({
|
|
183
|
+
message: expect.stringContaining('2 errors'),
|
|
184
|
+
workflowId: expect.any(String),
|
|
185
|
+
logs: expect.any(Array),
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- **Nested Object Matching**:
|
|
190
|
+
```typescript
|
|
191
|
+
expect(result.logs).toEqual(
|
|
192
|
+
expect.arrayContaining([
|
|
193
|
+
expect.objectContaining({
|
|
194
|
+
workflowId: expect.any(String),
|
|
195
|
+
level: expect.any(String),
|
|
196
|
+
})
|
|
197
|
+
])
|
|
198
|
+
);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Implementation Guidance
|
|
204
|
+
|
|
205
|
+
### Default Error Merger Specification
|
|
206
|
+
|
|
207
|
+
The default error merger must aggregate:
|
|
208
|
+
|
|
209
|
+
1. **Message**: Count + all error messages (numbered list)
|
|
210
|
+
2. **Original Errors**: Array of all WorkflowError objects
|
|
211
|
+
3. **Parent WorkflowId**: Use first error's workflowId
|
|
212
|
+
4. **Stack Traces**: Concatenated with separators
|
|
213
|
+
5. **Logs**: Flattened array from all errors
|
|
214
|
+
|
|
215
|
+
**Implementation:**
|
|
216
|
+
```typescript
|
|
217
|
+
export function mergeWorkflowErrors(errors: WorkflowError[]): WorkflowError {
|
|
218
|
+
if (errors.length === 0) {
|
|
219
|
+
throw new Error('Cannot merge empty error array');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (errors.length === 1) {
|
|
223
|
+
return errors[0];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const message = `${errors.length} concurrent error${errors.length > 1 ? 's' : ''}: ` +
|
|
227
|
+
errors.map((e, i) => `[${i + 1}] ${e.message}`).join('; ');
|
|
228
|
+
|
|
229
|
+
const stack = errors
|
|
230
|
+
.map((e, i) => `=== Error ${i + 1} ===\n${e.stack || 'No stack trace'}`)
|
|
231
|
+
.join('\n\n');
|
|
232
|
+
|
|
233
|
+
const logs = errors.flatMap(e => e.logs);
|
|
234
|
+
const workflowId = errors[0].workflowId;
|
|
235
|
+
const state = errors[0].state;
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
message,
|
|
239
|
+
original: errors,
|
|
240
|
+
workflowId,
|
|
241
|
+
stack,
|
|
242
|
+
state,
|
|
243
|
+
logs,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### @Task Decorator Integration
|
|
249
|
+
|
|
250
|
+
**Current Implementation** (lines 118-120):
|
|
251
|
+
```typescript
|
|
252
|
+
if (rejected.length > 0) {
|
|
253
|
+
throw rejected[0].reason; // First error only
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Required Changes:**
|
|
258
|
+
```typescript
|
|
259
|
+
if (rejected.length > 0) {
|
|
260
|
+
// Convert to WorkflowError
|
|
261
|
+
const errors = rejected.map((r) => {
|
|
262
|
+
const error = r.reason;
|
|
263
|
+
return isWorkflowError(error)
|
|
264
|
+
? error
|
|
265
|
+
: convertToWorkflowError(error, wf.id);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Apply error merge strategy
|
|
269
|
+
if (opts.errorMergeStrategy?.enabled) {
|
|
270
|
+
const mergedError = opts.errorMergeStrategy.combine
|
|
271
|
+
? opts.errorMergeStrategy.combine(errors)
|
|
272
|
+
: mergeWorkflowErrors(errors);
|
|
273
|
+
|
|
274
|
+
wf.emitEvent({
|
|
275
|
+
type: 'error',
|
|
276
|
+
node: wf.node,
|
|
277
|
+
error: mergedError,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
throw mergedError;
|
|
281
|
+
} else {
|
|
282
|
+
// Backward compatible: throw first error
|
|
283
|
+
wf.emitEvent({
|
|
284
|
+
type: 'error',
|
|
285
|
+
node: wf.node,
|
|
286
|
+
error: errors[0],
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
throw errors[0];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Testing Library Recommendations
|
|
297
|
+
|
|
298
|
+
### Vitest (Recommended for This Project)
|
|
299
|
+
|
|
300
|
+
**Pros:**
|
|
301
|
+
- Native ESM support (essential for this project)
|
|
302
|
+
- Fast execution with worker threads
|
|
303
|
+
- Jest-compatible API (easy migration)
|
|
304
|
+
- Built-in TypeScript support
|
|
305
|
+
- Excellent watch mode
|
|
306
|
+
|
|
307
|
+
**Already Configured:**
|
|
308
|
+
- Version: 1.0.0
|
|
309
|
+
- Config: `/home/dustin/projects/groundswell/vitest.config.ts`
|
|
310
|
+
- Pattern: `src/__tests__/**/*.test.ts`
|
|
311
|
+
- Globals: Enabled
|
|
312
|
+
|
|
313
|
+
**Usage:**
|
|
314
|
+
```bash
|
|
315
|
+
npm test # Run all tests
|
|
316
|
+
npm run test:watch # Watch mode
|
|
317
|
+
npx vitest run path # Run specific file
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Jest (Alternative)
|
|
321
|
+
|
|
322
|
+
**Pros:**
|
|
323
|
+
- Largest ecosystem
|
|
324
|
+
- Extensive documentation
|
|
325
|
+
- Wide community adoption
|
|
326
|
+
|
|
327
|
+
**Cons:**
|
|
328
|
+
- ESM support requires configuration
|
|
329
|
+
- Slower than Vitest
|
|
330
|
+
- Requires ts-jest for TypeScript
|
|
331
|
+
|
|
332
|
+
**Recommendation:** Continue using Vitest (already configured and working)
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Test Coverage Requirements
|
|
337
|
+
|
|
338
|
+
### Unit Tests
|
|
339
|
+
|
|
340
|
+
**File:** `src/__tests__/unit/error-merge-strategy.test.ts`
|
|
341
|
+
|
|
342
|
+
**Coverage:**
|
|
343
|
+
- `mergeWorkflowErrors()` function
|
|
344
|
+
- `mergeWorkflowErrorsWithDepth()` function (if implemented)
|
|
345
|
+
- Empty error array handling
|
|
346
|
+
- Single error handling
|
|
347
|
+
- Two errors merging
|
|
348
|
+
- Multiple errors (3, 5, 10+)
|
|
349
|
+
- Message aggregation
|
|
350
|
+
- Stack trace concatenation
|
|
351
|
+
- Log flattening
|
|
352
|
+
- Parent context preservation
|
|
353
|
+
- Custom combine function
|
|
354
|
+
- maxMergeDepth parameter
|
|
355
|
+
|
|
356
|
+
### Integration Tests
|
|
357
|
+
|
|
358
|
+
**File:** `src/__tests__/integration/error-merge-integration.test.ts`
|
|
359
|
+
|
|
360
|
+
**Coverage:**
|
|
361
|
+
- @Task decorator with errorMergeStrategy enabled
|
|
362
|
+
- @Task decorator with errorMergeStrategy disabled
|
|
363
|
+
- Custom combine function execution
|
|
364
|
+
- Concurrent execution with error merging
|
|
365
|
+
- Error event emission with merged errors
|
|
366
|
+
- Parent workflow error handling
|
|
367
|
+
|
|
368
|
+
### Adversarial Tests
|
|
369
|
+
|
|
370
|
+
**File:** `src/__tests__/adversarial/error-merge-edge-cases.test.ts`
|
|
371
|
+
|
|
372
|
+
**Coverage:**
|
|
373
|
+
- Empty error array
|
|
374
|
+
- Single error
|
|
375
|
+
- Very large error counts (100+)
|
|
376
|
+
- Deeply nested error structures
|
|
377
|
+
- Rapid sequential task execution
|
|
378
|
+
- Memory leak detection
|
|
379
|
+
- Performance under load
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Common Pitfalls to Avoid
|
|
384
|
+
|
|
385
|
+
### 1. Not Testing Empty Array
|
|
386
|
+
```typescript
|
|
387
|
+
// Bad
|
|
388
|
+
it('should merge errors', () => {
|
|
389
|
+
const result = mergeErrors([error1, error2]);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Good
|
|
393
|
+
it('should throw on empty array', () => {
|
|
394
|
+
expect(() => mergeErrors([])).toThrow();
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### 2. Only Testing with 2 Errors
|
|
399
|
+
```typescript
|
|
400
|
+
// Bad
|
|
401
|
+
it('should merge two errors', () => {
|
|
402
|
+
const result = mergeErrors([error1, error2]);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// Good
|
|
406
|
+
it('should merge multiple errors', () => {
|
|
407
|
+
const result = mergeErrors([error1, error2, error3]);
|
|
408
|
+
expect(result.message).toContain('3 concurrent errors');
|
|
409
|
+
});
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 3. Not Verifying All Properties
|
|
413
|
+
```typescript
|
|
414
|
+
// Bad
|
|
415
|
+
expect(result.message).toBeDefined();
|
|
416
|
+
|
|
417
|
+
// Good
|
|
418
|
+
expect(result.message).toBeDefined();
|
|
419
|
+
expect(result.workflowId).toBeDefined();
|
|
420
|
+
expect(result.stack).toBeDefined();
|
|
421
|
+
expect(result.logs).toBeDefined();
|
|
422
|
+
expect(result.original).toEqual([error1, error2]);
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### 4. Not Testing Backward Compatibility
|
|
426
|
+
```typescript
|
|
427
|
+
// Bad: Only tests new behavior
|
|
428
|
+
it('should merge errors when enabled', async () => {
|
|
429
|
+
// Test new behavior
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Good: Tests both old and new
|
|
433
|
+
it('should maintain backward compatibility when disabled', async () => {
|
|
434
|
+
// Test old behavior still works
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## Implementation Workflow
|
|
441
|
+
|
|
442
|
+
### Step 1: Create Default Error Merger
|
|
443
|
+
**File:** `src/utils/error-merger.ts`
|
|
444
|
+
|
|
445
|
+
**Tasks:**
|
|
446
|
+
- [ ] Implement `mergeWorkflowErrors()` function
|
|
447
|
+
- [ ] Add JSDoc documentation
|
|
448
|
+
- [ ] Export function
|
|
449
|
+
|
|
450
|
+
### Step 2: Update @Task Decorator
|
|
451
|
+
**File:** `src/decorators/task.ts`
|
|
452
|
+
|
|
453
|
+
**Tasks:**
|
|
454
|
+
- [ ] Import `mergeWorkflowErrors` from utils
|
|
455
|
+
- [ ] Add `isWorkflowError` type guard
|
|
456
|
+
- [ ] Add `convertToWorkflowError` utility
|
|
457
|
+
- [ ] Update error handling at lines 118-120
|
|
458
|
+
- [ ] Test backward compatibility
|
|
459
|
+
|
|
460
|
+
### Step 3: Create Test Suite
|
|
461
|
+
**File:** `src/__tests__/unit/error-merge-strategy.test.ts`
|
|
462
|
+
|
|
463
|
+
**Tasks:**
|
|
464
|
+
- [ ] Unit tests for `mergeWorkflowErrors()`
|
|
465
|
+
- [ ] Tests for empty, single, multiple errors
|
|
466
|
+
- [ ] Tests for message aggregation
|
|
467
|
+
- [ ] Tests for stack concatenation
|
|
468
|
+
- [ ] Tests for log flattening
|
|
469
|
+
- [ ] Tests for custom combine function
|
|
470
|
+
- [ ] Tests for backward compatibility
|
|
471
|
+
|
|
472
|
+
### Step 4: Run Tests
|
|
473
|
+
**Tasks:**
|
|
474
|
+
- [ ] Run all tests: `npm test`
|
|
475
|
+
- [ ] Verify 344+ existing tests still pass
|
|
476
|
+
- [ ] Verify new tests pass
|
|
477
|
+
- [ ] Check coverage: `npm run test:coverage`
|
|
478
|
+
|
|
479
|
+
### Step 5: Update Documentation
|
|
480
|
+
**Tasks:**
|
|
481
|
+
- [ ] Add JSDoc comments to new functions
|
|
482
|
+
- [ ] Update PRD if behavior changes
|
|
483
|
+
- [ ] Add code examples to tests
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## Success Criteria
|
|
488
|
+
|
|
489
|
+
### Functional Requirements
|
|
490
|
+
- ✅ ErrorMergeStrategy interface exists in TaskOptions (P1.M2.T2.S1 - Complete)
|
|
491
|
+
- ⏳ Default error merger implemented
|
|
492
|
+
- ⏳ Custom combine function supported
|
|
493
|
+
- ⏳ maxMergeDepth parameter working
|
|
494
|
+
- ⏳ Error events emitted with merged errors
|
|
495
|
+
- ⏳ Backward compatible (disabled throws first error)
|
|
496
|
+
|
|
497
|
+
### Test Requirements
|
|
498
|
+
- ⏳ All 344+ existing tests pass
|
|
499
|
+
- ⏳ New tests have 100% coverage
|
|
500
|
+
- ⏳ No performance degradation
|
|
501
|
+
- ⏳ No breaking changes to public API
|
|
502
|
+
|
|
503
|
+
### Documentation Requirements
|
|
504
|
+
- ⏳ JSDoc comments on all public functions
|
|
505
|
+
- ⏳ Code examples in test files
|
|
506
|
+
- ⏳ PRD updated if needed
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## External Resources
|
|
511
|
+
|
|
512
|
+
### Official Documentation
|
|
513
|
+
1. **Vitest Guide:** https://vitest.dev/guide/
|
|
514
|
+
2. **Promise.allSettled MDN:** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
|
|
515
|
+
3. **AggregateError MDN:** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
|
|
516
|
+
4. **TypeScript Handbook:** https://www.typescriptlang.org/docs/handbook/intro.html
|
|
517
|
+
|
|
518
|
+
### Community Resources
|
|
519
|
+
1. **TC39 Promise.allSettled Proposal:** https://github.com/tc39/proposal-promise-allSettled
|
|
520
|
+
2. **Jest Documentation:** https://jestjs.io/docs/getting-started
|
|
521
|
+
|
|
522
|
+
### Project-Specific
|
|
523
|
+
1. **@Task Decorator:** `/home/dustin/projects/groundswell/src/decorators/task.ts`
|
|
524
|
+
2. **Error Strategy Types:** `/home/dustin/projects/groundswell/src/types/error-strategy.ts`
|
|
525
|
+
3. **WorkflowError Interface:** `/home/dustin/projects/groundswell/src/types/error.ts`
|
|
526
|
+
4. **Existing Tests:** `/home/dustin/projects/groundswell/src/__tests__/adversarial/concurrent-task-failures.test.ts`
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## Helper Functions Library
|
|
531
|
+
|
|
532
|
+
### Error Creation
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
function createMockError(overrides?: Partial<WorkflowError>): WorkflowError {
|
|
536
|
+
return {
|
|
537
|
+
message: 'Mock error',
|
|
538
|
+
original: new Error('Mock'),
|
|
539
|
+
workflowId: 'mock-workflow',
|
|
540
|
+
state: {} as any,
|
|
541
|
+
logs: [],
|
|
542
|
+
...overrides
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function createFailingWorkflow(parent: Workflow, name: string, errorMessage: string): Workflow {
|
|
547
|
+
return new (class extends Workflow {
|
|
548
|
+
async run() {
|
|
549
|
+
throw new Error(errorMessage);
|
|
550
|
+
}
|
|
551
|
+
})(name, parent);
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Type Guards
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
function isWorkflowError(error: unknown): error is WorkflowError {
|
|
559
|
+
return (
|
|
560
|
+
typeof error === 'object' &&
|
|
561
|
+
error !== null &&
|
|
562
|
+
'message' in error &&
|
|
563
|
+
'workflowId' in error &&
|
|
564
|
+
'logs' in error
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function isRejected(result: PromiseSettledResult<unknown>): result is PromiseRejectedResult {
|
|
569
|
+
return result.status === 'rejected';
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
|
|
573
|
+
return result.status === 'fulfilled';
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Test Setup
|
|
578
|
+
|
|
579
|
+
```typescript
|
|
580
|
+
function setupEventObserver(workflow: Workflow): WorkflowEvent[] {
|
|
581
|
+
const events: WorkflowEvent[] = [];
|
|
582
|
+
workflow.addObserver({
|
|
583
|
+
onLog: () => {},
|
|
584
|
+
onEvent: (e) => events.push(e),
|
|
585
|
+
onStateUpdated: () => {},
|
|
586
|
+
onTreeChanged: () => {},
|
|
587
|
+
});
|
|
588
|
+
return events;
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## Next Steps
|
|
595
|
+
|
|
596
|
+
### Immediate Actions
|
|
597
|
+
|
|
598
|
+
1. **Review Research Documents**
|
|
599
|
+
- Read `INDEX.md` for navigation
|
|
600
|
+
- Study `02-error-merge-strategy-testing-guide.md` for implementation
|
|
601
|
+
- Reference `01-testing-aggregated-errors.md` for testing patterns
|
|
602
|
+
|
|
603
|
+
2. **Implement Default Merger**
|
|
604
|
+
- Create `src/utils/error-merger.ts`
|
|
605
|
+
- Implement `mergeWorkflowErrors()` function
|
|
606
|
+
- Add comprehensive JSDoc documentation
|
|
607
|
+
|
|
608
|
+
3. **Update @Task Decorator**
|
|
609
|
+
- Modify `src/decorators/task.ts` lines 118-120
|
|
610
|
+
- Add error merge strategy logic
|
|
611
|
+
- Maintain backward compatibility
|
|
612
|
+
|
|
613
|
+
4. **Create Test Suite**
|
|
614
|
+
- Create `src/__tests__/unit/error-merge-strategy.test.ts`
|
|
615
|
+
- Implement comprehensive test coverage
|
|
616
|
+
- Test all scenarios (empty, single, multiple, custom)
|
|
617
|
+
|
|
618
|
+
5. **Validate Implementation**
|
|
619
|
+
- Run all tests: `npm test`
|
|
620
|
+
- Verify 344+ existing tests pass
|
|
621
|
+
- Check coverage is 100%
|
|
622
|
+
- Test with real workflow scenarios
|
|
623
|
+
|
|
624
|
+
### Future Enhancements
|
|
625
|
+
|
|
626
|
+
- Implement `maxMergeDepth` parameter for limiting recursion
|
|
627
|
+
- Add error deduplication for duplicate errors
|
|
628
|
+
- Implement time-windowed error aggregation
|
|
629
|
+
- Add error categorization and statistics
|
|
630
|
+
- Support for custom error merge strategies library
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
## Conclusion
|
|
635
|
+
|
|
636
|
+
This research provides complete guidance for implementing error aggregation in the groundswell workflow engine. All testing patterns, implementation details, and best practices have been documented comprehensively.
|
|
637
|
+
|
|
638
|
+
**Key Takeaways:**
|
|
639
|
+
|
|
640
|
+
1. **Comprehensive Coverage**: Research covers all aspects of error aggregation testing
|
|
641
|
+
2. **Implementation Ready**: Complete code examples and templates provided
|
|
642
|
+
3. **Best Practices**: Industry-standard patterns and common pitfalls documented
|
|
643
|
+
4. **Project Context**: Tailored specifically for groundswell architecture
|
|
644
|
+
5. **Quick Reference**: Organized for easy navigation during implementation
|
|
645
|
+
|
|
646
|
+
**Status**: Research Complete
|
|
647
|
+
**Next Phase**: Implementation (P1.M2.T2.S2)
|
|
648
|
+
**Expected Outcome**: Robust error aggregation with comprehensive test coverage
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
**Document Version:** 1.0
|
|
653
|
+
**Last Updated:** 2026-01-12
|
|
654
|
+
**Research By:** Claude Code Agent
|
|
655
|
+
**Project:** groundswell - Hierarchical workflow orchestration engine
|