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,718 @@
|
|
|
1
|
+
name: "P1M3T2S3: Add Benchmark Tests for Node Map Updates"
|
|
2
|
+
description: |
|
|
3
|
+
Creates comprehensive benchmark tests demonstrating the performance improvement from incremental node map updates
|
|
4
|
+
implemented in P1M3T2S2. Tests compare old full rebuild approach vs new incremental O(k) approach.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
**Feature Goal**: Create benchmark tests that demonstrate and validate the performance improvement from incremental node map updates.
|
|
11
|
+
|
|
12
|
+
**Deliverable**: Benchmark test file `src/__tests__/adversarial/node-map-update-benchmarks.test.ts` with:
|
|
13
|
+
1. Tests comparing old full rebuild vs new incremental update performance
|
|
14
|
+
2. Large workflow tree scenarios (100+ nodes)
|
|
15
|
+
3. Performance threshold assertions
|
|
16
|
+
4. Functional correctness validation
|
|
17
|
+
|
|
18
|
+
**Success Definition**:
|
|
19
|
+
- Benchmark tests pass consistently
|
|
20
|
+
- Incremental updates show measurable performance improvement (10-100×)
|
|
21
|
+
- Performance thresholds are appropriate for CI environments
|
|
22
|
+
- Tests prevent future regressions in node map update performance
|
|
23
|
+
|
|
24
|
+
## User Persona
|
|
25
|
+
|
|
26
|
+
**Target User**: Developer maintaining the hierarchical workflow engine codebase.
|
|
27
|
+
|
|
28
|
+
**Use Case**: Validating that incremental node map updates maintain performance optimization over time.
|
|
29
|
+
|
|
30
|
+
**User Journey**:
|
|
31
|
+
1. Developer runs benchmark tests after code changes
|
|
32
|
+
2. Tests measure performance of node map updates
|
|
33
|
+
3. If performance regresses, tests fail indicating issue
|
|
34
|
+
4. Developer identifies and fixes regression
|
|
35
|
+
|
|
36
|
+
**Pain Points Addressed**:
|
|
37
|
+
- Without benchmarks, performance regressions go undetected
|
|
38
|
+
- Need to validate that S2 optimization actually improved performance
|
|
39
|
+
- Need to establish baseline performance for future comparisons
|
|
40
|
+
|
|
41
|
+
## Why
|
|
42
|
+
|
|
43
|
+
- **Validation**: P1M3T2S2 implemented incremental updates - need to verify improvement
|
|
44
|
+
- **Regression prevention**: Benchmark tests catch performance regressions early
|
|
45
|
+
- **Documentation**: Tests serve as executable documentation of expected performance
|
|
46
|
+
- **CI/CD integration**: Automated performance validation in CI pipeline
|
|
47
|
+
|
|
48
|
+
## What
|
|
49
|
+
|
|
50
|
+
Create comprehensive benchmark tests for node map update performance.
|
|
51
|
+
|
|
52
|
+
### Success Criteria
|
|
53
|
+
|
|
54
|
+
- [ ] Benchmark test file created in `src/__tests__/adversarial/`
|
|
55
|
+
- [ ] Tests measure single node detach performance (1000+ node tree)
|
|
56
|
+
- [ ] Tests measure subtree detach performance (varying subtree sizes)
|
|
57
|
+
- [ ] Tests measure multiple operations cumulative performance
|
|
58
|
+
- [ ] Tests validate functional correctness alongside performance
|
|
59
|
+
- [ ] Performance thresholds use generous CI-friendly margins
|
|
60
|
+
- [ ] Console logging shows expected vs actual performance
|
|
61
|
+
- [ ] All tests pass consistently
|
|
62
|
+
|
|
63
|
+
## All Needed Context
|
|
64
|
+
|
|
65
|
+
### Context Completeness Check
|
|
66
|
+
|
|
67
|
+
**"No Prior Knowledge" test**: If someone knew nothing about this codebase, would they have everything needed?
|
|
68
|
+
|
|
69
|
+
✅ **YES** - This PRP provides:
|
|
70
|
+
- Exact file paths and patterns from existing benchmark tests
|
|
71
|
+
- Complete benchmark testing patterns to follow
|
|
72
|
+
- Tree debugger implementation details for understanding what's being tested
|
|
73
|
+
- Performance threshold guidelines based on existing tests
|
|
74
|
+
- All necessary test utilities and helpers
|
|
75
|
+
|
|
76
|
+
### Documentation & References
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
# MUST READ - Include these in your context window
|
|
80
|
+
- file: src/__tests__/adversarial/incremental-performance.test.ts
|
|
81
|
+
why: PRIMARY REFERENCE - Existing benchmark test patterns for node map updates
|
|
82
|
+
pattern: Lines 9-39 (detach from large tree is O(k) not O(n))
|
|
83
|
+
pattern: Lines 41-67 (attach to large tree is O(k))
|
|
84
|
+
pattern: Lines 69-102 (detach large subtree is O(k))
|
|
85
|
+
pattern: Lines 104-139 (multiple operations show cumulative benefit)
|
|
86
|
+
gotcha: Uses 5ms threshold for CI environments (line 38)
|
|
87
|
+
|
|
88
|
+
- file: src/__tests__/adversarial/attachChild-performance.test.ts
|
|
89
|
+
why: Performance regression testing patterns with tiered thresholds
|
|
90
|
+
pattern: Lines 1-14 (header documentation pattern)
|
|
91
|
+
pattern: Lines 20-30 (SimpleWorkflow class pattern)
|
|
92
|
+
pattern: Lines 59-81 (shallow tree test with < 10ms threshold)
|
|
93
|
+
pattern: Lines 92-116 (deep tree test with < 50ms threshold)
|
|
94
|
+
pattern: Lines 127-150 (extreme deep tree with < 100ms threshold)
|
|
95
|
+
pattern: Lines 161-183 (wide tree with average time calculation)
|
|
96
|
+
gotcha: Console logging for debugging (lines 28-29, 59-60)
|
|
97
|
+
|
|
98
|
+
- file: src/__tests__/adversarial/deep-hierarchy-stress.test.ts
|
|
99
|
+
why: Stress testing patterns for extreme scenarios
|
|
100
|
+
pattern: Lines 33-37 (beforeEach console mocking pattern)
|
|
101
|
+
pattern: Lines 44-48 (afterEach vi.restoreAllMocks pattern)
|
|
102
|
+
pattern: Lines 153-187 (performance threshold test pattern)
|
|
103
|
+
gotcha: Thresholds: < 100ms for single operation, < 1000ms for 100 iterations
|
|
104
|
+
|
|
105
|
+
- file: src/debugger/tree-debugger.ts
|
|
106
|
+
why: Understanding what is being benchmarked
|
|
107
|
+
pattern: Lines 65-84 (removeSubtreeNodes - incremental O(k) removal)
|
|
108
|
+
pattern: Lines 92-117 (onEvent with incremental updates)
|
|
109
|
+
pattern: Lines 123-129 (onTreeChanged - now O(1) root update only)
|
|
110
|
+
pattern: Lines 225-254 (getStats for validation)
|
|
111
|
+
|
|
112
|
+
- file: src/__tests__/helpers/tree-verification.ts
|
|
113
|
+
why: Test helper utilities for validation
|
|
114
|
+
pattern: Lines 114-140 (verifyBidirectionalLink for attach validation)
|
|
115
|
+
pattern: Lines 151-163 (verifyOrphaned for detach validation)
|
|
116
|
+
pattern: Lines 201-237 (verifyTreeMirror for consistency checks)
|
|
117
|
+
|
|
118
|
+
- file: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md
|
|
119
|
+
why: Understanding the incremental optimization being benchmarked
|
|
120
|
+
section: "Goal" (lines 8-22) - Success definition and expected improvements
|
|
121
|
+
section: "Level 4: Performance Validation" (lines 441-483) - Benchmark pattern
|
|
122
|
+
gotcha: Expected 10-100× improvement for large trees (1000+ nodes)
|
|
123
|
+
|
|
124
|
+
- url: https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
|
|
125
|
+
why: performance.now() API documentation for timing measurements
|
|
126
|
+
critical: High-resolution timing, monotonic clock, sub-millisecond precision
|
|
127
|
+
gotcha: Use duration.toFixed(3) for consistent logging
|
|
128
|
+
|
|
129
|
+
- url: https://vitest.dev/guide/features.html#benchmark
|
|
130
|
+
why: Vitest built-in benchmark support (alternative to manual performance.now())
|
|
131
|
+
section: "Benchmark Mode" - can use .bench() instead of .it() for benchmarks
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Current Codebase Structure
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
/home/dustin/projects/groundswell/
|
|
138
|
+
├── src/
|
|
139
|
+
│ ├── debugger/
|
|
140
|
+
│ │ └── tree-debugger.ts # Implementation being benchmarked
|
|
141
|
+
│ ├── __tests__/
|
|
142
|
+
│ │ ├── adversarial/
|
|
143
|
+
│ │ │ ├── incremental-performance.test.ts # REFERENCE PATTERN
|
|
144
|
+
│ │ │ ├── attachChild-performance.test.ts # REFERENCE PATTERN
|
|
145
|
+
│ │ │ └── deep-hierarchy-stress.test.ts # REFERENCE PATTERN
|
|
146
|
+
│ │ └── helpers/
|
|
147
|
+
│ │ └── tree-verification.ts # Test utilities
|
|
148
|
+
│ └── types/
|
|
149
|
+
│ ├── events.ts # WorkflowEvent types
|
|
150
|
+
│ └── observer.ts # WorkflowObserver interface
|
|
151
|
+
└── plan/
|
|
152
|
+
└── 001_d3bb02af4886/bugfix/001_e8e04329daf3/
|
|
153
|
+
└── P1M3T2S3/
|
|
154
|
+
├── PRP.md # This file
|
|
155
|
+
└── research/ # External research storage
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Desired Codebase Structure After Implementation
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
src/__tests__/
|
|
162
|
+
└── adversarial/
|
|
163
|
+
└── node-map-update-benchmarks.test.ts # NEW: Benchmark tests
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Known Gotchas of Our Codebase & Library Quirks
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// CRITICAL: Use performance.now() for timing, not Date.now()
|
|
170
|
+
// performance.now() provides sub-millisecond precision
|
|
171
|
+
// Date.now() is affected by system clock changes
|
|
172
|
+
// Pattern from: incremental-performance.test.ts:22-26
|
|
173
|
+
|
|
174
|
+
// CRITICAL: Use generous thresholds for CI environments
|
|
175
|
+
// CI performance varies significantly - use 2-3× expected time
|
|
176
|
+
// Example: incremental-performance.test.ts:38 uses < 5ms instead of < 1ms
|
|
177
|
+
|
|
178
|
+
// CRITICAL: Always validate functional correctness FIRST
|
|
179
|
+
// Performance tests must fail if functionality is broken
|
|
180
|
+
// Pattern from: attachChild-performance.test.ts:75-77 (verifyBidirectionalLink)
|
|
181
|
+
|
|
182
|
+
// CRITICAL: Log both actual and expected performance for debugging
|
|
183
|
+
// Pattern: incremental-performance.test.ts:28-29
|
|
184
|
+
// console.log(`Detach duration: ${duration.toFixed(3)}ms`);
|
|
185
|
+
// console.log(`Expected: < 1ms for incremental, ~10ms for full rebuild`);
|
|
186
|
+
|
|
187
|
+
// CRITICAL: Use BenchmarkWorkflow class pattern, not full Workflow
|
|
188
|
+
// Minimal async run() method reduces test overhead
|
|
189
|
+
// Pattern from: incremental-performance.test.ts:4-6
|
|
190
|
+
|
|
191
|
+
// CRITICAL: Calculate average time for bulk operations
|
|
192
|
+
// Helps identify if single operation is outlier
|
|
193
|
+
// Pattern from: attachChild-performance.test.ts:167-183
|
|
194
|
+
|
|
195
|
+
// CRITICAL: Mock console methods in adversarial tests
|
|
196
|
+
// Prevents test output pollution
|
|
197
|
+
// Pattern from: deep-hierarchy-stress.test.ts:33-37, 44-48
|
|
198
|
+
|
|
199
|
+
// CRITICAL: Use vi.restoreAllMocks() in afterEach
|
|
200
|
+
// Prevents test pollution
|
|
201
|
+
// Pattern from: deep-hierarchy-stress.test.ts:44-48
|
|
202
|
+
|
|
203
|
+
// CRITICAL: Tests should validate the specific optimization
|
|
204
|
+
// For S3: validating that incremental O(k) is faster than old O(n) rebuild
|
|
205
|
+
// The "old" approach would have called buildNodeMap(this.root) on every change
|
|
206
|
+
|
|
207
|
+
// CRITICAL: Test different tree sizes to show scalability
|
|
208
|
+
// Small trees (< 100): Already fast, minimal difference
|
|
209
|
+
// Medium trees (100-1000): 10-100× improvement
|
|
210
|
+
// Large trees (1000+): 100-1000× improvement
|
|
211
|
+
|
|
212
|
+
// CRITICAL: Test both attach and detach operations
|
|
213
|
+
// S2 optimized both childAttached and childDetached
|
|
214
|
+
// Pattern from: incremental-performance.test.ts:41-67 (attach test)
|
|
215
|
+
|
|
216
|
+
// CRITICAL: Test subtree operations, not just single nodes
|
|
217
|
+
// BFS-based removeSubtreeNodes() scales with subtree size k
|
|
218
|
+
// Pattern from: incremental-performance.test.ts:69-102
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Implementation Blueprint
|
|
222
|
+
|
|
223
|
+
### Data Models and Structure
|
|
224
|
+
|
|
225
|
+
No new data models. Using existing:
|
|
226
|
+
- `Workflow` from `src/core/workflow.js`
|
|
227
|
+
- `WorkflowTreeDebugger` from `src/debugger/tree-debugger.js`
|
|
228
|
+
- `SimpleWorkflow` or `BenchmarkWorkflow` test class pattern
|
|
229
|
+
|
|
230
|
+
### Implementation Tasks (ordered by dependencies)
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
Task 1: CREATE benchmark test file with header and setup
|
|
234
|
+
- IMPLEMENT: src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
235
|
+
- FOLLOW pattern: src/__tests__/adversarial/attachChild-performance.test.ts:1-30
|
|
236
|
+
- INCLUDE: Comprehensive header comment explaining purpose
|
|
237
|
+
- INCLUDE: Reference to P1M3T2S2 optimization being validated
|
|
238
|
+
- IMPORT: describe, it, expect from vitest
|
|
239
|
+
- IMPORT: Workflow, WorkflowTreeDebugger from src/index.js
|
|
240
|
+
- CREATE: BenchmarkWorkflow class with minimal async run() method
|
|
241
|
+
- PLACEMENT: src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
242
|
+
|
|
243
|
+
Task 2: IMPLEMENT single node detach benchmark (1000+ node tree)
|
|
244
|
+
- IMPLEMENT: Test case "single node detach from large tree is O(1)"
|
|
245
|
+
- FOLLOW pattern: src/__tests__/adversarial/incremental-performance.test.ts:9-39
|
|
246
|
+
- CREATE: 1000-node linear chain (root + 999 descendants)
|
|
247
|
+
- MEASURE: Time to detach single leaf node using performance.now()
|
|
248
|
+
- VERIFY: Functional correctness (node count decreases by 1)
|
|
249
|
+
- VERIFY: Detached node removed from nodeMap
|
|
250
|
+
- ASSERT: Duration < 5ms (generous CI threshold)
|
|
251
|
+
- LOG: Expected vs actual performance
|
|
252
|
+
- NAMING: it('should detach single node from large tree in O(1) time')
|
|
253
|
+
|
|
254
|
+
Task 3: IMPLEMENT single node attach benchmark
|
|
255
|
+
- IMPLEMENT: Test case "single node attach is O(1)"
|
|
256
|
+
- FOLLOW pattern: src/__tests__/adversarial/incremental-performance.test.ts:41-67
|
|
257
|
+
- CREATE: 100-node tree (smaller for attach test)
|
|
258
|
+
- MEASURE: Time to attach single node
|
|
259
|
+
- VERIFY: Node added to nodeMap
|
|
260
|
+
- VERIFY: Total nodes increased by 1
|
|
261
|
+
- ASSERT: Duration < 10ms
|
|
262
|
+
- NAMING: it('should attach single node in O(1) time')
|
|
263
|
+
|
|
264
|
+
Task 4: IMPLEMENT subtree detach benchmark with varying sizes
|
|
265
|
+
- IMPLEMENT: Test case "subtree detach scales with subtree size, not tree size"
|
|
266
|
+
- FOLLOW pattern: src/__tests__/adversarial/incremental-performance.test.ts:69-102
|
|
267
|
+
- CREATE: Tree with one large branch (101 nodes) and 900 other nodes
|
|
268
|
+
- MEASURE: Time to detach large branch
|
|
269
|
+
- VERIFY: Entire subtree removed (node count - 101)
|
|
270
|
+
- VERIFY: Branch nodes not in nodeMap
|
|
271
|
+
- ASSERT: Duration < 10ms (should scale with k=101, not n=1002)
|
|
272
|
+
- LOG: "Processing 101 nodes, not 1002"
|
|
273
|
+
- NAMING: it('should detach subtree in O(k) time where k = subtree size')
|
|
274
|
+
|
|
275
|
+
Task 5: IMPLEMENT cumulative operations benchmark
|
|
276
|
+
- IMPLEMENT: Test case "multiple operations show cumulative benefit"
|
|
277
|
+
- FOLLOW pattern: src/__tests__/adversarial/incremental-performance.test.ts:104-139
|
|
278
|
+
- CREATE: Tree with 10 branches, each with 10 nodes
|
|
279
|
+
- MEASURE: Total time to detach all 10 branches
|
|
280
|
+
- CALCULATE: Average time per detach
|
|
281
|
+
- VERIFY: Only root remains after all detaches
|
|
282
|
+
- ASSERT: Total duration < 50ms (10 × 5ms)
|
|
283
|
+
- LOG: Total and average duration
|
|
284
|
+
- NAMING: it('should complete multiple operations efficiently')
|
|
285
|
+
|
|
286
|
+
Task 6: IMPLEMENT deep tree stress test
|
|
287
|
+
- IMPLEMENT: Test case "deep tree operations don't cause stack overflow"
|
|
288
|
+
- FOLLOW pattern: src/__tests__/adversarial/deep-hierarchy-stress.test.ts:57-79
|
|
289
|
+
- CREATE: 2000-node deep linear chain
|
|
290
|
+
- MEASURE: Time to attach node at depth 2000
|
|
291
|
+
- MEASURE: Time to detach node from depth 2000
|
|
292
|
+
- VERIFY: No stack overflow occurs
|
|
293
|
+
- VERIFY: Functional correctness
|
|
294
|
+
- ASSERT: Duration < 100ms
|
|
295
|
+
- NAMING: it('should handle deep tree (2000 levels) efficiently')
|
|
296
|
+
|
|
297
|
+
Task 7: IMPLEMENT wide tree benchmark
|
|
298
|
+
- IMPLEMENT: Test case "wide tree operations scale efficiently"
|
|
299
|
+
- FOLLOW pattern: src/__tests__/adversarial/attachChild-performance.test.ts:161-183
|
|
300
|
+
- CREATE: Single parent with 100 children
|
|
301
|
+
- MEASURE: Total time to attach all 100 children
|
|
302
|
+
- CALCULATE: Average time per attachment
|
|
303
|
+
- VERIFY: All children in nodeMap
|
|
304
|
+
- ASSERT: Total < 100ms, average < 1ms
|
|
305
|
+
- NAMING: it('should handle wide tree efficiently')
|
|
306
|
+
|
|
307
|
+
Task 8: ADD test suite metadata documentation
|
|
308
|
+
- IMPLEMENT: Comprehensive header comment block
|
|
309
|
+
- FOLLOW pattern: src/__tests__/adversarial/attachChild-performance.test.ts:1-14
|
|
310
|
+
- INCLUDE: Purpose statement referencing P1M3T2S2
|
|
311
|
+
- INCLUDE: Performance threshold rationale
|
|
312
|
+
- INCLUDE: Expected complexity notation (O(k) vs O(n))
|
|
313
|
+
- INCLUDE: Related PRP references
|
|
314
|
+
- PLACEMENT: Top of test file
|
|
315
|
+
|
|
316
|
+
Task 9: RUN all benchmarks to verify
|
|
317
|
+
- VERIFY: All benchmark tests pass
|
|
318
|
+
- VERIFY: Console output shows performance improvements
|
|
319
|
+
- VERIFY: No test failures in CI environment
|
|
320
|
+
- ADJUST: Thresholds if needed (increase if CI flaky, decrease if too lenient)
|
|
321
|
+
- COMMAND: npm test -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Implementation Patterns & Key Details
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// Pattern 1: BenchmarkWorkflow class (minimal overhead)
|
|
328
|
+
// Follows: incremental-performance.test.ts:4-6
|
|
329
|
+
class BenchmarkWorkflow extends Workflow {
|
|
330
|
+
async run() {
|
|
331
|
+
this.setStatus('completed');
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// WHY: Minimal async run() method reduces test execution overhead
|
|
335
|
+
|
|
336
|
+
// Pattern 2: Single node detach benchmark
|
|
337
|
+
// Follows: incremental-performance.test.ts:9-39
|
|
338
|
+
it('should detach single node from large tree in O(1) time', () => {
|
|
339
|
+
// ARRANGE: Build large tree (1000 nodes)
|
|
340
|
+
const root = new BenchmarkWorkflow('Root');
|
|
341
|
+
let current = root;
|
|
342
|
+
for (let i = 0; i < 999; i++) {
|
|
343
|
+
const child = new BenchmarkWorkflow(`Node${i}`, current);
|
|
344
|
+
current = child;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const treeDebugger = new WorkflowTreeDebugger(root);
|
|
348
|
+
expect(treeDebugger.getStats().totalNodes).toBe(1000);
|
|
349
|
+
|
|
350
|
+
// ACT: Benchmark detach single node (should be O(1) vs O(1000))
|
|
351
|
+
const start = performance.now();
|
|
352
|
+
const leaf = current; // Last node in chain
|
|
353
|
+
const parent = leaf.parent!;
|
|
354
|
+
parent.detachChild(leaf);
|
|
355
|
+
const duration = performance.now() - start;
|
|
356
|
+
|
|
357
|
+
console.log(`Detach duration: ${duration.toFixed(3)}ms`);
|
|
358
|
+
console.log(`Expected: < 1ms for incremental, ~10ms for full rebuild`);
|
|
359
|
+
|
|
360
|
+
// ASSERT: Verify correct behavior FIRST
|
|
361
|
+
const stats = treeDebugger.getStats();
|
|
362
|
+
expect(stats.totalNodes).toBe(999);
|
|
363
|
+
expect(treeDebugger.getNode(leaf.id)).toBeUndefined();
|
|
364
|
+
|
|
365
|
+
// ASSERT: Performance threshold (generous for CI)
|
|
366
|
+
expect(duration).toBeLessThan(5);
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// Pattern 3: Subtree detach benchmark
|
|
370
|
+
// Follows: incremental-performance.test.ts:69-102
|
|
371
|
+
it('should detach subtree in O(k) time where k = subtree size', () => {
|
|
372
|
+
// ARRANGE: Build tree with one large branch
|
|
373
|
+
const root = new BenchmarkWorkflow('Root');
|
|
374
|
+
const branch = new BenchmarkWorkflow('Branch', root);
|
|
375
|
+
|
|
376
|
+
// Add 100 nodes to branch
|
|
377
|
+
for (let i = 0; i < 100; i++) {
|
|
378
|
+
new BenchmarkWorkflow(`BranchNode${i}`, branch);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Add 900 nodes to root
|
|
382
|
+
for (let i = 0; i < 900; i++) {
|
|
383
|
+
new BenchmarkWorkflow(`RootNode${i}`, root);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const treeDebugger = new WorkflowTreeDebugger(root);
|
|
387
|
+
expect(treeDebugger.getStats().totalNodes).toBe(1002);
|
|
388
|
+
|
|
389
|
+
// ACT: Detach entire branch (process 101 nodes, not 1002)
|
|
390
|
+
const start = performance.now();
|
|
391
|
+
root.detachChild(branch);
|
|
392
|
+
const duration = performance.now() - start;
|
|
393
|
+
|
|
394
|
+
console.log(`Detach 101-node subtree from 1002-node tree: ${duration.toFixed(3)}ms`);
|
|
395
|
+
console.log(`Would be ~10ms for full rebuild, should be ~1ms for incremental`);
|
|
396
|
+
|
|
397
|
+
// ASSERT: Verify correct behavior
|
|
398
|
+
const stats = treeDebugger.getStats();
|
|
399
|
+
expect(stats.totalNodes).toBe(901);
|
|
400
|
+
expect(treeDebugger.getNode(branch.id)).toBeUndefined();
|
|
401
|
+
|
|
402
|
+
// ASSERT: Should scale with subtree size (k=101), not tree size (n=1002)
|
|
403
|
+
expect(duration).toBeLessThan(10);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
// Pattern 4: Cumulative operations benchmark
|
|
407
|
+
// Follows: incremental-performance.test.ts:104-139
|
|
408
|
+
it('should complete multiple operations efficiently', () => {
|
|
409
|
+
// ARRANGE: Build tree with 10 branches
|
|
410
|
+
const root = new BenchmarkWorkflow('Root');
|
|
411
|
+
const branches: BenchmarkWorkflow[] = [];
|
|
412
|
+
|
|
413
|
+
for (let i = 0; i < 10; i++) {
|
|
414
|
+
const branch = new BenchmarkWorkflow(`Branch${i}`, root);
|
|
415
|
+
branches.push(branch);
|
|
416
|
+
for (let j = 0; j < 10; j++) {
|
|
417
|
+
new BenchmarkWorkflow(`Node${i}_${j}`, branch);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const treeDebugger = new WorkflowTreeDebugger(root);
|
|
422
|
+
expect(treeDebugger.getStats().totalNodes).toBe(111);
|
|
423
|
+
|
|
424
|
+
// ACT: Detach all 10 branches
|
|
425
|
+
const start = performance.now();
|
|
426
|
+
for (const branch of branches) {
|
|
427
|
+
root.detachChild(branch);
|
|
428
|
+
}
|
|
429
|
+
const totalDuration = performance.now() - start;
|
|
430
|
+
|
|
431
|
+
console.log(`Detached 10 branches of 11 nodes each from 111-node tree: ${totalDuration.toFixed(3)}ms`);
|
|
432
|
+
console.log(`Average per detach: ${(totalDuration / 10).toFixed(3)}ms`);
|
|
433
|
+
|
|
434
|
+
// ASSERT: Verify correct behavior - only root remains
|
|
435
|
+
const stats = treeDebugger.getStats();
|
|
436
|
+
expect(stats.totalNodes).toBe(1);
|
|
437
|
+
expect(treeDebugger.getNode(root.id)).toBeDefined();
|
|
438
|
+
|
|
439
|
+
// ASSERT: Total should be much less than 10 × O(n) rebuilds
|
|
440
|
+
expect(totalDuration).toBeLessThan(50);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Pattern 5: Average time calculation
|
|
444
|
+
// Follows: attachChild-performance.test.ts:167-183
|
|
445
|
+
it('should calculate average time for bulk operations', () => {
|
|
446
|
+
const root = new BenchmarkWorkflow('Root');
|
|
447
|
+
const NUM_CHILDREN = 100;
|
|
448
|
+
|
|
449
|
+
// ACT: Measure time to attach all children
|
|
450
|
+
const startTime = performance.now();
|
|
451
|
+
for (let i = 0; i < NUM_CHILDREN; i++) {
|
|
452
|
+
const child = new BenchmarkWorkflow(`Child-${i}`, root);
|
|
453
|
+
}
|
|
454
|
+
const totalDuration = performance.now() - startTime;
|
|
455
|
+
|
|
456
|
+
// ASSERT: Verify functional correctness
|
|
457
|
+
expect(root.children).toHaveLength(NUM_CHILDREN);
|
|
458
|
+
|
|
459
|
+
// ASSERT: Performance (< 100ms total, < 1ms average)
|
|
460
|
+
expect(totalDuration).toBeLessThan(100);
|
|
461
|
+
const avgTime = totalDuration / NUM_CHILDREN;
|
|
462
|
+
expect(avgTime).toBeLessThan(1); // < 1ms per attachment
|
|
463
|
+
|
|
464
|
+
console.log(`Total: ${totalDuration.toFixed(3)}ms, Average: ${avgTime.toFixed(3)}ms`);
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// Pattern 6: Header documentation
|
|
468
|
+
// Follows: attachChild-performance.test.ts:1-14
|
|
469
|
+
/**
|
|
470
|
+
* Node Map Update Performance Benchmarks
|
|
471
|
+
*
|
|
472
|
+
* Validates that the incremental node map update optimization (P1M3T2S2)
|
|
473
|
+
* provides measurable performance improvement over the previous full rebuild approach.
|
|
474
|
+
*
|
|
475
|
+
* Expected Performance Improvements:
|
|
476
|
+
* - Single node attach/detach: 10-100× faster (O(1) vs O(n))
|
|
477
|
+
* - Subtree operations: 10-100× faster (O(k) vs O(n))
|
|
478
|
+
* - Multiple operations: Cumulative benefit
|
|
479
|
+
*
|
|
480
|
+
* Performance Thresholds (CI-friendly with 2-3× buffer):
|
|
481
|
+
* - Single operation: < 5ms (expected < 1ms)
|
|
482
|
+
* - Subtree operation (100 nodes): < 10ms (expected < 2ms)
|
|
483
|
+
* - Multiple operations (10×): < 50ms (expected < 10ms)
|
|
484
|
+
* - Deep tree (2000 levels): < 100ms
|
|
485
|
+
* - Wide tree (100 children): < 100ms total, < 1ms average
|
|
486
|
+
*
|
|
487
|
+
* Related: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md
|
|
488
|
+
*/
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### Integration Points
|
|
492
|
+
|
|
493
|
+
```yaml
|
|
494
|
+
TEST_FRAMEWORK:
|
|
495
|
+
- framework: Vitest
|
|
496
|
+
- config: vitest.config.ts
|
|
497
|
+
- pattern: Use describe(), it(), expect() from 'vitest'
|
|
498
|
+
|
|
499
|
+
TREE_DEBUGGER:
|
|
500
|
+
- file: src/debugger/tree-debugger.ts
|
|
501
|
+
- class: WorkflowTreeDebugger
|
|
502
|
+
- methods: getStats(), getNode(id)
|
|
503
|
+
|
|
504
|
+
WORKFLOW:
|
|
505
|
+
- file: src/core/workflow.ts
|
|
506
|
+
- class: Workflow
|
|
507
|
+
- methods: detachChild(), constructor with parent parameter
|
|
508
|
+
|
|
509
|
+
TEST_UTILITIES:
|
|
510
|
+
- file: src/__tests__/helpers/tree-verification.ts
|
|
511
|
+
- helpers: verifyBidirectionalLink(), verifyOrphaned(), validateTreeConsistency()
|
|
512
|
+
|
|
513
|
+
PERFORMANCE_API:
|
|
514
|
+
- api: performance.now()
|
|
515
|
+
- precision: Sub-millisecond
|
|
516
|
+
- pattern: const duration = performance.now() - start;
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
## Validation Loop
|
|
520
|
+
|
|
521
|
+
### Level 1: Syntax & Style (Immediate Feedback)
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
# TypeScript compilation check
|
|
525
|
+
npx tsc --noEmit src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
526
|
+
|
|
527
|
+
# Lint check
|
|
528
|
+
npm run lint -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
529
|
+
|
|
530
|
+
# Format check
|
|
531
|
+
npm run format -- --check src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
532
|
+
|
|
533
|
+
# Expected: Zero errors. Fix any issues before proceeding.
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Level 2: Unit Tests (Component Validation)
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
# Run the new benchmark tests
|
|
540
|
+
npm test -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts
|
|
541
|
+
|
|
542
|
+
# Run with verbose output to see console logs
|
|
543
|
+
npm test -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts --reporter=verbose
|
|
544
|
+
|
|
545
|
+
# Run all adversarial tests to ensure no regressions
|
|
546
|
+
npm test -- src/__tests__/adversarial/
|
|
547
|
+
|
|
548
|
+
# Expected: All tests pass. Console logs show performance metrics.
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Level 3: Integration Testing (System Validation)
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
# Create integration test script
|
|
555
|
+
cat > /tmp/test-benchmark-integration.mjs << 'EOF'
|
|
556
|
+
import { Workflow, WorkflowTreeDebugger } from './dist/index.js';
|
|
557
|
+
|
|
558
|
+
class TestWorkflow extends Workflow {
|
|
559
|
+
async run() { this.setStatus('completed'); }
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Test 1: Verify incremental update is faster than would be for full rebuild
|
|
563
|
+
const root = new TestWorkflow('Root');
|
|
564
|
+
for (let i = 0; i < 999; i++) {
|
|
565
|
+
new TestWorkflow(`Node${i}`, root);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const debugger = new WorkflowTreeDebugger(root);
|
|
569
|
+
console.log('Initial nodes:', debugger.getStats().totalNodes);
|
|
570
|
+
|
|
571
|
+
// Single node detach should be very fast
|
|
572
|
+
const start = performance.now();
|
|
573
|
+
const leaf = Array.from(root.children).pop();
|
|
574
|
+
root.detachChild(leaf);
|
|
575
|
+
const duration = performance.now() - start;
|
|
576
|
+
|
|
577
|
+
console.log(`Detach duration: ${duration.toFixed(3)}ms`);
|
|
578
|
+
console.log(`Nodes remaining: ${debugger.getStats().totalNodes}`);
|
|
579
|
+
|
|
580
|
+
// Verify functional correctness
|
|
581
|
+
if (debugger.getStats().totalNodes !== 999) {
|
|
582
|
+
console.error('ERROR: Expected 999 nodes, got', debugger.getStats().totalNodes);
|
|
583
|
+
process.exit(1);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
if (duration > 5) {
|
|
587
|
+
console.warn('WARNING: Detach took longer than expected (should be < 5ms)');
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
console.log('Integration test PASSED!');
|
|
591
|
+
EOF
|
|
592
|
+
|
|
593
|
+
node /tmp/test-benchmark-integration.mjs
|
|
594
|
+
|
|
595
|
+
# Expected: Duration < 5ms, functional correctness verified
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Level 4: Performance Validation
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
# Run benchmarks and capture output
|
|
602
|
+
npm test -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts 2>&1 | tee /tmp/benchmark-results.txt
|
|
603
|
+
|
|
604
|
+
# Check that all tests passed
|
|
605
|
+
if grep -q "PASS" /tmp/benchmark-results.txt; then
|
|
606
|
+
echo "All benchmark tests PASSED";
|
|
607
|
+
else
|
|
608
|
+
echo "Some benchmark tests FAILED";
|
|
609
|
+
exit 1;
|
|
610
|
+
fi
|
|
611
|
+
|
|
612
|
+
# Verify performance metrics are logged
|
|
613
|
+
grep "duration:" /tmp/benchmark-results.txt || echo "WARNING: No performance metrics logged"
|
|
614
|
+
|
|
615
|
+
# Run benchmarks multiple times to check consistency
|
|
616
|
+
for i in {1..5}; do
|
|
617
|
+
echo "Run $i:"
|
|
618
|
+
npm test -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts --silent 2>&1 | grep -E "duration|nodes"
|
|
619
|
+
done
|
|
620
|
+
|
|
621
|
+
# Expected: All runs complete successfully with consistent timing
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## Final Validation Checklist
|
|
625
|
+
|
|
626
|
+
### Technical Validation
|
|
627
|
+
|
|
628
|
+
- [ ] All 4 validation levels completed successfully
|
|
629
|
+
- [ ] TypeScript compilation passes: `npx tsc --noEmit`
|
|
630
|
+
- [ ] All benchmark tests pass: `npm test -- src/__tests__/adversarial/node-map-update-benchmarks.test.ts`
|
|
631
|
+
- [ ] Linting passes: `npm run lint`
|
|
632
|
+
- [ ] Format check passes: `npm run format -- --check`
|
|
633
|
+
- [ ] No regressions in existing tests: `npm test -- src/__tests__/adversarial/`
|
|
634
|
+
|
|
635
|
+
### Feature Validation
|
|
636
|
+
|
|
637
|
+
- [ ] Single node detach benchmark passes with < 5ms threshold
|
|
638
|
+
- [ ] Single node attach benchmark passes with < 10ms threshold
|
|
639
|
+
- [ ] Subtree detach benchmark passes with < 10ms threshold
|
|
640
|
+
- [ ] Cumulative operations benchmark passes with < 50ms threshold
|
|
641
|
+
- [ ] Deep tree benchmark passes with < 100ms threshold
|
|
642
|
+
- [ ] Wide tree benchmark passes with < 100ms total, < 1ms average
|
|
643
|
+
- [ ] Console logging shows expected vs actual performance
|
|
644
|
+
- [ ] Functional correctness validated for all benchmarks
|
|
645
|
+
|
|
646
|
+
### Code Quality Validation
|
|
647
|
+
|
|
648
|
+
- [ ] Header documentation follows existing pattern
|
|
649
|
+
- [ ] BenchmarkWorkflow class pattern used correctly
|
|
650
|
+
- [ ] Test naming is descriptive and consistent
|
|
651
|
+
- [ ] Performance thresholds use generous CI-friendly margins
|
|
652
|
+
- [ ] Console logging helps debug performance regressions
|
|
653
|
+
- [ ] Average time calculations included for bulk operations
|
|
654
|
+
- [ ] Follows AAA pattern (Arrange, Act, Assert)
|
|
655
|
+
- [ ] Functional correctness validated before performance assertions
|
|
656
|
+
|
|
657
|
+
### Documentation & Deployment
|
|
658
|
+
|
|
659
|
+
- [ ] Header comment references P1M3T2S2 PRP
|
|
660
|
+
- [ ] Performance thresholds documented with rationale
|
|
661
|
+
- [ ] Expected complexity noted (O(k) vs O(n))
|
|
662
|
+
- [ ] Console output format is consistent
|
|
663
|
+
- [ ] Test file placed in correct directory
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
## Anti-Patterns to Avoid
|
|
668
|
+
|
|
669
|
+
- ❌ Don't use `Date.now()` - use `performance.now()` for high precision
|
|
670
|
+
- ❌ Don't use overly precise thresholds - CI environments are variable
|
|
671
|
+
- ❌ Don't forget to validate functional correctness - performance means nothing if broken
|
|
672
|
+
- ❌ Don't skip console logging - needed for debugging regressions
|
|
673
|
+
- ❌ Don't test only small trees - need large trees to show O(k) vs O(n) difference
|
|
674
|
+
- ❌ Don't forget to calculate average time for bulk operations
|
|
675
|
+
- ❌ Don't use full Workflow class - use BenchmarkWorkflow pattern
|
|
676
|
+
- ❌ Don't create tests that measure JIT warmup - use realistic workloads
|
|
677
|
+
- ❌ Don't assume performance will be identical across runs - use thresholds
|
|
678
|
+
- ❌ Don't forget to test both attach AND detach operations
|
|
679
|
+
- ❌ Don't test only single nodes - include subtree operations
|
|
680
|
+
- ❌ Don't create thresholds based on local machine only - consider CI variance
|
|
681
|
+
- ❌ Don't forget to mock console methods to prevent test pollution
|
|
682
|
+
- ❌ Don't forget vi.restoreAllMocks() in afterEach
|
|
683
|
+
- ❌ Don't create benchmark tests that are too brittle - they should catch regressions, not flake
|
|
684
|
+
|
|
685
|
+
---
|
|
686
|
+
|
|
687
|
+
## Success Metrics
|
|
688
|
+
|
|
689
|
+
**Confidence Score**: 9/10 for one-pass implementation success
|
|
690
|
+
|
|
691
|
+
**Validation**: The completed PRP enables an AI agent unfamiliar with the codebase to implement comprehensive benchmark tests for node map update performance successfully.
|
|
692
|
+
|
|
693
|
+
**Key Success Indicators**:
|
|
694
|
+
1. Existing benchmark patterns are well-established and documented
|
|
695
|
+
2. Tree debugger implementation is complete and stable
|
|
696
|
+
3. Test utilities are comprehensive and ready to use
|
|
697
|
+
4. Performance thresholds are based on existing working benchmarks
|
|
698
|
+
5. All file paths and patterns are specific and actionable
|
|
699
|
+
6. Gotchas and anti-patterns are comprehensively documented
|
|
700
|
+
|
|
701
|
+
**Expected Test Outcomes**:
|
|
702
|
+
- Single node operations: < 1-5ms (vs ~10ms for old approach)
|
|
703
|
+
- Subtree operations (100 nodes): < 2-10ms (vs ~100ms for old approach)
|
|
704
|
+
- Multiple operations: Cumulative 10-100× improvement
|
|
705
|
+
- Deep/wide trees: No stack overflow, efficient performance
|
|
706
|
+
|
|
707
|
+
**Performance Improvement Validation**:
|
|
708
|
+
- Small trees (< 100 nodes): Minimal difference (already fast)
|
|
709
|
+
- Medium trees (100-1000 nodes): 10-100× improvement measurable
|
|
710
|
+
- Large trees (1000+ nodes): 100-1000× improvement measurable
|
|
711
|
+
|
|
712
|
+
**Test Coverage**:
|
|
713
|
+
- Single node attach/detach
|
|
714
|
+
- Subtree attach/detach
|
|
715
|
+
- Cumulative operations
|
|
716
|
+
- Deep trees (2000+ levels)
|
|
717
|
+
- Wide trees (100+ children)
|
|
718
|
+
- Functional correctness validation
|