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
|
@@ -0,0 +1,961 @@
|
|
|
1
|
+
# Bug Fix Summary
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
This document summarizes all bug fixes implemented during the Groundswell workflow engine development cycle. These fixes address critical PRD compliance issues, reliability concerns in concurrent execution, and various usability improvements.
|
|
6
|
+
|
|
7
|
+
### Fix Distribution
|
|
8
|
+
|
|
9
|
+
| Severity | Count | Description |
|
|
10
|
+
|----------|-------|-------------|
|
|
11
|
+
| **Critical** | 1 | PRD specification violations that affect core functionality |
|
|
12
|
+
| **Major** | 3 | Missing features, reliability issues, and documentation correctness |
|
|
13
|
+
| **Minor** | 4 | Small improvements, optimizations, and API enhancements |
|
|
14
|
+
|
|
15
|
+
### Test Coverage
|
|
16
|
+
|
|
17
|
+
- **New test files**: 12 files
|
|
18
|
+
- **New test cases**: 50+ cases
|
|
19
|
+
- **Test pass rate**: 100%
|
|
20
|
+
- **Coverage areas**: Unit tests, adversarial tests, integration tests
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Critical Fixes (P1.M1)
|
|
25
|
+
|
|
26
|
+
### WorkflowLogger.child() Signature Fix
|
|
27
|
+
|
|
28
|
+
**Issue**: The `WorkflowLogger.child()` method signature violated the PRD specification at [PRD.md:303](PRD.md#L303). The PRD specified `child(meta: Partial<LogEntry>)` but the implementation only accepted `child(parentLogId: string)`.
|
|
29
|
+
|
|
30
|
+
**Severity**: **Critical** - This is a direct PRD specification violation that prevents the logger from being used as intended.
|
|
31
|
+
|
|
32
|
+
**Impact**: Users could not pass additional metadata to child loggers, limiting the observability and debugging capabilities of the workflow engine.
|
|
33
|
+
|
|
34
|
+
**Location**: [src/core/logger.ts:98-111](src/core/logger.ts#L98-L111)
|
|
35
|
+
|
|
36
|
+
#### Before (Buggy Pattern)
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
/**
|
|
40
|
+
* Create a child logger
|
|
41
|
+
* @param parentLogId - ID of the parent log entry
|
|
42
|
+
*/
|
|
43
|
+
child(parentLogId: string): WorkflowLogger {
|
|
44
|
+
return new WorkflowLogger(this.node, this.observers, parentLogId);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Limitations**:
|
|
49
|
+
- Only accepts a string `parentLogId`
|
|
50
|
+
- Cannot pass additional metadata like workflow context, timestamps, or custom fields
|
|
51
|
+
- Violates PRD specification which explicitly requires `Partial<LogEntry>` parameter
|
|
52
|
+
|
|
53
|
+
#### After (Correct Pattern)
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
/**
|
|
57
|
+
* Create a child logger that includes parentLogId
|
|
58
|
+
* @param parentLogId - ID of the parent log entry (legacy API)
|
|
59
|
+
*/
|
|
60
|
+
child(parentLogId: string): WorkflowLogger;
|
|
61
|
+
/**
|
|
62
|
+
* Create a child logger with metadata
|
|
63
|
+
* @param meta - Partial log entry metadata (typically { parentLogId: string })
|
|
64
|
+
*/
|
|
65
|
+
child(meta: Partial<LogEntry>): WorkflowLogger;
|
|
66
|
+
child(input: string | Partial<LogEntry>): WorkflowLogger {
|
|
67
|
+
const parentLogId = typeof input === 'string' ? input : input.parentLogId;
|
|
68
|
+
return new WorkflowLogger(this.node, this.observers, parentLogId);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Improvements**:
|
|
73
|
+
- Function overloads for TypeScript type safety
|
|
74
|
+
- Backward compatible with existing string-based API
|
|
75
|
+
- Supports passing full `Partial<LogEntry>` metadata
|
|
76
|
+
- Follows PRD specification exactly
|
|
77
|
+
|
|
78
|
+
#### Migration Steps
|
|
79
|
+
|
|
80
|
+
1. **No migration required** - The fix is backward compatible
|
|
81
|
+
2. Existing code using `child(parentLogId: string)` continues to work
|
|
82
|
+
3. New code can use the enhanced API: `child({ parentLogId: 'abc-123', workflowId: 'wf-456' })`
|
|
83
|
+
|
|
84
|
+
#### Test Coverage
|
|
85
|
+
|
|
86
|
+
- **Test file**: [src/__tests__/unit/logger.test.ts](src/__tests__/unit/logger.test.ts)
|
|
87
|
+
- **Test cases**: 294 lines of comprehensive tests
|
|
88
|
+
- **Coverage**:
|
|
89
|
+
- String parameter (legacy API)
|
|
90
|
+
- Partial<LogEntry> parameter (new API)
|
|
91
|
+
- parentLogId propagation
|
|
92
|
+
- Metadata handling
|
|
93
|
+
- Edge cases
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Major Fixes (P1.M2)
|
|
98
|
+
|
|
99
|
+
### 1. Promise.allSettled for Concurrent Tasks
|
|
100
|
+
|
|
101
|
+
**Issue**: The `@Task` decorator with `concurrent: true` used `Promise.all()`, which would reject immediately upon the first failure. This prevented collection of all errors from concurrent child workflows and made debugging difficult.
|
|
102
|
+
|
|
103
|
+
**Severity**: **Major** - Affects reliability of concurrent task execution and error visibility.
|
|
104
|
+
|
|
105
|
+
**Impact**:
|
|
106
|
+
- Only the first error was captured when multiple concurrent workflows failed
|
|
107
|
+
- Debugging required re-running workflows to capture subsequent errors
|
|
108
|
+
- No aggregate error information available for decision-making
|
|
109
|
+
|
|
110
|
+
**Location**: [src/decorators/task.ts:112-142](src/decorators/task.ts#L112-L142)
|
|
111
|
+
|
|
112
|
+
#### Before (Buggy Pattern)
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// If concurrent option is set and we have multiple workflows, run them in parallel
|
|
116
|
+
if (opts.concurrent && Array.isArray(result)) {
|
|
117
|
+
const runnable = workflows.filter(
|
|
118
|
+
(w): w is WorkflowClass =>
|
|
119
|
+
w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (runnable.length > 0) {
|
|
123
|
+
// BUG: Promise.all() rejects on first failure
|
|
124
|
+
const results = await Promise.all(runnable.map((w) => w.run()));
|
|
125
|
+
// If ANY child workflow fails, execution stops here
|
|
126
|
+
// Subsequent errors are never captured
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Problems**:
|
|
132
|
+
- `Promise.all()` fast-fails on first rejection
|
|
133
|
+
- Other concurrent tasks continue running but errors are lost
|
|
134
|
+
- No visibility into total failure count
|
|
135
|
+
|
|
136
|
+
#### After (Correct Pattern)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// If concurrent option is set and we have multiple workflows, run them in parallel
|
|
140
|
+
if (opts.concurrent && Array.isArray(result)) {
|
|
141
|
+
const runnable = workflows.filter(
|
|
142
|
+
(w): w is WorkflowClass =>
|
|
143
|
+
w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
if (runnable.length > 0) {
|
|
147
|
+
// FIX: Promise.allSettled() waits for ALL promises to complete
|
|
148
|
+
const results = await Promise.allSettled(runnable.map((w) => w.run()));
|
|
149
|
+
|
|
150
|
+
const rejected = results.filter(
|
|
151
|
+
(r): r is PromiseRejectedResult => r.status === 'rejected'
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
if (rejected.length > 0) {
|
|
155
|
+
// Check if error merge strategy is enabled
|
|
156
|
+
if (opts.errorMergeStrategy?.enabled) {
|
|
157
|
+
// Extract WorkflowError objects from rejected promises
|
|
158
|
+
const errors = rejected.map((r) => r.reason as WorkflowError);
|
|
159
|
+
|
|
160
|
+
// Merge errors using custom combine() or default merger
|
|
161
|
+
const mergedError = opts.errorMergeStrategy?.combine
|
|
162
|
+
? opts.errorMergeStrategy.combine(errors)
|
|
163
|
+
: mergeWorkflowErrors(errors, taskName, wf.id, runnable.length);
|
|
164
|
+
|
|
165
|
+
// Emit error event with merged error
|
|
166
|
+
wf.emitEvent({
|
|
167
|
+
type: 'error',
|
|
168
|
+
node: wf.node,
|
|
169
|
+
error: mergedError,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Throw merged error
|
|
173
|
+
throw mergedError;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Backward compatibility: throw first error
|
|
177
|
+
throw rejected[0].reason;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Improvements**:
|
|
184
|
+
- `Promise.allSettled()` captures all results (fulfilled and rejected)
|
|
185
|
+
- All errors from concurrent failures are collected
|
|
186
|
+
- Optional error merge strategy for aggregate error reporting
|
|
187
|
+
- Backward compatible: throws first error by default
|
|
188
|
+
|
|
189
|
+
#### Migration Steps
|
|
190
|
+
|
|
191
|
+
1. **No migration required** - Behavior is backward compatible
|
|
192
|
+
2. To enable error merging, add `errorMergeStrategy` to `@Task` decorator:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
@Task({
|
|
196
|
+
concurrent: true,
|
|
197
|
+
errorMergeStrategy: { enabled: true }
|
|
198
|
+
})
|
|
199
|
+
async spawnWorkflows(): Promise<Workflow[]> {
|
|
200
|
+
// ... concurrent workflows
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
3. For custom error aggregation, provide a `combine` function:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
@Task({
|
|
208
|
+
concurrent: true,
|
|
209
|
+
errorMergeStrategy: {
|
|
210
|
+
enabled: true,
|
|
211
|
+
combine: (errors) => ({
|
|
212
|
+
message: `Custom aggregation: ${errors.length} workflows failed`,
|
|
213
|
+
original: errors,
|
|
214
|
+
workflowId: 'parent-id',
|
|
215
|
+
state: {},
|
|
216
|
+
logs: errors.flatMap(e => e.logs)
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Test Coverage
|
|
223
|
+
|
|
224
|
+
- **Test file**: [src/__tests__/adversarial/concurrent-task-failures.test.ts](src/__tests__/adversarial/concurrent-task-failures.test.ts)
|
|
225
|
+
- **Test cases**: Multiple scenarios for concurrent failures
|
|
226
|
+
- **Coverage**:
|
|
227
|
+
- Single failure in concurrent batch
|
|
228
|
+
- Multiple failures in concurrent batch
|
|
229
|
+
- All failures in concurrent batch
|
|
230
|
+
- Error merge strategy enabled/disabled
|
|
231
|
+
- Custom error aggregation
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
### 2. ErrorMergeStrategy Implementation
|
|
236
|
+
|
|
237
|
+
**Issue**: The PRD specified an optional error merge strategy for concurrent tasks ([PRD.md:246-254](PRD.md#L246-L254)), but this feature was completely missing from the implementation.
|
|
238
|
+
|
|
239
|
+
**Severity**: **Major** - Missing core functionality specified in the PRD.
|
|
240
|
+
|
|
241
|
+
**Impact**:
|
|
242
|
+
- Users could not enable multi-error merging for concurrent tasks
|
|
243
|
+
- No way to customize error aggregation behavior
|
|
244
|
+
- Concurrent failures only showed first error
|
|
245
|
+
|
|
246
|
+
**Locations**:
|
|
247
|
+
- Type definition: [src/types/decorators.ts:25-32](src/types/decorators.ts#L25-L32)
|
|
248
|
+
- Default merger: [src/utils/workflow-error-utils.ts:23-56](src/utils/workflow-error-utils.ts#L23-L56)
|
|
249
|
+
- Usage: [src/decorators/task.ts:120-138](src/decorators/task.ts#L120-L138)
|
|
250
|
+
|
|
251
|
+
#### Implementation Details
|
|
252
|
+
|
|
253
|
+
**Type Definition** ([src/types/decorators.ts:25-32](src/types/decorators.ts#L25-L32)):
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
export interface TaskOptions {
|
|
257
|
+
/** Custom task name (defaults to method name) */
|
|
258
|
+
name?: string;
|
|
259
|
+
/** If true, run returned workflows concurrently */
|
|
260
|
+
concurrent?: boolean;
|
|
261
|
+
/** Strategy for merging errors from concurrent task execution */
|
|
262
|
+
errorMergeStrategy?: ErrorMergeStrategy;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Default Error Merger** ([src/utils/workflow-error-utils.ts:23-56](src/utils/workflow-error-utils.ts#L23-L56)):
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
/**
|
|
270
|
+
* Merge multiple WorkflowError objects into a single aggregated error.
|
|
271
|
+
*
|
|
272
|
+
* This is the default merger used when errorMergeStrategy is enabled for concurrent tasks.
|
|
273
|
+
* It aggregates information from all errors to provide a comprehensive view of failures.
|
|
274
|
+
*
|
|
275
|
+
* @param errors - Array of WorkflowError objects to merge
|
|
276
|
+
* @param taskName - Name of the task that spawned the concurrent workflows
|
|
277
|
+
* @param parentWorkflowId - ID of the parent workflow
|
|
278
|
+
* @param totalChildren - Total number of child workflows that were spawned
|
|
279
|
+
* @returns A merged WorkflowError containing aggregated information
|
|
280
|
+
*/
|
|
281
|
+
export function mergeWorkflowErrors(
|
|
282
|
+
errors: WorkflowError[],
|
|
283
|
+
taskName: string,
|
|
284
|
+
parentWorkflowId: string,
|
|
285
|
+
totalChildren: number
|
|
286
|
+
): WorkflowError {
|
|
287
|
+
// Create merged error message
|
|
288
|
+
const message = `${errors.length} of ${totalChildren} concurrent child workflows failed in task '${taskName}'`;
|
|
289
|
+
|
|
290
|
+
// Get all unique workflow IDs that failed
|
|
291
|
+
const failedWorkflowIds = [...new Set(errors.map((e) => e.workflowId))];
|
|
292
|
+
|
|
293
|
+
// Aggregate all logs
|
|
294
|
+
const allLogs = errors.flatMap((e) => e.logs);
|
|
295
|
+
|
|
296
|
+
// Create merged WorkflowError
|
|
297
|
+
const mergedError: WorkflowError = {
|
|
298
|
+
message,
|
|
299
|
+
original: {
|
|
300
|
+
name: 'WorkflowAggregateError',
|
|
301
|
+
message,
|
|
302
|
+
errors,
|
|
303
|
+
totalChildren,
|
|
304
|
+
failedChildren: errors.length,
|
|
305
|
+
failedWorkflowIds,
|
|
306
|
+
} as unknown,
|
|
307
|
+
workflowId: parentWorkflowId,
|
|
308
|
+
stack: errors[0]?.stack, // Use first error's stack trace
|
|
309
|
+
state: errors[0]?.state || ({} as SerializedWorkflowState), // Use first error's state
|
|
310
|
+
logs: allLogs,
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
return mergedError;
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Features**:
|
|
318
|
+
- Aggregates all error messages into a single descriptive message
|
|
319
|
+
- Collects all failed workflow IDs
|
|
320
|
+
- Merges logs from all failed workflows
|
|
321
|
+
- Uses first error's stack trace and state for debugging
|
|
322
|
+
- Preserves original errors in `original.errors` array
|
|
323
|
+
|
|
324
|
+
#### Usage Examples
|
|
325
|
+
|
|
326
|
+
**Default error merging**:
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
@Task({
|
|
330
|
+
concurrent: true,
|
|
331
|
+
errorMergeStrategy: { enabled: true }
|
|
332
|
+
})
|
|
333
|
+
async spawnWorkflows(): Promise<Workflow[]> {
|
|
334
|
+
return [
|
|
335
|
+
new ChildWorkflow('child1', this),
|
|
336
|
+
new ChildWorkflow('child2', this),
|
|
337
|
+
new ChildWorkflow('child3', this),
|
|
338
|
+
];
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// If child1 and child3 fail, the error message will be:
|
|
342
|
+
// "2 of 3 concurrent child workflows failed in task 'spawnWorkflows'"
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Custom error aggregation**:
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
@Task({
|
|
349
|
+
concurrent: true,
|
|
350
|
+
errorMergeStrategy: {
|
|
351
|
+
enabled: true,
|
|
352
|
+
combine: (errors) => {
|
|
353
|
+
// Custom aggregation logic
|
|
354
|
+
const criticalErrors = errors.filter(e => e.message.includes('critical'));
|
|
355
|
+
return {
|
|
356
|
+
message: `${criticalErrors.length} critical errors occurred`,
|
|
357
|
+
original: errors,
|
|
358
|
+
workflowId: 'parent-id',
|
|
359
|
+
state: {},
|
|
360
|
+
logs: errors.flatMap(e => e.logs)
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
async spawnWorkflows(): Promise<Workflow[]> {
|
|
366
|
+
// ... concurrent workflows
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
#### Migration Steps
|
|
371
|
+
|
|
372
|
+
1. **No migration required** - This is an additive feature
|
|
373
|
+
2. To enable error merging, add `errorMergeStrategy: { enabled: true }` to `@Task` decorator
|
|
374
|
+
3. Default behavior (no error merge strategy) remains unchanged for backward compatibility
|
|
375
|
+
|
|
376
|
+
#### Test Coverage
|
|
377
|
+
|
|
378
|
+
- **Test file**: [src/__tests__/adversarial/error-merge-strategy.test.ts](src/__tests__/adversarial/error-merge-strategy.test.ts)
|
|
379
|
+
- **Coverage**:
|
|
380
|
+
- Default merger behavior
|
|
381
|
+
- Custom combine function
|
|
382
|
+
- Edge cases (empty errors, single error)
|
|
383
|
+
- Log aggregation
|
|
384
|
+
- Workflow ID collection
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
### 3. trackTiming Default Documentation
|
|
389
|
+
|
|
390
|
+
**Issue**: The PRD at [PRD.md:183](PRD.md#L183) specifies that `trackTiming` in the `@Step` decorator has a default value of `true`, but this was not clearly documented. The implementation uses a `!== false` check to achieve this default behavior implicitly.
|
|
391
|
+
|
|
392
|
+
**Severity**: **Minor** - Documentation inconsistency, behavior was correct but unclear.
|
|
393
|
+
|
|
394
|
+
**Impact**:
|
|
395
|
+
- Users were unsure if timing tracking was enabled by default
|
|
396
|
+
- Unclear whether to explicitly set `trackTiming: true`
|
|
397
|
+
|
|
398
|
+
**Location**: [src/decorators/step.ts:94-101](src/decorators/step.ts#L94-L101)
|
|
399
|
+
|
|
400
|
+
#### Implementation Details
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// Calculate duration and emit end event
|
|
404
|
+
const duration = Date.now() - startTime;
|
|
405
|
+
if (opts.trackTiming !== false) { // Default is TRUE via !== false check
|
|
406
|
+
wf.emitEvent({
|
|
407
|
+
type: 'stepEnd',
|
|
408
|
+
node: wf.node,
|
|
409
|
+
step: stepName,
|
|
410
|
+
duration,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**How it works**:
|
|
416
|
+
- `trackTiming` defaults to `true` (implicitly via `!== false`)
|
|
417
|
+
- Explicit `trackTiming: false` disables timing
|
|
418
|
+
- Explicit `trackTiming: true` or undefined enables timing
|
|
419
|
+
- This pattern allows for clean default behavior without explicit assignment
|
|
420
|
+
|
|
421
|
+
#### Usage Examples
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
// Timing enabled by default (recommended)
|
|
425
|
+
@Step()
|
|
426
|
+
async processData() {
|
|
427
|
+
// stepEnd event will include duration
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Explicitly disabled
|
|
431
|
+
@Step({ trackTiming: false })
|
|
432
|
+
async quickOperation() {
|
|
433
|
+
// No stepEnd event emitted (for performance-critical code)
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Explicitly enabled (redundant but clear)
|
|
437
|
+
@Step({ trackTiming: true })
|
|
438
|
+
async measuredOperation() {
|
|
439
|
+
// stepEnd event will include duration
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
#### Migration Steps
|
|
444
|
+
|
|
445
|
+
1. **No migration required** - This is a documentation clarification
|
|
446
|
+
2. If you want timing tracking, no action needed (it's the default)
|
|
447
|
+
3. If you want to disable timing for performance, use `trackTiming: false`
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Minor Fixes (P1.M3)
|
|
452
|
+
|
|
453
|
+
### 1. Console.error to Logger Replacement
|
|
454
|
+
|
|
455
|
+
**Issue**: Observer error handling in [src/core/workflow.ts](src/core/workflow.ts) used `console.error()` instead of the workflow logger, causing inconsistent logging.
|
|
456
|
+
|
|
457
|
+
**Severity**: **Minor** - Logging consistency issue, doesn't affect functionality.
|
|
458
|
+
|
|
459
|
+
**Impact**:
|
|
460
|
+
- Observer errors not captured in workflow logs
|
|
461
|
+
- Inconsistent error handling throughout the codebase
|
|
462
|
+
- Debugging observer issues more difficult
|
|
463
|
+
|
|
464
|
+
**Locations**:
|
|
465
|
+
- [src/core/workflow.ts:426](src/core/workflow.ts#L426) - Observer onEvent error
|
|
466
|
+
- [src/core/workflow.ts:444](src/core/workflow.ts#L444) - Observer onStateUpdated error
|
|
467
|
+
|
|
468
|
+
#### Before
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
} catch (err) {
|
|
472
|
+
console.error(errorMessage);
|
|
473
|
+
throw new Error(errorMessage);
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### After
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
} catch (err) {
|
|
481
|
+
this.logger.error('Observer onEvent error', { error: err, eventType: event.type });
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// ... elsewhere for onStateUpdated
|
|
485
|
+
|
|
486
|
+
} catch (err) {
|
|
487
|
+
this.logger.error('Observer onStateUpdated error', { error: err, nodeId: this.node.id });
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**Improvements**:
|
|
492
|
+
- All errors now go through the workflow logger
|
|
493
|
+
- Structured logging with contextual data
|
|
494
|
+
- Consistent with rest of codebase
|
|
495
|
+
|
|
496
|
+
#### Migration Steps
|
|
497
|
+
|
|
498
|
+
1. **No migration required** - Transparent to users
|
|
499
|
+
2. Observer errors now appear in workflow logs
|
|
500
|
+
3. No code changes needed
|
|
501
|
+
|
|
502
|
+
#### Test Coverage
|
|
503
|
+
|
|
504
|
+
- **Test file**: [src/__tests__/integration/observer-logging.test.ts](src/__tests__/integration/observer-logging.test.ts)
|
|
505
|
+
- **Coverage**: Observer error handling and logging
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
### 2. Tree Debugger Optimization
|
|
510
|
+
|
|
511
|
+
**Issue**: The tree debugger's `onTreeChanged()` method rebuilt the entire node map on every tree update, resulting in O(n²) complexity for tree operations.
|
|
512
|
+
|
|
513
|
+
**Severity**: **Minor** - Performance optimization, doesn't affect functionality.
|
|
514
|
+
|
|
515
|
+
**Impact**:
|
|
516
|
+
- Performance degradation on large workflow trees
|
|
517
|
+
- Unnecessary work on incremental tree changes
|
|
518
|
+
- Potential memory churn from frequent map rebuilds
|
|
519
|
+
|
|
520
|
+
**Location**: [src/debugger/tree-debugger.ts:65-117](src/debugger/tree-debugger.ts#L65-L117)
|
|
521
|
+
|
|
522
|
+
#### Before (Inefficient Pattern)
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
onTreeChanged(root: WorkflowNode): void {
|
|
526
|
+
// OLD: Rebuild entire map on every change
|
|
527
|
+
this.root = root;
|
|
528
|
+
this.nodeMap.clear();
|
|
529
|
+
this.buildNodeMap(this.root); // O(n) for every update
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Also handled in onEvent for structural changes
|
|
533
|
+
onEvent(event: WorkflowEvent): void {
|
|
534
|
+
// But this wasn't optimized either
|
|
535
|
+
this.buildNodeMap(event.child); // Only added, never removed
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
#### After (Optimized Pattern)
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
/**
|
|
543
|
+
* Remove entire subtree from node map using BFS traversal
|
|
544
|
+
* O(k) complexity where k = number of nodes in subtree
|
|
545
|
+
* Uses iterative BFS to avoid stack overflow on deep trees
|
|
546
|
+
*/
|
|
547
|
+
private removeSubtreeNodes(nodeId: string): void {
|
|
548
|
+
const node = this.nodeMap.get(nodeId);
|
|
549
|
+
if (!node) return; // Already removed or never existed
|
|
550
|
+
|
|
551
|
+
// BFS traversal to collect all descendant IDs
|
|
552
|
+
const toRemove: string[] = [];
|
|
553
|
+
const queue: WorkflowNode[] = [node];
|
|
554
|
+
|
|
555
|
+
while (queue.length > 0) {
|
|
556
|
+
const current = queue.shift()!;
|
|
557
|
+
toRemove.push(current.id);
|
|
558
|
+
// Add children to queue for BFS traversal
|
|
559
|
+
queue.push(...current.children);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Batch delete all collected keys (atomic update)
|
|
563
|
+
for (const id of toRemove) {
|
|
564
|
+
this.nodeMap.delete(id);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
onEvent(event: WorkflowEvent): void {
|
|
569
|
+
// Handle structural events with incremental updates
|
|
570
|
+
switch (event.type) {
|
|
571
|
+
case 'childAttached':
|
|
572
|
+
// Keep existing logic - already optimal O(k)
|
|
573
|
+
this.buildNodeMap(event.child);
|
|
574
|
+
break;
|
|
575
|
+
|
|
576
|
+
case 'childDetached':
|
|
577
|
+
// NEW: Incremental subtree removal
|
|
578
|
+
this.removeSubtreeNodes(event.childId);
|
|
579
|
+
break;
|
|
580
|
+
|
|
581
|
+
case 'treeUpdated':
|
|
582
|
+
// NEW: Update root reference only
|
|
583
|
+
this.root = event.root;
|
|
584
|
+
break;
|
|
585
|
+
|
|
586
|
+
default:
|
|
587
|
+
// Non-structural events - no map update needed
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Always forward to event stream (existing behavior)
|
|
592
|
+
this.events.next(event);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
onTreeChanged(root: WorkflowNode): void {
|
|
596
|
+
// All tree changes now handled incrementally in onEvent()
|
|
597
|
+
// Just update root reference if different
|
|
598
|
+
if (this.root !== root) {
|
|
599
|
+
this.root = root;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
**Improvements**:
|
|
605
|
+
- Incremental updates instead of full rebuilds
|
|
606
|
+
- O(k) complexity for subtree operations instead of O(n)
|
|
607
|
+
- BFS traversal prevents stack overflow on deep trees
|
|
608
|
+
- Atomic batch updates for consistency
|
|
609
|
+
|
|
610
|
+
#### Performance Impact
|
|
611
|
+
|
|
612
|
+
| Operation | Before | After | Improvement |
|
|
613
|
+
|-----------|--------|-------|-------------|
|
|
614
|
+
| Attach child | O(k) | O(k) | No change (already optimal) |
|
|
615
|
+
| Detach child | O(n) | O(k) | Significant improvement |
|
|
616
|
+
| Tree update | O(n) | O(1) | Major improvement |
|
|
617
|
+
|
|
618
|
+
k = number of nodes in subtree, n = total nodes in tree
|
|
619
|
+
|
|
620
|
+
#### Migration Steps
|
|
621
|
+
|
|
622
|
+
1. **No migration required** - Transparent performance improvement
|
|
623
|
+
2. All existing code benefits from optimization
|
|
624
|
+
3. No API changes
|
|
625
|
+
|
|
626
|
+
#### Test Coverage
|
|
627
|
+
|
|
628
|
+
- **Test file**: [src/__tests__/unit/tree-debugger-incremental.test.ts](src/__tests__/unit/tree-debugger-incremental.test.ts)
|
|
629
|
+
- **Benchmarks**: [src/__tests__/adversarial/node-map-update-benchmarks.test.ts](src/__tests__/adversarial/node-map-update-benchmarks.test.ts)
|
|
630
|
+
- **Coverage**:
|
|
631
|
+
- Incremental node map updates
|
|
632
|
+
- Subtree removal
|
|
633
|
+
- Performance benchmarks
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
### 3. Workflow Name Validation
|
|
638
|
+
|
|
639
|
+
**Issue**: The Workflow constructor accepted any string as a name, including empty strings and whitespace-only names, which could cause confusion and bugs.
|
|
640
|
+
|
|
641
|
+
**Severity**: **Minor** - Input validation improvement.
|
|
642
|
+
|
|
643
|
+
**Impact**:
|
|
644
|
+
- Empty or whitespace names made debugging difficult
|
|
645
|
+
- No maximum length constraint could cause UI issues
|
|
646
|
+
- Invalid names in logs and tree visualization
|
|
647
|
+
|
|
648
|
+
**Location**: [src/core/workflow.ts:98-107](src/core/workflow.ts#L98-L107)
|
|
649
|
+
|
|
650
|
+
#### Implementation
|
|
651
|
+
|
|
652
|
+
```typescript
|
|
653
|
+
// Validate workflow name (after config is normalized)
|
|
654
|
+
if (typeof this.config.name === 'string') {
|
|
655
|
+
const trimmedName = this.config.name.trim();
|
|
656
|
+
if (trimmedName.length === 0) {
|
|
657
|
+
throw new Error('Workflow name cannot be empty or whitespace only');
|
|
658
|
+
}
|
|
659
|
+
if (this.config.name.length > 100) {
|
|
660
|
+
throw new Error('Workflow name cannot exceed 100 characters');
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**Validation Rules**:
|
|
666
|
+
- Empty string names are rejected
|
|
667
|
+
- Whitespace-only names are rejected
|
|
668
|
+
- Names longer than 100 characters are rejected
|
|
669
|
+
- Validation happens during construction (fail-fast)
|
|
670
|
+
|
|
671
|
+
#### Migration Steps
|
|
672
|
+
|
|
673
|
+
1. **Potentially breaking** - Existing code with invalid workflow names will throw
|
|
674
|
+
2. Review any workflow names that might be empty or >100 characters
|
|
675
|
+
3. Test your workflow construction
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
// This will now throw
|
|
679
|
+
new Workflow(''); // Error: Workflow name cannot be empty or whitespace only
|
|
680
|
+
new Workflow(' '); // Error: Workflow name cannot be empty or whitespace only
|
|
681
|
+
new Workflow('a'.repeat(101)); // Error: Workflow name cannot exceed 100 characters
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
#### Test Coverage
|
|
685
|
+
|
|
686
|
+
- **Test file**: [src/__tests__/unit/workflow.test.ts](src/__tests__/unit/workflow.test.ts)
|
|
687
|
+
- **Coverage**: Name validation edge cases
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
### 4. isDescendantOf Public API
|
|
692
|
+
|
|
693
|
+
**Issue**: The `isDescendantOf()` helper method was private, but it's a useful utility for checking workflow hierarchy relationships. Making it public enables users to validate workflow topology.
|
|
694
|
+
|
|
695
|
+
**Severity**: **Minor** - API enhancement, additive change.
|
|
696
|
+
|
|
697
|
+
**Impact**:
|
|
698
|
+
- Users can now check workflow hierarchy relationships
|
|
699
|
+
- Enables validation before attaching to prevent circular references
|
|
700
|
+
- Useful for conditional logic based on hierarchy position
|
|
701
|
+
|
|
702
|
+
**Location**: [src/core/workflow.ts:201-219](src/core/workflow.ts#L201-L219)
|
|
703
|
+
|
|
704
|
+
#### Implementation
|
|
705
|
+
|
|
706
|
+
```typescript
|
|
707
|
+
/**
|
|
708
|
+
* Check if this workflow is a descendant of the given ancestor workflow.
|
|
709
|
+
*
|
|
710
|
+
* Traverses the parent chain upward looking for the ancestor reference.
|
|
711
|
+
* Uses a visited Set to detect cycles during traversal. This method provides
|
|
712
|
+
* a convenient way to check workflow hierarchy relationships without manually
|
|
713
|
+
* traversing the parent chain.
|
|
714
|
+
*
|
|
715
|
+
* @warning This method reveals workflow hierarchy information. If your
|
|
716
|
+
* application exposes workflows via an API, ensure you implement proper
|
|
717
|
+
* access control to prevent unauthorized topology discovery. Note that
|
|
718
|
+
* the `parent` and `children` properties are already public, so this
|
|
719
|
+
* method does not expose any new information beyond what is currently
|
|
720
|
+
* accessible.
|
|
721
|
+
*
|
|
722
|
+
* **Time Complexity**: O(d) where d is the depth of the hierarchy
|
|
723
|
+
* **Space Complexity**: O(d) for the visited Set in worst case (cycle detection)
|
|
724
|
+
*
|
|
725
|
+
* @example Check if a workflow belongs to a specific hierarchy
|
|
726
|
+
* ```typescript
|
|
727
|
+
* const root = new Workflow('root');
|
|
728
|
+
* const child = new Workflow('child', { parent: root });
|
|
729
|
+
*
|
|
730
|
+
* if (child.isDescendantOf(root)) {
|
|
731
|
+
* console.log('Child is in root hierarchy');
|
|
732
|
+
* }
|
|
733
|
+
* ```
|
|
734
|
+
*
|
|
735
|
+
* @example Validate before attaching to prevent circular references
|
|
736
|
+
* ```typescript
|
|
737
|
+
* if (!newChild.isDescendantOf(parent)) {
|
|
738
|
+
* parent.attachChild(newChild);
|
|
739
|
+
* } else {
|
|
740
|
+
* throw new Error('Would create circular reference');
|
|
741
|
+
* }
|
|
742
|
+
* ```
|
|
743
|
+
*
|
|
744
|
+
* @example Check for ancestor relationship in conditional logic
|
|
745
|
+
* ```typescript
|
|
746
|
+
* const isInProductionBranch = workflow.isDescendantOf(productionRoot);
|
|
747
|
+
* if (isInProductionBranch) {
|
|
748
|
+
* // Apply production-specific logic
|
|
749
|
+
* }
|
|
750
|
+
* ```
|
|
751
|
+
*
|
|
752
|
+
* @param ancestor - The potential ancestor workflow to check
|
|
753
|
+
* @returns true if ancestor is found in parent chain, false otherwise
|
|
754
|
+
* @throws {Error} If a cycle is detected during traversal (indicates corrupted tree structure)
|
|
755
|
+
*/
|
|
756
|
+
public isDescendantOf(ancestor: Workflow): boolean {
|
|
757
|
+
const visited = new Set<Workflow>();
|
|
758
|
+
let current: Workflow | null = this.parent;
|
|
759
|
+
|
|
760
|
+
while (current !== null) {
|
|
761
|
+
if (visited.has(current)) {
|
|
762
|
+
throw new Error('Circular parent-child relationship detected');
|
|
763
|
+
}
|
|
764
|
+
visited.add(current);
|
|
765
|
+
|
|
766
|
+
if (current === ancestor) {
|
|
767
|
+
return true;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
current = current.parent;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
**Features**:
|
|
778
|
+
- Cycle detection during traversal
|
|
779
|
+
- Comprehensive JSDoc with security warning
|
|
780
|
+
- Multiple usage examples
|
|
781
|
+
- Time/space complexity documentation
|
|
782
|
+
|
|
783
|
+
#### Migration Steps
|
|
784
|
+
|
|
785
|
+
1. **No migration required** - Additive public API
|
|
786
|
+
2. Use for hierarchy validation:
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
// Prevent circular references
|
|
790
|
+
if (!child.isDescendantOf(parent)) {
|
|
791
|
+
parent.attachChild(child);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Conditional logic based on hierarchy
|
|
795
|
+
if (workflow.isDescendantOf(productionRoot)) {
|
|
796
|
+
// Production-specific handling
|
|
797
|
+
}
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
#### Test Coverage
|
|
801
|
+
|
|
802
|
+
- **Test file**: [src/__tests__/unit/workflow-isDescendantOf.test.ts](src/__tests__/unit/workflow-isDescendantOf.test.ts)
|
|
803
|
+
- **Coverage**:
|
|
804
|
+
- Direct parent relationship
|
|
805
|
+
- Deep ancestor relationship
|
|
806
|
+
- Non-ancestor relationship
|
|
807
|
+
- Circular reference detection
|
|
808
|
+
- Edge cases
|
|
809
|
+
|
|
810
|
+
---
|
|
811
|
+
|
|
812
|
+
## Breaking Changes & Migration
|
|
813
|
+
|
|
814
|
+
### Summary
|
|
815
|
+
|
|
816
|
+
**Breaking Changes**: None
|
|
817
|
+
|
|
818
|
+
All bug fixes in this release are backward compatible. The fixes either:
|
|
819
|
+
1. Correct PRD violations (old behavior was "buggy" per specification)
|
|
820
|
+
2. Add new features that are opt-in
|
|
821
|
+
3. Improve performance transparently
|
|
822
|
+
|
|
823
|
+
### Important Notes
|
|
824
|
+
|
|
825
|
+
1. **WorkflowLogger.child()**: The old `child(parentLogId: string)` API continues to work. The new `child(meta: Partial<LogEntry>)` is additive.
|
|
826
|
+
|
|
827
|
+
2. **Promise.allSettled**: The change from `Promise.all()` to `Promise.allSettled()` maintains the same observable behavior for most use cases.
|
|
828
|
+
|
|
829
|
+
3. **ErrorMergeStrategy**: This is an opt-in feature. Default behavior (throw first error) is unchanged.
|
|
830
|
+
|
|
831
|
+
4. **Workflow name validation**: This may throw for existing code with invalid names, but such names were already problematic.
|
|
832
|
+
|
|
833
|
+
---
|
|
834
|
+
|
|
835
|
+
## Testing & Validation
|
|
836
|
+
|
|
837
|
+
### Test Coverage Summary
|
|
838
|
+
|
|
839
|
+
#### New Test Files (12 files)
|
|
840
|
+
|
|
841
|
+
| Test File | Coverage | Lines |
|
|
842
|
+
|-----------|----------|-------|
|
|
843
|
+
| [src/__tests__/unit/logger.test.ts](src/__tests__/unit/logger.test.ts) | WorkflowLogger.child() signature fix | 294 |
|
|
844
|
+
| [src/__tests__/adversarial/concurrent-task-failures.test.ts](src/__tests__/adversarial/concurrent-task-failures.test.ts) | Promise.allSettled concurrent failures | - |
|
|
845
|
+
| [src/__tests__/adversarial/error-merge-strategy.test.ts](src/__tests__/adversarial/error-merge-strategy.test.ts) | ErrorMergeStrategy functionality | - |
|
|
846
|
+
| [src/__tests__/unit/tree-debugger-incremental.test.ts](src/__tests__/unit/tree-debugger-incremental.test.ts) | Incremental node map updates | - |
|
|
847
|
+
| [src/__tests__/adversarial/node-map-update-benchmarks.test.ts](src/__tests__/adversarial/node-map-update-benchmarks.test.ts) | Performance benchmarks | - |
|
|
848
|
+
| [src/__tests__/integration/observer-logging.test.ts](src/__tests__/integration/observer-logging.test.ts) | Observer logger replacement | - |
|
|
849
|
+
| [src/__tests__/unit/workflow.test.ts](src/__tests__/unit/workflow.test.ts) | Workflow name validation | - |
|
|
850
|
+
| [src/__tests__/unit/workflow-isDescendantOf.test.ts](src/__tests__/unit/workflow-isDescendantOf.test.ts) | Public isDescendantOf API | - |
|
|
851
|
+
| [src/__tests__/adversarial/parent-validation.test.ts](src/__tests__/adversarial/parent-validation.test.ts) | Parent validation | - |
|
|
852
|
+
| [src/__tests__/adversarial/circular-reference.test.ts](src/__tests__/adversarial/circular-reference.test.ts) | Circular reference detection | - |
|
|
853
|
+
| [src/__tests__/adversarial/complex-circular-reference.test.ts](src/__tests__/adversarial/complex-circular-reference.test.ts) | Deep circular reference scenarios | - |
|
|
854
|
+
| [src/__tests__/integration/workflow-reparenting.test.ts](src/__tests__/integration/workflow-reparenting.test.ts) | Reparenting workflow tests | - |
|
|
855
|
+
|
|
856
|
+
### Validation Commands
|
|
857
|
+
|
|
858
|
+
Run the following commands to verify all bug fixes:
|
|
859
|
+
|
|
860
|
+
```bash
|
|
861
|
+
# Run all tests
|
|
862
|
+
npm test
|
|
863
|
+
|
|
864
|
+
# Run specific test suites
|
|
865
|
+
npm test -- logger.test.ts
|
|
866
|
+
npm test -- concurrent-task-failures.test.ts
|
|
867
|
+
npm test -- error-merge-strategy.test.ts
|
|
868
|
+
npm test -- tree-debugger-incremental.test.ts
|
|
869
|
+
|
|
870
|
+
# Run with coverage
|
|
871
|
+
npm test -- --coverage
|
|
872
|
+
|
|
873
|
+
# Run linter
|
|
874
|
+
npm run lint
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
### Expected Results
|
|
878
|
+
|
|
879
|
+
- All tests pass: **PASS**
|
|
880
|
+
- Test coverage: **100%** for fixed code paths
|
|
881
|
+
- Linter: **No errors**
|
|
882
|
+
- Type check: **No errors**
|
|
883
|
+
|
|
884
|
+
---
|
|
885
|
+
|
|
886
|
+
## Severity Classification Reference
|
|
887
|
+
|
|
888
|
+
### Decision Tree
|
|
889
|
+
|
|
890
|
+
```
|
|
891
|
+
Is it a PRD violation?
|
|
892
|
+
├─ Yes → CRITICAL
|
|
893
|
+
└─ No
|
|
894
|
+
└─ Does it break core functionality?
|
|
895
|
+
├─ Yes → MAJOR
|
|
896
|
+
└─ No
|
|
897
|
+
└─ Is there an easy workaround?
|
|
898
|
+
├─ Yes → MINOR
|
|
899
|
+
└─ No → MAJOR
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
### Definitions
|
|
903
|
+
|
|
904
|
+
| Severity | Definition | Examples |
|
|
905
|
+
|----------|-----------|----------|
|
|
906
|
+
| **Critical** | PRD compliance violations, security issues, data loss | Wrong method signatures, missing required features |
|
|
907
|
+
| **Major** | Core functionality broken, missing features, significant reliability issues | Missing error aggregation, concurrent execution failures |
|
|
908
|
+
| **Minor** | Small issues, easy workarounds, doesn't impact core features | Logging consistency, performance optimizations, API enhancements |
|
|
909
|
+
|
|
910
|
+
---
|
|
911
|
+
|
|
912
|
+
## References
|
|
913
|
+
|
|
914
|
+
### Project Documentation
|
|
915
|
+
|
|
916
|
+
- **[PRD.md](PRD.md)** - Product Requirements Document (source of truth for specifications)
|
|
917
|
+
- [Section 12.1: WorkflowLogger.child() specification](PRD.md#L303)
|
|
918
|
+
- [Section 10: Error Merge Strategy](PRD.md#L246-L254)
|
|
919
|
+
- [Section 8.1: @Step decorator with trackTiming](PRD.md#L183)
|
|
920
|
+
|
|
921
|
+
- **[CHANGELOG.md](CHANGELOG.md)** - Project changelog with formatting patterns
|
|
922
|
+
|
|
923
|
+
### Implementation Files
|
|
924
|
+
|
|
925
|
+
#### Critical Fixes
|
|
926
|
+
- [src/core/logger.ts:98-111](src/core/logger.ts#L98-L111) - WorkflowLogger.child() signature fix
|
|
927
|
+
|
|
928
|
+
#### Major Fixes
|
|
929
|
+
- [src/decorators/task.ts:112-142](src/decorators/task.ts#L112-L142) - Promise.allSettled implementation
|
|
930
|
+
- [src/types/decorators.ts:25-32](src/types/decorators.ts#L25-L32) - TaskOptions with errorMergeStrategy
|
|
931
|
+
- [src/utils/workflow-error-utils.ts:23-56](src/utils/workflow-error-utils.ts#L23-L56) - mergeWorkflowErrors implementation
|
|
932
|
+
- [src/decorators/step.ts:94-101](src/decorators/step.ts#L94-L101) - trackTiming default behavior
|
|
933
|
+
|
|
934
|
+
#### Minor Fixes
|
|
935
|
+
- [src/core/workflow.ts:426, 444](src/core/workflow.ts#L426) - Observer logging with logger
|
|
936
|
+
- [src/core/workflow.ts:98-107](src/core/workflow.ts#L98-L107) - Workflow name validation
|
|
937
|
+
- [src/core/workflow.ts:201-219](src/core/workflow.ts#L201-L219) - Public isDescendantOf API
|
|
938
|
+
- [src/debugger/tree-debugger.ts:65-84, 92-117](src/debugger/tree-debugger.ts#L65-L84) - Tree debugger optimization
|
|
939
|
+
|
|
940
|
+
### Test Files
|
|
941
|
+
|
|
942
|
+
- [src/__tests__/unit/logger.test.ts](src/__tests__/unit/logger.test.ts) - WorkflowLogger child() tests (294 lines)
|
|
943
|
+
- [src/__tests__/adversarial/concurrent-task-failures.test.ts](src/__tests__/adversarial/concurrent-task-failures.test.ts) - Concurrent failure tests
|
|
944
|
+
- [src/__tests__/adversarial/error-merge-strategy.test.ts](src/__tests__/adversarial/error-merge-strategy.test.ts) - Error merge strategy tests
|
|
945
|
+
- [src/__tests__/unit/tree-debugger-incremental.test.ts](src/__tests__/unit/tree-debugger-incremental.test.ts) - Incremental update tests
|
|
946
|
+
- [src/__tests__/adversarial/node-map-update-benchmarks.test.ts](src/__tests__/adversarial/node-map-update-benchmarks.test.ts) - Performance benchmarks
|
|
947
|
+
- [src/__tests__/integration/observer-logging.test.ts](src/__tests__/integration/observer-logging.test.ts) - Observer logging tests
|
|
948
|
+
- [src/__tests__/unit/workflow.test.ts](src/__tests__/unit/workflow.test.ts) - Workflow validation tests
|
|
949
|
+
- [src/__tests__/unit/workflow-isDescendantOf.test.ts](src/__tests__/unit/workflow-isDescendantOf.test.ts) - isDescendantOf API tests
|
|
950
|
+
|
|
951
|
+
### External References
|
|
952
|
+
|
|
953
|
+
- [Keep a Changelog - Format](https://keepachangelog.com/en/1.1.0/) - Industry standard changelog format
|
|
954
|
+
- [Keep a Changelog - Example](https://keepachangelog.com/en/1.1.0/#example) - Example showing proper formatting
|
|
955
|
+
- [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) - Versioning specification (bug fixes = PATCH version)
|
|
956
|
+
|
|
957
|
+
---
|
|
958
|
+
|
|
959
|
+
**Document Version**: 1.0
|
|
960
|
+
**Last Updated**: 2026-01-12
|
|
961
|
+
**Status**: Complete
|