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,558 @@
|
|
|
1
|
+
name: "P1M3T2S2: Implement Incremental Node Map Update for childDetached"
|
|
2
|
+
description: |
|
|
3
|
+
Implements incremental node map updates in WorkflowTreeDebugger to eliminate O(n) full rebuild on tree mutations.
|
|
4
|
+
Replaces current full rebuild strategy with O(k) incremental updates where k = subtree size.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
**Feature Goal**: Replace O(n) full nodeMap rebuild in `onTreeChanged()` with O(k) incremental updates for `childDetached` and `childAttached` events.
|
|
11
|
+
|
|
12
|
+
**Deliverable**: Modified `src/debugger/tree-debugger.ts` with:
|
|
13
|
+
1. New `removeSubtreeNodes(nodeId: string)` private method using BFS traversal
|
|
14
|
+
2. Updated `onEvent()` to handle `childDetached` and `childAttached` events incrementally
|
|
15
|
+
3. Simplified `onTreeChanged()` to only update root reference
|
|
16
|
+
|
|
17
|
+
**Success Definition**:
|
|
18
|
+
- `childDetached` events remove entire subtree from nodeMap in O(k) time
|
|
19
|
+
- `childAttached` events add subtree in O(k) time (existing behavior preserved)
|
|
20
|
+
- `onTreeChanged()` no longer rebuilds entire map
|
|
21
|
+
- All existing tests pass
|
|
22
|
+
- Performance improvement of 10-100× for large trees (1000+ nodes)
|
|
23
|
+
|
|
24
|
+
## User Persona
|
|
25
|
+
|
|
26
|
+
**Target User**: Developer using hierarchical workflow engine with large trees (100+ nodes) and frequent structural changes.
|
|
27
|
+
|
|
28
|
+
**Use Case**: Attaching/detaching child workflows in long-running workflows with thousands of nodes.
|
|
29
|
+
|
|
30
|
+
**User Journey**:
|
|
31
|
+
1. Developer creates workflow with 1000+ nodes
|
|
32
|
+
2. Workflow attaches/detaches child workflows during execution
|
|
33
|
+
3. Tree debugger receives tree change events
|
|
34
|
+
4. Node map updates incrementally without O(n) rebuild
|
|
35
|
+
|
|
36
|
+
**Pain Points Addressed**:
|
|
37
|
+
- Current O(n) rebuild causes noticeable lag on large trees
|
|
38
|
+
- Memory churn from `Map.clear()` + full rebuild
|
|
39
|
+
- Orphaned nodes leak in nodeMap after detach (memory leak)
|
|
40
|
+
|
|
41
|
+
## Why
|
|
42
|
+
|
|
43
|
+
- **Performance**: Current implementation causes 100-1000× slowdown on large trees with frequent structural changes
|
|
44
|
+
- **Memory leak**: `childDetached` events leave orphaned nodes in nodeMap until full rebuild
|
|
45
|
+
- **Scalability**: Full rebuild strategy doesn't scale beyond ~1000 nodes
|
|
46
|
+
- **Consistency**: `onEvent()` already handles `childAttached` incrementally - complete the pattern
|
|
47
|
+
|
|
48
|
+
## What
|
|
49
|
+
|
|
50
|
+
Modify WorkflowTreeDebugger to use incremental node map updates for tree structural changes.
|
|
51
|
+
|
|
52
|
+
### Success Criteria
|
|
53
|
+
|
|
54
|
+
- [ ] `removeSubtreeNodes(nodeId: string)` method removes entire subtree using BFS traversal
|
|
55
|
+
- [ ] `onEvent()` handles `childDetached` by calling `removeSubtreeNodes()`
|
|
56
|
+
- [ ] `onEvent()` handles `childAttached` using existing `buildNodeMap()` pattern
|
|
57
|
+
- [ ] `onTreeChanged()` only updates root reference, no rebuild
|
|
58
|
+
- [ ] All existing tests pass
|
|
59
|
+
- [ ] No memory leaks from orphaned nodes after detach
|
|
60
|
+
- [ ] Performance improvement measurable with 1000+ node trees
|
|
61
|
+
|
|
62
|
+
## All Needed Context
|
|
63
|
+
|
|
64
|
+
### Context Completeness Check
|
|
65
|
+
|
|
66
|
+
**"No Prior Knowledge" test**: If someone knew nothing about this codebase, would they have everything needed?
|
|
67
|
+
|
|
68
|
+
✅ **YES** - This PRP provides:
|
|
69
|
+
- Exact file paths and line numbers for all referenced code
|
|
70
|
+
- Complete code patterns to follow from existing codebase
|
|
71
|
+
- Specific test patterns and validation commands
|
|
72
|
+
- All architectural constraints and gotchas
|
|
73
|
+
- External research with specific URLs
|
|
74
|
+
|
|
75
|
+
### Documentation & References
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
# MUST READ - Include these in your context window
|
|
79
|
+
- url: https://react.dev/learn/render-and-commit
|
|
80
|
+
why: React's reconciliation algorithm patterns for incremental tree updates
|
|
81
|
+
critical: O(n) diffing with heuristics, key-based identification
|
|
82
|
+
|
|
83
|
+
- url: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
|
|
84
|
+
why: Map operations have O(1) complexity - validates incremental approach
|
|
85
|
+
section: "#instance-methods" (set, get, delete operations)
|
|
86
|
+
|
|
87
|
+
- file: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md
|
|
88
|
+
why: Comprehensive analysis of current onTreeChanged implementation with performance impact
|
|
89
|
+
section: "Incremental Update Opportunities" (lines 327-472)
|
|
90
|
+
gotcha: Current onEvent() already handles childAttached incrementally but onTreeChanged() rebuilds
|
|
91
|
+
|
|
92
|
+
- file: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md
|
|
93
|
+
why: External research on BFS/DFS patterns, Map performance, React reconciliation
|
|
94
|
+
section: "6. Actionable Implementation Guide" (lines 576-736)
|
|
95
|
+
|
|
96
|
+
- file: src/debugger/tree-debugger.ts
|
|
97
|
+
why: Primary file to modify - contains current implementation
|
|
98
|
+
pattern: Observer pattern with onEvent(), onTreeChanged(), buildNodeMap()
|
|
99
|
+
gotcha: buildNodeMap() is recursive - may hit stack limits on deep trees (use BFS for removal)
|
|
100
|
+
|
|
101
|
+
- file: src/types/events.ts
|
|
102
|
+
why: WorkflowEvent discriminated union - all event types defined
|
|
103
|
+
pattern: Lines 10-11 define childAttached and childDetached events
|
|
104
|
+
gotcha: childDetached only provides childId string, not full node object
|
|
105
|
+
|
|
106
|
+
- file: src/types/observer.ts
|
|
107
|
+
why: WorkflowObserver interface - must implement all methods
|
|
108
|
+
pattern: Lines 9-18 define onLog, onEvent, onStateUpdated, onTreeChanged
|
|
109
|
+
|
|
110
|
+
- file: src/__tests__/helpers/tree-verification.ts
|
|
111
|
+
why: Test helper patterns for validating tree operations
|
|
112
|
+
pattern: BFS traversal in collectAllNodes() (lines 13-32)
|
|
113
|
+
pattern: verifyOrphaned() for testing detach operations (lines 151-163)
|
|
114
|
+
|
|
115
|
+
- file: src/__tests__/unit/tree-debugger.test.ts
|
|
116
|
+
why: Existing test patterns for WorkflowTreeDebugger
|
|
117
|
+
pattern: SimpleWorkflow class pattern, observer creation helper
|
|
118
|
+
gotcha: Tests use direct node access via debugger.getNode()
|
|
119
|
+
|
|
120
|
+
- file: src/__tests__/adversarial/attachChild-performance.test.ts
|
|
121
|
+
why: Performance test patterns using performance.now()
|
|
122
|
+
pattern: Threshold-based performance assertions (< 10ms, < 50ms, etc.)
|
|
123
|
+
|
|
124
|
+
- file: src/core/workflow.ts
|
|
125
|
+
why: Understanding where events are emitted
|
|
126
|
+
pattern: Lines 300-304 (childAttached emission), 353-357 (childDetached emission)
|
|
127
|
+
pattern: Lines 367-379 (observer notification with error isolation)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Current Codebase Structure
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
/home/dustin/projects/groundswell/
|
|
134
|
+
├── src/
|
|
135
|
+
│ ├── debugger/
|
|
136
|
+
│ │ └── tree-debugger.ts # PRIMARY FILE - Modify this
|
|
137
|
+
│ ├── core/
|
|
138
|
+
│ │ └── workflow.ts # Event emission patterns
|
|
139
|
+
│ ├── types/
|
|
140
|
+
│ │ ├── events.ts # WorkflowEvent types
|
|
141
|
+
│ │ ├── observer.ts # WorkflowObserver interface
|
|
142
|
+
│ │ └── workflow.ts # WorkflowNode interface
|
|
143
|
+
│ └── __tests__/
|
|
144
|
+
│ ├── unit/
|
|
145
|
+
│ │ └── tree-debugger.test.ts # Test patterns to follow
|
|
146
|
+
│ ├── helpers/
|
|
147
|
+
│ │ └── tree-verification.ts # BFS pattern reference
|
|
148
|
+
│ └── adversarial/
|
|
149
|
+
│ └── attachChild-performance.test.ts # Performance test patterns
|
|
150
|
+
└── plan/
|
|
151
|
+
└── 001_d3bb02af4886/bugfix/001_e8e04329daf3/
|
|
152
|
+
├── docs/P1M3T2S1/analysis.md # S1 analysis - READ THIS
|
|
153
|
+
└── P1M3T2S2/
|
|
154
|
+
├── PRP.md # This file
|
|
155
|
+
└── research/
|
|
156
|
+
└── external_research.md # External patterns research
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Desired Codebase Structure After Implementation
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
src/debugger/
|
|
163
|
+
└── tree-debugger.ts # Modified with incremental updates
|
|
164
|
+
├── removeSubtreeNodes() # NEW: BFS-based subtree removal
|
|
165
|
+
├── onEvent() # MODIFIED: Handle childDetached
|
|
166
|
+
├── buildNodeMap() # UNCHANGED: Keep existing pattern
|
|
167
|
+
└── onTreeChanged() # MODIFIED: Remove full rebuild
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Known Gotchas of Our Codebase & Library Quirks
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// CRITICAL: childDetached event only provides childId, not full WorkflowNode
|
|
174
|
+
// From src/types/events.ts:11
|
|
175
|
+
// { type: 'childDetached'; parentId: string; childId: string }
|
|
176
|
+
// Must use stored node reference from nodeMap to get descendants
|
|
177
|
+
|
|
178
|
+
// CRITICAL: buildNodeMap() is recursive - may hit stack limits on deep trees
|
|
179
|
+
// From src/debugger/tree-debugger.ts:53-58
|
|
180
|
+
// Use iterative BFS for removeSubtreeNodes() to avoid stack overflow
|
|
181
|
+
|
|
182
|
+
// CRITICAL: onEvent() is called BEFORE onTreeChanged() by emitEvent()
|
|
183
|
+
// From src/core/workflow.ts:367-379
|
|
184
|
+
// Order: obs.onEvent(event) THEN obs.onTreeChanged(root)
|
|
185
|
+
// This means onEvent() must do the incremental work
|
|
186
|
+
|
|
187
|
+
// CRITICAL: Observer callbacks are wrapped in try-catch for error isolation
|
|
188
|
+
// From src/core/workflow.ts:376
|
|
189
|
+
// Observer errors don't stop workflow execution
|
|
190
|
+
|
|
191
|
+
// CRITICAL: Node tree must mirror workflow tree (1:1 correspondence)
|
|
192
|
+
// From PRD Section 12.2 and tree-verification.ts:201-237
|
|
193
|
+
// Any tree change affects both trees simultaneously
|
|
194
|
+
|
|
195
|
+
// CRITICAL: Map.set() replaces existing entries for same key
|
|
196
|
+
// From src/debugger/tree-debugger.ts:54
|
|
197
|
+
// this.nodeMap.set(node.id, node) - OK to call on already-mapped nodes
|
|
198
|
+
|
|
199
|
+
// CRITICAL: Use Map.delete() for removal, not setting to undefined
|
|
200
|
+
// Map has undefined as valid value - use delete to actually remove key
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Implementation Blueprint
|
|
204
|
+
|
|
205
|
+
### Data Models and Structure
|
|
206
|
+
|
|
207
|
+
No new data models needed. Using existing:
|
|
208
|
+
- `WorkflowNode` from `src/types/workflow.ts`
|
|
209
|
+
- `WorkflowEvent` discriminated union from `src/types/events.ts`
|
|
210
|
+
- `WorkflowObserver` interface from `src/types/observer.ts`
|
|
211
|
+
|
|
212
|
+
### Implementation Tasks (ordered by dependencies)
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
Task 1: ADD removeSubtreeNodes() private method
|
|
216
|
+
- IMPLEMENT: BFS-based subtree removal from nodeMap
|
|
217
|
+
- FOLLOW pattern: src/__tests__/helpers/tree-verification.ts:13-32 (collectAllNodes BFS)
|
|
218
|
+
- NAMING: removeSubtreeNodes(nodeId: string): void
|
|
219
|
+
- ALGORITHM:
|
|
220
|
+
1. Get node from nodeMap using nodeId
|
|
221
|
+
2. If not found, return early (already removed)
|
|
222
|
+
3. Use queue-based BFS to collect all descendant IDs
|
|
223
|
+
4. Delete all collected IDs from nodeMap
|
|
224
|
+
- GOTCHA: Use iterative BFS, not recursive (avoid stack overflow)
|
|
225
|
+
- GOTCHA: Collect all keys first, then delete (atomic update)
|
|
226
|
+
- COMPLEXITY: O(k) where k = nodes in subtree
|
|
227
|
+
- PLACEMENT: After buildNodeMap() in tree-debugger.ts
|
|
228
|
+
|
|
229
|
+
Task 2: MODIFY onEvent() to handle childDetached
|
|
230
|
+
- IMPLEMENT: switch-case for event.type dispatch
|
|
231
|
+
- FOLLOW pattern: S1 analysis lines 527-555 (recommended implementation)
|
|
232
|
+
- CURRENT: Only handles childAttached (line 68-69)
|
|
233
|
+
- ADD: case 'childDetached' -> call removeSubtreeNodes(event.childId)
|
|
234
|
+
- PRESERVE: existing childAttached handling (buildNodeMap is already optimal)
|
|
235
|
+
- GOTCHA: childDetached only provides childId string, not full node
|
|
236
|
+
- PLACEMENT: Replace existing if statement with switch statement
|
|
237
|
+
|
|
238
|
+
Task 3: MODIFY onTreeChanged() to remove full rebuild
|
|
239
|
+
- IMPLEMENT: Only update root reference if different
|
|
240
|
+
- CURRENT: Lines 80-84 - clears map and rebuilds
|
|
241
|
+
- NEW: Just update this.root if different from parameter
|
|
242
|
+
- PRESERVE: Observer interface contract (method must exist)
|
|
243
|
+
- RATIONALE: All incremental work now done in onEvent()
|
|
244
|
+
- PLACEMENT: Same location (lines 80-84)
|
|
245
|
+
|
|
246
|
+
Task 4: CREATE unit tests for incremental updates
|
|
247
|
+
- IMPLEMENT: Tests in src/__tests__/unit/tree-debugger-incremental.test.ts
|
|
248
|
+
- FOLLOW pattern: src/__tests__/unit/tree-debugger.test.ts (test structure)
|
|
249
|
+
- TEST CASES:
|
|
250
|
+
1. childDetached removes entire subtree (node + descendants)
|
|
251
|
+
2. childDetached on already-removed node is no-op
|
|
252
|
+
3. childAttached adds subtree (verify existing behavior)
|
|
253
|
+
4. onTreeChanged doesn't rebuild map
|
|
254
|
+
- NAMING: describe('Incremental Node Map Updates')
|
|
255
|
+
- PLACEMENT: New test file alongside tree-debugger.test.ts
|
|
256
|
+
|
|
257
|
+
Task 5: RUN existing test suite
|
|
258
|
+
- VERIFY: All existing tree-debugger tests pass
|
|
259
|
+
- VERIFY: No regressions in observer tests
|
|
260
|
+
- VERIFY: Tree verification helpers still work
|
|
261
|
+
- COMMAND: npm test -- src/__tests__/unit/tree-debugger.test.ts
|
|
262
|
+
- COMMAND: npm test -- src/__tests__/integration/observer-propagation.test.ts
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Implementation Patterns & Key Details
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
// Pattern 1: BFS-based subtree removal (NEW METHOD)
|
|
269
|
+
// Follows: src/__tests__/helpers/tree-verification.ts:13-32
|
|
270
|
+
private removeSubtreeNodes(nodeId: string): void {
|
|
271
|
+
const node = this.nodeMap.get(nodeId);
|
|
272
|
+
if (!node) return; // Already removed or never existed
|
|
273
|
+
|
|
274
|
+
// BFS traversal to collect all descendant IDs
|
|
275
|
+
const toRemove: string[] = [];
|
|
276
|
+
const queue: WorkflowNode[] = [node];
|
|
277
|
+
|
|
278
|
+
while (queue.length > 0) {
|
|
279
|
+
const current = queue.shift()!;
|
|
280
|
+
toRemove.push(current.id);
|
|
281
|
+
// Add children to queue for BFS traversal
|
|
282
|
+
queue.push(...current.children);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Batch delete all collected keys (atomic update)
|
|
286
|
+
for (const id of toRemove) {
|
|
287
|
+
this.nodeMap.delete(id);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// COMPLEXITY: O(k) time, O(w) space where w = max width of subtree
|
|
291
|
+
|
|
292
|
+
// Pattern 2: Event-type dispatch in onEvent() (MODIFY EXISTING)
|
|
293
|
+
// Follows: S1 analysis lines 527-555
|
|
294
|
+
onEvent(event: WorkflowEvent): void {
|
|
295
|
+
// Handle structural events with incremental updates
|
|
296
|
+
switch (event.type) {
|
|
297
|
+
case 'childAttached':
|
|
298
|
+
// Keep existing logic - already optimal O(k)
|
|
299
|
+
this.buildNodeMap(event.child);
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case 'childDetached':
|
|
303
|
+
// NEW: Incremental subtree removal
|
|
304
|
+
this.removeSubtreeNodes(event.childId);
|
|
305
|
+
break;
|
|
306
|
+
|
|
307
|
+
case 'treeUpdated':
|
|
308
|
+
// NEW: Update root reference only
|
|
309
|
+
this.root = event.root;
|
|
310
|
+
break;
|
|
311
|
+
|
|
312
|
+
default:
|
|
313
|
+
// Non-structural events - no map update needed
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Always forward to event stream (existing behavior)
|
|
318
|
+
this.events.next(event);
|
|
319
|
+
}
|
|
320
|
+
// COMPLEXITY: O(k) for structural events, O(1) for non-structural
|
|
321
|
+
|
|
322
|
+
// Pattern 3: Simplified onTreeChanged() (MODIFY EXISTING)
|
|
323
|
+
// Follows: S1 analysis lines 570-578
|
|
324
|
+
onTreeChanged(root: WorkflowNode): void {
|
|
325
|
+
// All tree changes now handled incrementally in onEvent()
|
|
326
|
+
// Just update root reference if different
|
|
327
|
+
if (this.root !== root) {
|
|
328
|
+
this.root = root;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// COMPLEXITY: O(1) - no rebuild!
|
|
332
|
+
|
|
333
|
+
// GOTCHA: Don't forget to handle treeUpdated event!
|
|
334
|
+
// Currently onTreeChanged() is called for treeUpdated events
|
|
335
|
+
// After change, onEvent() must handle treeUpdated to update root
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Integration Points
|
|
339
|
+
|
|
340
|
+
```yaml
|
|
341
|
+
EVENTS:
|
|
342
|
+
- childAttached: src/core/workflow.ts:300-304
|
|
343
|
+
- childDetached: src/core/workflow.ts:353-357
|
|
344
|
+
- treeUpdated: src/core/workflow.ts:405
|
|
345
|
+
|
|
346
|
+
OBSERVER_PATTERN:
|
|
347
|
+
- file: src/core/workflow.ts:367-379
|
|
348
|
+
- pattern: obs.onEvent(event) THEN obs.onTreeChanged(root)
|
|
349
|
+
- critical: onEvent() called first - must do incremental work
|
|
350
|
+
|
|
351
|
+
TREE_VERIFICATION:
|
|
352
|
+
- file: src/__tests__/helpers/tree-verification.ts
|
|
353
|
+
- use: verifyOrphaned() for testing detachChild
|
|
354
|
+
- use: verifyTreeMirror() for validating tree consistency
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Validation Loop
|
|
358
|
+
|
|
359
|
+
### Level 1: Syntax & Style (Immediate Feedback)
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# TypeScript compilation check
|
|
363
|
+
npx tsc --noEmit src/debugger/tree-debugger.ts
|
|
364
|
+
|
|
365
|
+
# Lint check
|
|
366
|
+
npm run lint -- src/debugger/tree-debugger.ts
|
|
367
|
+
|
|
368
|
+
# Format check
|
|
369
|
+
npm run format -- --check src/debugger/tree-debugger.ts
|
|
370
|
+
|
|
371
|
+
# Expected: Zero errors. Fix any issues before proceeding.
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Level 2: Unit Tests (Component Validation)
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Run existing tree debugger tests
|
|
378
|
+
npm test -- src/__tests__/unit/tree-debugger.test.ts
|
|
379
|
+
|
|
380
|
+
# Run new incremental update tests
|
|
381
|
+
npm test -- src/__tests__/unit/tree-debugger-incremental.test.ts
|
|
382
|
+
|
|
383
|
+
# Run observer propagation tests
|
|
384
|
+
npm test -- src/__tests__/integration/observer-propagation.test.ts
|
|
385
|
+
|
|
386
|
+
# Expected: All tests pass. If failing, debug root cause.
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Level 3: Integration Testing (System Validation)
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
# Create test script to verify behavior
|
|
393
|
+
cat > /tmp/test-incremental.mjs << 'EOF'
|
|
394
|
+
import { Workflow, WorkflowTreeDebugger } from './src/index.js';
|
|
395
|
+
|
|
396
|
+
class TestWorkflow extends Workflow {
|
|
397
|
+
async run() { this.setStatus('completed'); }
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Test 1: childDetached removes subtree
|
|
401
|
+
const root = new TestWorkflow('Root');
|
|
402
|
+
const child1 = new TestWorkflow('Child1', root);
|
|
403
|
+
const grandchild = new TestWorkflow('Grandchild', child1);
|
|
404
|
+
const child2 = new TestWorkflow('Child2', root);
|
|
405
|
+
|
|
406
|
+
const debugger = new WorkflowTreeDebugger(root);
|
|
407
|
+
|
|
408
|
+
console.log('Initial nodes:', debugger.getStats().totalNodes); // Should be 4
|
|
409
|
+
console.log('Grandchild found:', !!debugger.getNode(grandchild.id)); // true
|
|
410
|
+
|
|
411
|
+
// Detach child1 (removes child1 + grandchild)
|
|
412
|
+
root.detachChild(child1);
|
|
413
|
+
|
|
414
|
+
console.log('After detach:', debugger.getStats().totalNodes); // Should be 2
|
|
415
|
+
console.log('Grandchild removed:', !debugger.getNode(grandchild.id)); // true
|
|
416
|
+
console.log('Child1 removed:', !debugger.getNode(child1.id)); // true
|
|
417
|
+
console.log('Child2 still there:', !!debugger.getNode(child2.id)); // true
|
|
418
|
+
|
|
419
|
+
// Test 2: childAttached adds subtree
|
|
420
|
+
const child3 = new TestWorkflow('Child3', root);
|
|
421
|
+
console.log('After attach:', debugger.getStats().totalNodes); // Should be 3
|
|
422
|
+
console.log('Child3 found:', !!debugger.getNode(child3.id)); // true
|
|
423
|
+
|
|
424
|
+
console.log('✓ All tests passed!');
|
|
425
|
+
EOF
|
|
426
|
+
|
|
427
|
+
node /tmp/test-incremental.mjs
|
|
428
|
+
|
|
429
|
+
# Expected output:
|
|
430
|
+
# Initial nodes: 4
|
|
431
|
+
# Grandchild found: true
|
|
432
|
+
# After detach: 2
|
|
433
|
+
# Grandchild removed: true
|
|
434
|
+
# Child1 removed: true
|
|
435
|
+
# Child2 still there: true
|
|
436
|
+
# After attach: 3
|
|
437
|
+
# Child3 found: true
|
|
438
|
+
# ✓ All tests passed!
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Level 4: Performance Validation
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
# Create performance benchmark
|
|
445
|
+
cat > /tmp/benchmark-incremental.mjs << 'EOF'
|
|
446
|
+
import { Workflow, WorkflowTreeDebugger } from './src/index.js';
|
|
447
|
+
|
|
448
|
+
class TestWorkflow extends Workflow {
|
|
449
|
+
async run() { this.setStatus('completed'); }
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Build large tree (1000 nodes)
|
|
453
|
+
const root = new TestWorkflow('Root');
|
|
454
|
+
let current = root;
|
|
455
|
+
for (let i = 0; i < 999; i++) {
|
|
456
|
+
const child = new TestWorkflow(`Node${i}`, current);
|
|
457
|
+
current = child;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const debugger = new WorkflowTreeDebugger(root);
|
|
461
|
+
console.log('Total nodes:', debugger.getStats().totalNodes);
|
|
462
|
+
|
|
463
|
+
// Benchmark: Detach single node (should be O(1) vs O(1000))
|
|
464
|
+
const start = performance.now();
|
|
465
|
+
const leaf = current; // Last node in chain
|
|
466
|
+
const parent = leaf.parent!;
|
|
467
|
+
parent.detachChild(leaf);
|
|
468
|
+
const duration = performance.now() - start;
|
|
469
|
+
|
|
470
|
+
console.log(`Detach duration: ${duration.toFixed(3)}ms`);
|
|
471
|
+
console.log(`Expected: < 1ms for incremental, ~10ms for full rebuild`);
|
|
472
|
+
|
|
473
|
+
// Verify correct behavior
|
|
474
|
+
const stats = debugger.getStats();
|
|
475
|
+
console.log('Nodes after detach:', stats.totalNodes); // Should be 999
|
|
476
|
+
console.log('Leaf removed:', !debugger.getNode(leaf.id)); // true
|
|
477
|
+
EOF
|
|
478
|
+
|
|
479
|
+
node /tmp/benchmark-incremental.mjs
|
|
480
|
+
|
|
481
|
+
# Expected: Detach duration < 1ms (vs ~10ms for full rebuild)
|
|
482
|
+
# Speedup: 10-100× for single node detach from 1000-node tree
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Final Validation Checklist
|
|
486
|
+
|
|
487
|
+
### Technical Validation
|
|
488
|
+
|
|
489
|
+
- [ ] All 4 validation levels completed successfully
|
|
490
|
+
- [ ] TypeScript compilation passes: `npx tsc --noEmit`
|
|
491
|
+
- [ ] All tests pass: `npm test -- src/__tests__/unit/tree-debugger*.test.ts`
|
|
492
|
+
- [ ] Linting passes: `npm run lint`
|
|
493
|
+
- [ ] Format check passes: `npm run format -- --check`
|
|
494
|
+
|
|
495
|
+
### Feature Validation
|
|
496
|
+
|
|
497
|
+
- [ ] `removeSubtreeNodes()` method implemented with BFS traversal
|
|
498
|
+
- [ ] `onEvent()` handles `childDetached` events
|
|
499
|
+
- [ ] `onEvent()` handles `childAttached` events (existing preserved)
|
|
500
|
+
- [ ] `onEvent()` handles `treeUpdated` events
|
|
501
|
+
- [ ] `onTreeChanged()` no longer rebuilds map
|
|
502
|
+
- [ ] Detached subtree fully removed (node + descendants)
|
|
503
|
+
- [ ] No orphaned nodes leak in nodeMap
|
|
504
|
+
- [ ] Performance improvement measurable (10-100× for large trees)
|
|
505
|
+
|
|
506
|
+
### Code Quality Validation
|
|
507
|
+
|
|
508
|
+
- [ ] Follows existing codebase patterns (BFS from tree-verification.ts)
|
|
509
|
+
- [ ] Method naming matches conventions (camelCase, descriptive)
|
|
510
|
+
- [ ] File placement correct (tree-debugger.ts only modification)
|
|
511
|
+
- [ ] No recursive methods added (BFS is iterative)
|
|
512
|
+
- [ ] Error handling graceful (node not found = no-op)
|
|
513
|
+
|
|
514
|
+
### Edge Cases Covered
|
|
515
|
+
|
|
516
|
+
- [ ] Detaching already-removed node is no-op
|
|
517
|
+
- [ ] Detaching node with many descendants removes all
|
|
518
|
+
- [ ] Attaching node with many descendants adds all
|
|
519
|
+
- [ ] Multiple rapid attach/detach operations work correctly
|
|
520
|
+
- [ ] Deep trees (1000+ depth) don't cause stack overflow
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Anti-Patterns to Avoid
|
|
525
|
+
|
|
526
|
+
- ❌ Don't use recursive DFS for `removeSubtreeNodes()` - use iterative BFS
|
|
527
|
+
- ❌ Don't delete nodes one-by-one during traversal - collect all keys first
|
|
528
|
+
- ❌ Don't rebuild entire map in `onTreeChanged()` - defeats purpose
|
|
529
|
+
- ❌ Don't forget to handle `treeUpdated` event in `onEvent()`
|
|
530
|
+
- ❌ Don't assume `nodeMap.get()` returns non-null - check for undefined
|
|
531
|
+
- ❌ Don't modify `buildNodeMap()` - it's already optimal for addition
|
|
532
|
+
- ❌ Don't add new public methods - keep implementation private
|
|
533
|
+
- ❌ Don't create new Map on each update - mutate existing Map
|
|
534
|
+
- ❌ Don't use `Map.clear()` in any code path - causes GC churn
|
|
535
|
+
- ❌ Don't forget to forward events to `this.events.next()` - breaks event stream
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## Success Metrics
|
|
540
|
+
|
|
541
|
+
**Confidence Score**: 9/10 for one-pass implementation success
|
|
542
|
+
|
|
543
|
+
**Validation**: The completed PRP enables an AI agent unfamiliar with the codebase to implement incremental node map updates successfully using only the PRP content and codebase access.
|
|
544
|
+
|
|
545
|
+
**Key Success Indicators**:
|
|
546
|
+
1. S1 analysis provides complete current implementation analysis
|
|
547
|
+
2. External research provides proven patterns (React reconciliation, BFS traversal)
|
|
548
|
+
3. Codebase has existing BFS pattern to follow (tree-verification.ts)
|
|
549
|
+
4. Test patterns are well-established
|
|
550
|
+
5. All file paths and line numbers are specific and actionable
|
|
551
|
+
6. Gotchas and anti-patterns are comprehensively documented
|
|
552
|
+
|
|
553
|
+
**Estimated Performance Impact**:
|
|
554
|
+
- Small trees (< 100 nodes): Minimal improvement (already fast)
|
|
555
|
+
- Medium trees (100-1000 nodes): 10-100× improvement on structural changes
|
|
556
|
+
- Large trees (1000+ nodes): 100-1000× improvement on structural changes
|
|
557
|
+
|
|
558
|
+
**Expected Test Coverage**: 100% of new code paths with unit tests
|