groundswell 0.0.2 → 1.0.0
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/LICENSE +21 -0
- package/README.md +26 -9
- package/dist/cache/cache-key.d.ts +86 -0
- package/dist/cache/cache-key.d.ts.map +1 -0
- package/dist/cache/cache-key.js +204 -0
- package/dist/cache/cache-key.js.map +1 -0
- package/dist/cache/cache.d.ts +104 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +179 -0
- package/dist/cache/cache.js.map +1 -0
- package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/core/agent.d.ts +203 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +833 -0
- package/dist/core/agent.js.map +1 -0
- package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +80 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/event-tree.d.ts +72 -0
- package/dist/core/event-tree.d.ts.map +1 -0
- package/dist/core/event-tree.js +211 -0
- package/dist/core/event-tree.js.map +1 -0
- package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
- package/dist/core/factory.d.ts.map +1 -0
- package/dist/core/factory.js +110 -0
- package/dist/core/factory.js.map +1 -0
- package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +50 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +91 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp-handler.d.ts +127 -0
- package/dist/core/mcp-handler.d.ts.map +1 -0
- package/dist/core/mcp-handler.js +323 -0
- package/dist/core/mcp-handler.js.map +1 -0
- package/dist/core/prompt.d.ts +80 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +120 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/workflow-context.d.ts +61 -0
- package/dist/core/workflow-context.d.ts.map +1 -0
- package/dist/core/workflow-context.js +358 -0
- package/dist/core/workflow-context.js.map +1 -0
- package/dist/core/workflow.d.ts +543 -0
- package/dist/core/workflow.d.ts.map +1 -0
- package/dist/core/workflow.js +986 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/debugger/event-replayer.d.ts +422 -0
- package/dist/debugger/event-replayer.d.ts.map +1 -0
- package/dist/debugger/event-replayer.js +639 -0
- package/dist/debugger/event-replayer.js.map +1 -0
- package/dist/debugger/index.d.ts +2 -0
- package/dist/debugger/index.d.ts.map +1 -0
- package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
- package/dist/debugger/index.js.map +1 -0
- package/dist/debugger/tree-debugger.d.ts +240 -0
- package/dist/debugger/tree-debugger.d.ts.map +1 -0
- package/dist/debugger/tree-debugger.js +620 -0
- package/dist/debugger/tree-debugger.js.map +1 -0
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/observed-state.d.ts +32 -0
- package/dist/decorators/observed-state.d.ts.map +1 -0
- package/dist/decorators/observed-state.js +79 -0
- package/dist/decorators/observed-state.js.map +1 -0
- package/dist/decorators/step.d.ts +15 -0
- package/dist/decorators/step.d.ts.map +1 -0
- package/dist/decorators/step.js +192 -0
- package/dist/decorators/step.js.map +1 -0
- package/dist/decorators/task.d.ts +50 -0
- package/dist/decorators/task.d.ts.map +1 -0
- package/dist/decorators/task.js +118 -0
- package/dist/decorators/task.js.map +1 -0
- package/dist/examples/index.d.ts +3 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/{src/examples/index.ts → dist/examples/index.js} +1 -0
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/tdd-orchestrator.d.ts +15 -0
- package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
- package/dist/examples/tdd-orchestrator.js +121 -0
- package/dist/examples/tdd-orchestrator.js.map +1 -0
- package/dist/examples/test-cycle-workflow.d.ts +14 -0
- package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
- package/dist/examples/test-cycle-workflow.js +116 -0
- package/dist/examples/test-cycle-workflow.js.map +1 -0
- package/dist/harnesses/claude-code-harness.d.ts +391 -0
- package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
- package/dist/harnesses/claude-code-harness.js +1076 -0
- package/dist/harnesses/claude-code-harness.js.map +1 -0
- package/dist/harnesses/harness-registry.d.ts +440 -0
- package/dist/harnesses/harness-registry.d.ts.map +1 -0
- package/dist/harnesses/harness-registry.js +543 -0
- package/dist/harnesses/harness-registry.js.map +1 -0
- package/dist/harnesses/index.d.ts +12 -0
- package/dist/harnesses/index.d.ts.map +1 -0
- package/dist/harnesses/index.js +11 -0
- package/dist/harnesses/index.js.map +1 -0
- package/dist/harnesses/pi-harness.d.ts +219 -0
- package/dist/harnesses/pi-harness.d.ts.map +1 -0
- package/dist/harnesses/pi-harness.js +676 -0
- package/dist/harnesses/pi-harness.js.map +1 -0
- package/dist/harnesses/pi-schema-converter.d.ts +24 -0
- package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
- package/dist/harnesses/pi-schema-converter.js +81 -0
- package/dist/harnesses/pi-schema-converter.js.map +1 -0
- package/dist/harnesses/register-defaults.d.ts +24 -0
- package/dist/harnesses/register-defaults.d.ts.map +1 -0
- package/dist/harnesses/register-defaults.js +40 -0
- package/dist/harnesses/register-defaults.js.map +1 -0
- package/dist/harnesses/session-store.d.ts +201 -0
- package/dist/harnesses/session-store.d.ts.map +1 -0
- package/dist/harnesses/session-store.js +254 -0
- package/dist/harnesses/session-store.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/reflection/index.d.ts +5 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
- package/dist/reflection/index.js.map +1 -0
- package/dist/reflection/reflection.d.ts +84 -0
- package/dist/reflection/reflection.d.ts.map +1 -0
- package/dist/reflection/reflection.js +344 -0
- package/dist/reflection/reflection.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/introspection.d.ts +165 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js +324 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/types/agent.d.ts +1317 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +423 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/decorators.d.ts +40 -0
- package/dist/types/decorators.d.ts.map +1 -0
- package/dist/types/decorators.js +2 -0
- package/dist/types/decorators.js.map +1 -0
- package/dist/types/error-strategy.d.ts +13 -0
- package/dist/types/error-strategy.d.ts.map +1 -0
- package/dist/types/error-strategy.js +2 -0
- package/dist/types/error-strategy.js.map +1 -0
- package/dist/types/error.d.ts +20 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +2 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/events.d.ts +113 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/harnesses.d.ts +474 -0
- package/dist/types/harnesses.d.ts.map +1 -0
- package/dist/types/harnesses.js +2 -0
- package/dist/types/harnesses.js.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logging.d.ts +24 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +2 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/observer.d.ts +18 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +2 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/prompt.d.ts +31 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/prompt.js +6 -0
- package/dist/types/prompt.js.map +1 -0
- package/dist/types/providers.d.ts +691 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/providers.js +14 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/types/reflection.d.ts +96 -0
- package/dist/types/reflection.d.ts.map +1 -0
- package/dist/types/reflection.js +24 -0
- package/dist/types/reflection.js.map +1 -0
- package/dist/types/restart.d.ts +132 -0
- package/dist/types/restart.d.ts.map +1 -0
- package/dist/types/restart.js +2 -0
- package/dist/types/restart.js.map +1 -0
- package/dist/types/sdk-primitives.d.ts +118 -0
- package/dist/types/sdk-primitives.d.ts.map +1 -0
- package/dist/types/sdk-primitives.js +6 -0
- package/dist/types/sdk-primitives.js.map +1 -0
- package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
- package/dist/types/snapshot.d.ts.map +1 -0
- package/dist/types/snapshot.js +2 -0
- package/dist/types/snapshot.js.map +1 -0
- package/dist/types/streaming.d.ts +194 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/types/streaming.js +67 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/types/workflow-context.d.ts +275 -0
- package/dist/types/workflow-context.d.ts.map +1 -0
- package/dist/types/workflow-context.js +8 -0
- package/dist/types/workflow-context.js.map +1 -0
- package/dist/types/workflow.d.ts +30 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/agent-validation.d.ts +88 -0
- package/dist/utils/agent-validation.d.ts.map +1 -0
- package/dist/utils/agent-validation.js +87 -0
- package/dist/utils/agent-validation.js.map +1 -0
- package/dist/utils/delay.d.ts +7 -0
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +9 -0
- package/dist/utils/delay.js.map +1 -0
- package/dist/utils/harness-config.d.ts +180 -0
- package/dist/utils/harness-config.d.ts.map +1 -0
- package/dist/utils/harness-config.js +311 -0
- package/dist/utils/harness-config.js.map +1 -0
- package/dist/utils/id.d.ts +6 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/model-spec.d.ts +110 -0
- package/dist/utils/model-spec.d.ts.map +1 -0
- package/dist/utils/model-spec.js +149 -0
- package/dist/utils/model-spec.js.map +1 -0
- package/dist/utils/observable.d.ts +54 -0
- package/dist/utils/observable.d.ts.map +1 -0
- package/dist/utils/observable.js +82 -0
- package/dist/utils/observable.js.map +1 -0
- package/dist/utils/provider-config.d.ts +10 -0
- package/dist/utils/provider-config.d.ts.map +1 -0
- package/dist/utils/provider-config.js +10 -0
- package/dist/utils/provider-config.js.map +1 -0
- package/dist/utils/restart-analysis.d.ts +202 -0
- package/dist/utils/restart-analysis.d.ts.map +1 -0
- package/dist/utils/restart-analysis.js +426 -0
- package/dist/utils/restart-analysis.js.map +1 -0
- package/dist/utils/session-serialization.d.ts +118 -0
- package/dist/utils/session-serialization.d.ts.map +1 -0
- package/dist/utils/session-serialization.js +217 -0
- package/dist/utils/session-serialization.js.map +1 -0
- package/dist/utils/workflow-error-utils.d.ts +22 -0
- package/dist/utils/workflow-error-utils.d.ts.map +1 -0
- package/dist/utils/workflow-error-utils.js +45 -0
- package/dist/utils/workflow-error-utils.js.map +1 -0
- package/package.json +34 -5
- package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
- package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
- package/.claude/commands/task-breakdown.md +0 -94
- package/.claude/settings.local.json +0 -9
- package/.claude/system_prompts/task-breakdown.md +0 -101
- package/CHANGELOG.md +0 -188
- package/PRD.md +0 -543
- package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
- package/PRPs/PRDs/002-agent-prompt.md +0 -390
- package/PRPs/PRDs/003-agent-prompt.md +0 -943
- package/PRPs/PRDs/004-agent-prompt.md +0 -1136
- package/PRPs/PRDs/tasks-001.json +0 -492
- package/PRPs/README.md +0 -83
- package/PRPs/templates/prp_base.md +0 -222
- package/docs/agent.md +0 -422
- package/docs/prompt.md +0 -419
- package/docs/workflow.md +0 -600
- package/examples/README.md +0 -258
- package/examples/examples/01-basic-workflow.ts +0 -100
- package/examples/examples/02-decorator-options.ts +0 -217
- package/examples/examples/03-parent-child.ts +0 -241
- package/examples/examples/04-observers-debugger.ts +0 -340
- package/examples/examples/05-error-handling.ts +0 -387
- package/examples/examples/06-concurrent-tasks.ts +0 -352
- package/examples/examples/07-agent-loops.ts +0 -432
- package/examples/examples/08-sdk-features.ts +0 -667
- package/examples/examples/09-reflection.ts +0 -573
- package/examples/examples/10-introspection.ts +0 -550
- package/examples/examples/11-reparenting-workflows.ts +0 -269
- package/examples/index.ts +0 -147
- package/examples/utils/helpers.ts +0 -57
- package/package-lock.json +0 -2398
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
- package/plan/001_d3bb02af4886/backlog.json +0 -867
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
- package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
- package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
- package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
- package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
- package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
- package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
- package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
- package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
- package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
- package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
- package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
- package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
- package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
- package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
- package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
- package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
- package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
- package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
- package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
- package/scripts/generate-llms-full.ts +0 -206
- package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
- package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
- package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
- package/src/__tests__/adversarial/edge-case.test.ts +0 -703
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
- package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
- package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
- package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
- package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
- package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
- package/src/__tests__/helpers/index.ts +0 -18
- package/src/__tests__/helpers/tree-verification.ts +0 -257
- package/src/__tests__/integration/agent-workflow.test.ts +0 -256
- package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
- package/src/__tests__/integration/observer-logging.test.ts +0 -643
- package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
- package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
- package/src/__tests__/unit/agent.test.ts +0 -169
- package/src/__tests__/unit/cache-key.test.ts +0 -182
- package/src/__tests__/unit/cache.test.ts +0 -172
- package/src/__tests__/unit/context.test.ts +0 -217
- package/src/__tests__/unit/decorators.test.ts +0 -100
- package/src/__tests__/unit/introspection-tools.test.ts +0 -277
- package/src/__tests__/unit/logger.test.ts +0 -293
- package/src/__tests__/unit/observable.test.ts +0 -321
- package/src/__tests__/unit/prompt.test.ts +0 -135
- package/src/__tests__/unit/reflection.test.ts +0 -210
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
- package/src/__tests__/unit/tree-debugger.test.ts +0 -85
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
- package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
- package/src/__tests__/unit/workflow.test.ts +0 -357
- package/src/cache/cache-key.ts +0 -244
- package/src/cache/cache.ts +0 -236
- package/src/core/agent.ts +0 -593
- package/src/core/event-tree.ts +0 -260
- package/src/core/logger.ts +0 -112
- package/src/core/mcp-handler.ts +0 -184
- package/src/core/prompt.ts +0 -150
- package/src/core/workflow-context.ts +0 -351
- package/src/core/workflow.ts +0 -540
- package/src/debugger/tree-debugger.ts +0 -255
- package/src/decorators/observed-state.ts +0 -95
- package/src/decorators/step.ts +0 -139
- package/src/decorators/task.ts +0 -159
- package/src/examples/tdd-orchestrator.ts +0 -65
- package/src/examples/test-cycle-workflow.ts +0 -64
- package/src/index.ts +0 -142
- package/src/reflection/reflection.ts +0 -407
- package/src/tools/index.ts +0 -36
- package/src/tools/introspection.ts +0 -464
- package/src/types/agent.ts +0 -90
- package/src/types/decorators.ts +0 -32
- package/src/types/error-strategy.ts +0 -13
- package/src/types/error.ts +0 -20
- package/src/types/events.ts +0 -75
- package/src/types/index.ts +0 -55
- package/src/types/logging.ts +0 -24
- package/src/types/observer.ts +0 -18
- package/src/types/prompt.ts +0 -40
- package/src/types/reflection.ts +0 -117
- package/src/types/sdk-primitives.ts +0 -128
- package/src/types/workflow-context.ts +0 -163
- package/src/types/workflow.ts +0 -37
- package/src/utils/id.ts +0 -11
- package/src/utils/index.ts +0 -4
- package/src/utils/observable.ts +0 -106
- package/src/utils/workflow-error-utils.ts +0 -56
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -16
|
@@ -1,847 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bidirectional Consistency Tests for Dual Tree Structure
|
|
3
|
-
*
|
|
4
|
-
* Tests the 1:1 mirror invariant between the Workflow instance tree and the WorkflowNode tree
|
|
5
|
-
* as specified in PRD Section 12.2.
|
|
6
|
-
*
|
|
7
|
-
* For every relationship in the workflow tree, there MUST be an equivalent relationship in the node tree:
|
|
8
|
-
* - If child.parent === parent, then child.node.parent MUST equal parent.node
|
|
9
|
-
* - If parent.children includes child, then parent.node.children MUST include child.node
|
|
10
|
-
*
|
|
11
|
-
* @module integration/bidirectional-consistency
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
15
|
-
import { Workflow } from '../../index.js';
|
|
16
|
-
import {
|
|
17
|
-
verifyBidirectionalLink,
|
|
18
|
-
verifyTreeMirror,
|
|
19
|
-
verifyOrphaned,
|
|
20
|
-
verifyNoCycles,
|
|
21
|
-
validateTreeConsistency,
|
|
22
|
-
collectAllNodes,
|
|
23
|
-
getDepth,
|
|
24
|
-
} from '../helpers/tree-verification.js';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* SimpleWorkflow class for testing
|
|
28
|
-
* Pattern from: src/__tests__/adversarial/circular-reference.test.ts:20-26
|
|
29
|
-
*/
|
|
30
|
-
class SimpleWorkflow extends Workflow {
|
|
31
|
-
async run(): Promise<string> {
|
|
32
|
-
this.setStatus('running');
|
|
33
|
-
this.setStatus('completed');
|
|
34
|
-
return 'done';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// ============================================================================
|
|
39
|
-
// Basic Operations Tests
|
|
40
|
-
// ============================================================================
|
|
41
|
-
|
|
42
|
-
describe('Bidirectional Consistency: Basic Operations', () => {
|
|
43
|
-
describe('attachChild() consistency', () => {
|
|
44
|
-
it('should maintain bidirectional links in both trees', () => {
|
|
45
|
-
// ARRANGE
|
|
46
|
-
const parent = new SimpleWorkflow('Parent');
|
|
47
|
-
const child = new SimpleWorkflow('Child'); // No parent
|
|
48
|
-
|
|
49
|
-
// ACT
|
|
50
|
-
parent.attachChild(child);
|
|
51
|
-
|
|
52
|
-
// ASSERT - Verify bidirectional links
|
|
53
|
-
verifyBidirectionalLink(parent, child);
|
|
54
|
-
|
|
55
|
-
// ASSERT - Verify tree mirror invariant
|
|
56
|
-
verifyTreeMirror(parent);
|
|
57
|
-
|
|
58
|
-
// ASSERT - Verify no inconsistencies detected
|
|
59
|
-
const errors = validateTreeConsistency(parent);
|
|
60
|
-
expect(errors).toEqual([]);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should maintain consistency when attaching multiple children', () => {
|
|
64
|
-
// ARRANGE
|
|
65
|
-
const parent = new SimpleWorkflow('Parent');
|
|
66
|
-
const child1 = new SimpleWorkflow('Child1');
|
|
67
|
-
const child2 = new SimpleWorkflow('Child2');
|
|
68
|
-
const child3 = new SimpleWorkflow('Child3');
|
|
69
|
-
|
|
70
|
-
// ACT
|
|
71
|
-
parent.attachChild(child1);
|
|
72
|
-
parent.attachChild(child2);
|
|
73
|
-
parent.attachChild(child3);
|
|
74
|
-
|
|
75
|
-
// ASSERT - Verify each child
|
|
76
|
-
verifyBidirectionalLink(parent, child1);
|
|
77
|
-
verifyBidirectionalLink(parent, child2);
|
|
78
|
-
verifyBidirectionalLink(parent, child3);
|
|
79
|
-
|
|
80
|
-
// ASSERT - Verify entire tree
|
|
81
|
-
verifyTreeMirror(parent);
|
|
82
|
-
|
|
83
|
-
const errors = validateTreeConsistency(parent);
|
|
84
|
-
expect(errors).toEqual([]);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should maintain consistency when attaching child via constructor', () => {
|
|
88
|
-
// ARRANGE & ACT
|
|
89
|
-
const parent = new SimpleWorkflow('Parent');
|
|
90
|
-
const child = new SimpleWorkflow('Child', parent); // Auto-attaches
|
|
91
|
-
|
|
92
|
-
// ASSERT - Verify bidirectional links
|
|
93
|
-
verifyBidirectionalLink(parent, child);
|
|
94
|
-
|
|
95
|
-
// ASSERT - Verify tree mirror
|
|
96
|
-
verifyTreeMirror(parent);
|
|
97
|
-
|
|
98
|
-
const errors = validateTreeConsistency(parent);
|
|
99
|
-
expect(errors).toEqual([]);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should maintain consistency when reattaching a detached child', () => {
|
|
103
|
-
// ARRANGE
|
|
104
|
-
const parent = new SimpleWorkflow('Parent');
|
|
105
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
106
|
-
|
|
107
|
-
// ACT - Detach and reattach
|
|
108
|
-
parent.detachChild(child);
|
|
109
|
-
parent.attachChild(child);
|
|
110
|
-
|
|
111
|
-
// ASSERT - Verify bidirectional links restored
|
|
112
|
-
verifyBidirectionalLink(parent, child);
|
|
113
|
-
|
|
114
|
-
// ASSERT - Verify tree mirror
|
|
115
|
-
verifyTreeMirror(parent);
|
|
116
|
-
|
|
117
|
-
const errors = validateTreeConsistency(parent);
|
|
118
|
-
expect(errors).toEqual([]);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe('detachChild() consistency', () => {
|
|
123
|
-
it('should remove bidirectional links from both trees', () => {
|
|
124
|
-
// ARRANGE
|
|
125
|
-
const parent = new SimpleWorkflow('Parent');
|
|
126
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
127
|
-
|
|
128
|
-
// ACT
|
|
129
|
-
parent.detachChild(child);
|
|
130
|
-
|
|
131
|
-
// ASSERT - Verify orphaning in BOTH trees
|
|
132
|
-
expect(child.parent).toBeNull();
|
|
133
|
-
expect(child.node.parent).toBeNull();
|
|
134
|
-
expect(parent.children).not.toContain(child);
|
|
135
|
-
expect(parent.node.children).not.toContain(child.node);
|
|
136
|
-
|
|
137
|
-
// ASSERT - Verify orphaning helper
|
|
138
|
-
verifyOrphaned(child);
|
|
139
|
-
|
|
140
|
-
// ASSERT - Verify tree mirror
|
|
141
|
-
verifyTreeMirror(parent);
|
|
142
|
-
|
|
143
|
-
const errors = validateTreeConsistency(parent);
|
|
144
|
-
expect(errors).toEqual([]);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it('should maintain consistency when detaching middle child', () => {
|
|
148
|
-
// ARRANGE
|
|
149
|
-
const parent = new SimpleWorkflow('Parent');
|
|
150
|
-
const child1 = new SimpleWorkflow('Child1', parent);
|
|
151
|
-
const child2 = new SimpleWorkflow('Child2', parent);
|
|
152
|
-
const child3 = new SimpleWorkflow('Child3', parent);
|
|
153
|
-
|
|
154
|
-
// ACT - Detach middle child
|
|
155
|
-
parent.detachChild(child2);
|
|
156
|
-
|
|
157
|
-
// ASSERT - Verify child2 is orphaned
|
|
158
|
-
verifyOrphaned(child2);
|
|
159
|
-
|
|
160
|
-
// ASSERT - Verify other children still linked
|
|
161
|
-
verifyBidirectionalLink(parent, child1);
|
|
162
|
-
verifyBidirectionalLink(parent, child3);
|
|
163
|
-
|
|
164
|
-
// ASSERT - Verify parent has correct children
|
|
165
|
-
expect(parent.children).toEqual([child1, child3]);
|
|
166
|
-
expect(parent.node.children).toEqual([child1.node, child3.node]);
|
|
167
|
-
|
|
168
|
-
// ASSERT - Verify tree mirror
|
|
169
|
-
verifyTreeMirror(parent);
|
|
170
|
-
|
|
171
|
-
const errors = validateTreeConsistency(parent);
|
|
172
|
-
expect(errors).toEqual([]);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('should maintain consistency when detaching last child', () => {
|
|
176
|
-
// ARRANGE
|
|
177
|
-
const parent = new SimpleWorkflow('Parent');
|
|
178
|
-
const child1 = new SimpleWorkflow('Child1', parent);
|
|
179
|
-
const child2 = new SimpleWorkflow('Child2', parent);
|
|
180
|
-
const child3 = new SimpleWorkflow('Child3', parent);
|
|
181
|
-
|
|
182
|
-
// ACT - Detach last child
|
|
183
|
-
parent.detachChild(child3);
|
|
184
|
-
|
|
185
|
-
// ASSERT - Verify child3 is orphaned
|
|
186
|
-
verifyOrphaned(child3);
|
|
187
|
-
|
|
188
|
-
// ASSERT - Verify parent has correct children
|
|
189
|
-
expect(parent.children).toEqual([child1, child2]);
|
|
190
|
-
expect(parent.node.children).toEqual([child1.node, child2.node]);
|
|
191
|
-
|
|
192
|
-
// ASSERT - Verify tree mirror
|
|
193
|
-
verifyTreeMirror(parent);
|
|
194
|
-
|
|
195
|
-
const errors = validateTreeConsistency(parent);
|
|
196
|
-
expect(errors).toEqual([]);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should maintain consistency when detaching all children', () => {
|
|
200
|
-
// ARRANGE
|
|
201
|
-
const parent = new SimpleWorkflow('Parent');
|
|
202
|
-
const child1 = new SimpleWorkflow('Child1', parent);
|
|
203
|
-
const child2 = new SimpleWorkflow('Child2', parent);
|
|
204
|
-
|
|
205
|
-
// ACT - Detach all children
|
|
206
|
-
parent.detachChild(child1);
|
|
207
|
-
parent.detachChild(child2);
|
|
208
|
-
|
|
209
|
-
// ASSERT - Verify all children orphaned
|
|
210
|
-
verifyOrphaned(child1);
|
|
211
|
-
verifyOrphaned(child2);
|
|
212
|
-
|
|
213
|
-
// ASSERT - Verify parent has no children
|
|
214
|
-
expect(parent.children).toEqual([]);
|
|
215
|
-
expect(parent.node.children).toEqual([]);
|
|
216
|
-
|
|
217
|
-
// ASSERT - Verify tree mirror
|
|
218
|
-
verifyTreeMirror(parent);
|
|
219
|
-
|
|
220
|
-
const errors = validateTreeConsistency(parent);
|
|
221
|
-
expect(errors).toEqual([]);
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
// ============================================================================
|
|
227
|
-
// Reparenting Tests
|
|
228
|
-
// ============================================================================
|
|
229
|
-
|
|
230
|
-
describe('Bidirectional Consistency: Reparenting', () => {
|
|
231
|
-
it('should maintain consistency during single reparenting', () => {
|
|
232
|
-
// ARRANGE
|
|
233
|
-
const parent1 = new SimpleWorkflow('Parent1');
|
|
234
|
-
const parent2 = new SimpleWorkflow('Parent2');
|
|
235
|
-
const child = new SimpleWorkflow('Child', parent1);
|
|
236
|
-
|
|
237
|
-
// ASSERT - Verify initial state
|
|
238
|
-
verifyBidirectionalLink(parent1, child);
|
|
239
|
-
expect(parent2.children).toEqual([]);
|
|
240
|
-
|
|
241
|
-
// ACT - Reparent
|
|
242
|
-
parent1.detachChild(child);
|
|
243
|
-
parent2.attachChild(child);
|
|
244
|
-
|
|
245
|
-
// ASSERT - Verify new state
|
|
246
|
-
verifyBidirectionalLink(parent2, child);
|
|
247
|
-
|
|
248
|
-
// ASSERT - Verify old parent no longer has child in BOTH trees
|
|
249
|
-
expect(parent1.children).not.toContain(child);
|
|
250
|
-
expect(parent1.node.children).not.toContain(child.node);
|
|
251
|
-
|
|
252
|
-
// ASSERT - Verify new parent has child in BOTH trees
|
|
253
|
-
expect(parent2.children).toContain(child);
|
|
254
|
-
expect(parent2.node.children).toContain(child.node);
|
|
255
|
-
|
|
256
|
-
// ASSERT - Verify both trees are valid
|
|
257
|
-
verifyTreeMirror(parent1);
|
|
258
|
-
verifyTreeMirror(parent2);
|
|
259
|
-
|
|
260
|
-
const errors1 = validateTreeConsistency(parent1);
|
|
261
|
-
const errors2 = validateTreeConsistency(parent2);
|
|
262
|
-
expect(errors1).toEqual([]);
|
|
263
|
-
expect(errors2).toEqual([]);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it('should maintain consistency during multiple reparenting cycles', () => {
|
|
267
|
-
// ARRANGE
|
|
268
|
-
const parentA = new SimpleWorkflow('ParentA');
|
|
269
|
-
const parentB = new SimpleWorkflow('ParentB');
|
|
270
|
-
const parentC = new SimpleWorkflow('ParentC');
|
|
271
|
-
const child = new SimpleWorkflow('Child', parentA);
|
|
272
|
-
|
|
273
|
-
// ACT - Cycle 1: A -> B
|
|
274
|
-
parentA.detachChild(child);
|
|
275
|
-
parentB.attachChild(child);
|
|
276
|
-
|
|
277
|
-
// ASSERT - After cycle 1
|
|
278
|
-
verifyBidirectionalLink(parentB, child);
|
|
279
|
-
verifyTreeMirror(parentB);
|
|
280
|
-
expect(validateTreeConsistency(parentB)).toEqual([]);
|
|
281
|
-
|
|
282
|
-
// ACT - Cycle 2: B -> C
|
|
283
|
-
parentB.detachChild(child);
|
|
284
|
-
parentC.attachChild(child);
|
|
285
|
-
|
|
286
|
-
// ASSERT - After cycle 2
|
|
287
|
-
verifyBidirectionalLink(parentC, child);
|
|
288
|
-
verifyTreeMirror(parentC);
|
|
289
|
-
expect(validateTreeConsistency(parentC)).toEqual([]);
|
|
290
|
-
|
|
291
|
-
// ACT - Cycle 3: C -> A (back to original)
|
|
292
|
-
parentC.detachChild(child);
|
|
293
|
-
parentA.attachChild(child);
|
|
294
|
-
|
|
295
|
-
// ASSERT - After cycle 3
|
|
296
|
-
verifyBidirectionalLink(parentA, child);
|
|
297
|
-
verifyTreeMirror(parentA);
|
|
298
|
-
expect(validateTreeConsistency(parentA)).toEqual([]);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('should maintain consistency with deep hierarchy reparenting', () => {
|
|
302
|
-
// ARRANGE - Create deep hierarchy: root1 -> mid1 -> leaf
|
|
303
|
-
const root1 = new SimpleWorkflow('Root1');
|
|
304
|
-
const mid1 = new SimpleWorkflow('Mid1', root1);
|
|
305
|
-
const leaf = new SimpleWorkflow('Leaf', mid1);
|
|
306
|
-
|
|
307
|
-
// ARRANGE - Create second hierarchy: root2 -> mid2
|
|
308
|
-
const root2 = new SimpleWorkflow('Root2');
|
|
309
|
-
const mid2 = new SimpleWorkflow('Mid2', root2);
|
|
310
|
-
|
|
311
|
-
// ASSERT - Verify initial deep hierarchy
|
|
312
|
-
verifyBidirectionalLink(root1, mid1);
|
|
313
|
-
verifyBidirectionalLink(mid1, leaf);
|
|
314
|
-
verifyTreeMirror(root1);
|
|
315
|
-
|
|
316
|
-
// ACT - Reparent entire subtree (mid1 + leaf) from root1 to root2
|
|
317
|
-
root1.detachChild(mid1);
|
|
318
|
-
root2.attachChild(mid1);
|
|
319
|
-
|
|
320
|
-
// ASSERT - Verify new hierarchy: root2 -> mid2, mid1 -> leaf
|
|
321
|
-
verifyBidirectionalLink(root2, mid1);
|
|
322
|
-
verifyBidirectionalLink(mid1, leaf);
|
|
323
|
-
verifyTreeMirror(root2);
|
|
324
|
-
|
|
325
|
-
// ASSERT - Verify old root no longer has mid1 in BOTH trees
|
|
326
|
-
expect(root1.children).toEqual([]);
|
|
327
|
-
expect(root1.node.children).toEqual([]);
|
|
328
|
-
|
|
329
|
-
// ASSERT - Verify new root has both children in BOTH trees
|
|
330
|
-
expect(root2.children).toEqual([mid2, mid1]);
|
|
331
|
-
expect(root2.node.children).toEqual([mid2.node, mid1.node]);
|
|
332
|
-
|
|
333
|
-
// ASSERT - Verify leaf still under mid1 in BOTH trees
|
|
334
|
-
expect(mid1.children).toEqual([leaf]);
|
|
335
|
-
expect(mid1.node.children).toEqual([leaf.node]);
|
|
336
|
-
|
|
337
|
-
// ASSERT - Verify no inconsistencies
|
|
338
|
-
expect(validateTreeConsistency(root2)).toEqual([]);
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
it('should maintain consistency when reparenting between multiple parents', () => {
|
|
342
|
-
// ARRANGE
|
|
343
|
-
const parents = [
|
|
344
|
-
new SimpleWorkflow('Parent0'),
|
|
345
|
-
new SimpleWorkflow('Parent1'),
|
|
346
|
-
new SimpleWorkflow('Parent2'),
|
|
347
|
-
new SimpleWorkflow('Parent3'),
|
|
348
|
-
];
|
|
349
|
-
const child = new SimpleWorkflow('Child', parents[0]);
|
|
350
|
-
|
|
351
|
-
// ACT - Reparent through all parents
|
|
352
|
-
for (let i = 0; i < parents.length - 1; i++) {
|
|
353
|
-
const currentParent = parents[i];
|
|
354
|
-
const nextParent = parents[i + 1];
|
|
355
|
-
|
|
356
|
-
currentParent.detachChild(child);
|
|
357
|
-
nextParent.attachChild(child);
|
|
358
|
-
|
|
359
|
-
// ASSERT - Verify consistency after each reparenting
|
|
360
|
-
verifyBidirectionalLink(nextParent, child);
|
|
361
|
-
verifyTreeMirror(nextParent);
|
|
362
|
-
expect(validateTreeConsistency(nextParent)).toEqual([]);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// ASSERT - Final parent should have child
|
|
366
|
-
verifyBidirectionalLink(parents[3], child);
|
|
367
|
-
expect(parents[0].children).toEqual([]);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// ============================================================================
|
|
372
|
-
// Invariant Tests
|
|
373
|
-
// ============================================================================
|
|
374
|
-
|
|
375
|
-
describe('Bidirectional Consistency: Invariants', () => {
|
|
376
|
-
describe('Acyclicity invariant', () => {
|
|
377
|
-
it('should prevent circular references', () => {
|
|
378
|
-
// ARRANGE
|
|
379
|
-
const root = new SimpleWorkflow('Root');
|
|
380
|
-
const child = new SimpleWorkflow('Child', root);
|
|
381
|
-
|
|
382
|
-
// ACT & ASSERT - Try to create cycle
|
|
383
|
-
expect(() => {
|
|
384
|
-
child.attachChild(root as any);
|
|
385
|
-
}).toThrow(/circular|cycle|ancestor/i);
|
|
386
|
-
|
|
387
|
-
// ASSERT - Verify no corruption occurred
|
|
388
|
-
verifyNoCycles(root);
|
|
389
|
-
expect(root.parent).toBeNull();
|
|
390
|
-
expect(child.parent).toBe(root);
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
it('should detect complex circular references', () => {
|
|
394
|
-
// ARRANGE - Create chain: root -> child1 -> child2 -> child3
|
|
395
|
-
const root = new SimpleWorkflow('Root');
|
|
396
|
-
const child1 = new SimpleWorkflow('Child1', root);
|
|
397
|
-
const child2 = new SimpleWorkflow('Child2', child1);
|
|
398
|
-
const child3 = new SimpleWorkflow('Child3', child2);
|
|
399
|
-
|
|
400
|
-
// ACT & ASSERT - Try to create cycle: child3 -> root
|
|
401
|
-
expect(() => {
|
|
402
|
-
child3.attachChild(root as any);
|
|
403
|
-
}).toThrow(/circular|cycle|ancestor/i);
|
|
404
|
-
|
|
405
|
-
// ASSERT - Verify no corruption
|
|
406
|
-
verifyNoCycles(root);
|
|
407
|
-
verifyTreeMirror(root);
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
it('should prevent self-attachment', () => {
|
|
411
|
-
// ARRANGE
|
|
412
|
-
const workflow = new SimpleWorkflow('Self');
|
|
413
|
-
|
|
414
|
-
// ACT & ASSERT - Try to attach to self
|
|
415
|
-
expect(() => {
|
|
416
|
-
workflow.attachChild(workflow as any);
|
|
417
|
-
}).toThrow(/circular|cycle|ancestor/i);
|
|
418
|
-
});
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
describe('Tree mirror invariant', () => {
|
|
422
|
-
it('should maintain 1:1 correspondence after operations', () => {
|
|
423
|
-
// ARRANGE
|
|
424
|
-
const root = new SimpleWorkflow('Root');
|
|
425
|
-
const child1 = new SimpleWorkflow('Child1', root);
|
|
426
|
-
const child2 = new SimpleWorkflow('Child2', root);
|
|
427
|
-
|
|
428
|
-
// ASSERT - Verify mirror after creation
|
|
429
|
-
verifyTreeMirror(root);
|
|
430
|
-
|
|
431
|
-
// ACT - Detach and reattach
|
|
432
|
-
root.detachChild(child1);
|
|
433
|
-
verifyTreeMirror(root);
|
|
434
|
-
|
|
435
|
-
root.attachChild(child1);
|
|
436
|
-
verifyTreeMirror(root);
|
|
437
|
-
|
|
438
|
-
// ASSERT - Verify both trees have same structure
|
|
439
|
-
expect(root.children.length).toBe(root.node.children.length);
|
|
440
|
-
expect(root.children[0].node).toBe(root.node.children[0]);
|
|
441
|
-
expect(root.children[1].node).toBe(root.node.children[1]);
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
it('should detect mirror violations in parent relationship', () => {
|
|
445
|
-
// ARRANGE
|
|
446
|
-
const parent = new SimpleWorkflow('Parent');
|
|
447
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
448
|
-
|
|
449
|
-
// ACT - Manually corrupt node tree (simulating bug)
|
|
450
|
-
(child.node as any).parent = null;
|
|
451
|
-
|
|
452
|
-
// ASSERT - Should detect mirror violation
|
|
453
|
-
expect(() => {
|
|
454
|
-
verifyTreeMirror(parent);
|
|
455
|
-
}).toThrow(/MIRROR/);
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
it('should detect mirror violations in children relationship', () => {
|
|
459
|
-
// ARRANGE
|
|
460
|
-
const parent = new SimpleWorkflow('Parent');
|
|
461
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
462
|
-
|
|
463
|
-
// ACT - Manually corrupt node tree children array
|
|
464
|
-
(parent.node as any).children = [];
|
|
465
|
-
|
|
466
|
-
// ASSERT - Should detect mirror violation
|
|
467
|
-
expect(() => {
|
|
468
|
-
verifyTreeMirror(parent);
|
|
469
|
-
}).toThrow(/MIRROR/);
|
|
470
|
-
});
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
describe('Single root invariant', () => {
|
|
474
|
-
it('should maintain exactly one root', () => {
|
|
475
|
-
// ARRANGE
|
|
476
|
-
const root = new SimpleWorkflow('Root');
|
|
477
|
-
const child1 = new SimpleWorkflow('Child1', root);
|
|
478
|
-
const child2 = new SimpleWorkflow('Child2', root);
|
|
479
|
-
|
|
480
|
-
// ACT - Count roots
|
|
481
|
-
const allNodes = collectAllNodes(root);
|
|
482
|
-
const roots = allNodes.filter(n => n.parent === null);
|
|
483
|
-
|
|
484
|
-
// ASSERT - Should have exactly one root
|
|
485
|
-
expect(roots.length).toBe(1);
|
|
486
|
-
expect(roots[0]).toBe(root);
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
it('should have one root after reparenting', () => {
|
|
490
|
-
// ARRANGE
|
|
491
|
-
const root1 = new SimpleWorkflow('Root1');
|
|
492
|
-
const root2 = new SimpleWorkflow('Root2');
|
|
493
|
-
const child = new SimpleWorkflow('Child', root1);
|
|
494
|
-
|
|
495
|
-
// ASSERT - Initially: 2 roots (root1 and root2)
|
|
496
|
-
let allNodes = [...collectAllNodes(root1), ...collectAllNodes(root2)];
|
|
497
|
-
let roots = allNodes.filter(n => n.parent === null);
|
|
498
|
-
expect(roots.length).toBe(2);
|
|
499
|
-
|
|
500
|
-
// ACT - Reparent child to root2
|
|
501
|
-
root1.detachChild(child);
|
|
502
|
-
root2.attachChild(child);
|
|
503
|
-
|
|
504
|
-
// ASSERT - Still: 2 roots (root1 and root2)
|
|
505
|
-
allNodes = [...collectAllNodes(root1), ...collectAllNodes(root2)];
|
|
506
|
-
roots = allNodes.filter(n => n.parent === null);
|
|
507
|
-
expect(roots.length).toBe(2);
|
|
508
|
-
});
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
describe('Connectedness invariant', () => {
|
|
512
|
-
it('should have all nodes reachable from root', () => {
|
|
513
|
-
// ARRANGE
|
|
514
|
-
const root = new SimpleWorkflow('Root');
|
|
515
|
-
const child1 = new SimpleWorkflow('Child1', root);
|
|
516
|
-
const child2 = new SimpleWorkflow('Child2', root);
|
|
517
|
-
const grandchild = new SimpleWorkflow('Grandchild', child1);
|
|
518
|
-
|
|
519
|
-
// ACT - Collect all nodes and verify reachability
|
|
520
|
-
const allNodes = collectAllNodes(root);
|
|
521
|
-
const reachableFromRoot = new Set<Workflow>();
|
|
522
|
-
|
|
523
|
-
function traverse(node: Workflow): void {
|
|
524
|
-
reachableFromRoot.add(node);
|
|
525
|
-
node.children.forEach(traverse);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
traverse(root);
|
|
529
|
-
|
|
530
|
-
// ASSERT - All nodes should be reachable
|
|
531
|
-
allNodes.forEach(node => {
|
|
532
|
-
expect(reachableFromRoot.has(node)).toBe(true);
|
|
533
|
-
});
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
it('should have all nodes reachable after reparenting', () => {
|
|
537
|
-
// ARRANGE
|
|
538
|
-
const root1 = new SimpleWorkflow('Root1');
|
|
539
|
-
const root2 = new SimpleWorkflow('Root2');
|
|
540
|
-
const child = new SimpleWorkflow('Child', root1);
|
|
541
|
-
|
|
542
|
-
// ACT - Reparent
|
|
543
|
-
root1.detachChild(child);
|
|
544
|
-
root2.attachChild(child);
|
|
545
|
-
|
|
546
|
-
// ASSERT - Verify reachability from root2
|
|
547
|
-
const allNodes = collectAllNodes(root2);
|
|
548
|
-
const reachableFromRoot = new Set<Workflow>();
|
|
549
|
-
|
|
550
|
-
function traverse(node: Workflow): void {
|
|
551
|
-
reachableFromRoot.add(node);
|
|
552
|
-
node.children.forEach(traverse);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
traverse(root2);
|
|
556
|
-
|
|
557
|
-
expect(reachableFromRoot.has(root2)).toBe(true);
|
|
558
|
-
expect(reachableFromRoot.has(child)).toBe(true);
|
|
559
|
-
});
|
|
560
|
-
});
|
|
561
|
-
|
|
562
|
-
describe('Depth calculation', () => {
|
|
563
|
-
it('should calculate depth correctly', () => {
|
|
564
|
-
// ARRANGE
|
|
565
|
-
const root = new SimpleWorkflow('Root');
|
|
566
|
-
const child1 = new SimpleWorkflow('Child1', root);
|
|
567
|
-
const child2 = new SimpleWorkflow('Child2', child1);
|
|
568
|
-
const child3 = new SimpleWorkflow('Child3', child2);
|
|
569
|
-
|
|
570
|
-
// ASSERT - Verify depths
|
|
571
|
-
expect(getDepth(root)).toBe(0);
|
|
572
|
-
expect(getDepth(child1)).toBe(1);
|
|
573
|
-
expect(getDepth(child2)).toBe(2);
|
|
574
|
-
expect(getDepth(child3)).toBe(3);
|
|
575
|
-
});
|
|
576
|
-
});
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
// ============================================================================
|
|
580
|
-
// Adversarial Tests
|
|
581
|
-
// ============================================================================
|
|
582
|
-
|
|
583
|
-
describe('Bidirectional Consistency: Adversarial Tests', () => {
|
|
584
|
-
// Console mocking to suppress error output during expected failures
|
|
585
|
-
beforeEach(() => {
|
|
586
|
-
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
587
|
-
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
588
|
-
vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
afterEach(() => {
|
|
592
|
-
vi.restoreAllMocks();
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
describe('Manual mutation detection', () => {
|
|
596
|
-
it('should detect inconsistency from manual parent mutation', () => {
|
|
597
|
-
// ARRANGE
|
|
598
|
-
const parent1 = new SimpleWorkflow('Parent1');
|
|
599
|
-
const parent2 = new SimpleWorkflow('Parent2');
|
|
600
|
-
const child = new SimpleWorkflow('Child', parent1);
|
|
601
|
-
|
|
602
|
-
// ACT - Manually mutate parent (bypassing attachChild)
|
|
603
|
-
(child as any).parent = parent2;
|
|
604
|
-
|
|
605
|
-
// ASSERT - Should detect inconsistency
|
|
606
|
-
const errors = validateTreeConsistency(parent1);
|
|
607
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
608
|
-
expect(errors.some(e => e.includes('Mismatched parent'))).toBe(true);
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
it('should detect inconsistency from manual children array mutation', () => {
|
|
612
|
-
// ARRANGE
|
|
613
|
-
const parent = new SimpleWorkflow('Parent');
|
|
614
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
615
|
-
const other = new SimpleWorkflow('Other');
|
|
616
|
-
|
|
617
|
-
// ACT - Manually add to children array (bypassing attachChild)
|
|
618
|
-
(parent as any).children.push(other);
|
|
619
|
-
|
|
620
|
-
// ASSERT - Should detect inconsistency
|
|
621
|
-
const errors = validateTreeConsistency(parent);
|
|
622
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
623
|
-
});
|
|
624
|
-
|
|
625
|
-
it('should detect inconsistency from node tree mutation', () => {
|
|
626
|
-
// ARRANGE
|
|
627
|
-
const parent = new SimpleWorkflow('Parent');
|
|
628
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
629
|
-
|
|
630
|
-
// ACT - Manually mutate node tree
|
|
631
|
-
(child.node as any).parent = null;
|
|
632
|
-
|
|
633
|
-
// ASSERT - Should detect mirror violation
|
|
634
|
-
expect(() => {
|
|
635
|
-
verifyTreeMirror(parent);
|
|
636
|
-
}).toThrow();
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
it('should detect inconsistency from node children array mutation', () => {
|
|
640
|
-
// ARRANGE
|
|
641
|
-
const parent = new SimpleWorkflow('Parent');
|
|
642
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
643
|
-
|
|
644
|
-
// ACT - Manually mutate node.children array to add duplicate child
|
|
645
|
-
// This creates a mirror violation where node.children has extra entries
|
|
646
|
-
(parent.node as any).children.push(child.node); // Duplicate child
|
|
647
|
-
|
|
648
|
-
// ASSERT - Should detect mirror violation (children count mismatch)
|
|
649
|
-
expect(() => {
|
|
650
|
-
verifyTreeMirror(parent);
|
|
651
|
-
}).toThrow(/MIRROR|Children count mismatch/);
|
|
652
|
-
});
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
describe('Stress testing', () => {
|
|
656
|
-
it('should maintain consistency with deep hierarchies', () => {
|
|
657
|
-
// ARRANGE
|
|
658
|
-
const root = new SimpleWorkflow('Root');
|
|
659
|
-
let current = root;
|
|
660
|
-
|
|
661
|
-
// ACT - Create 100 levels deep
|
|
662
|
-
for (let i = 0; i < 100; i++) {
|
|
663
|
-
const child = new SimpleWorkflow(`Level-${i}`);
|
|
664
|
-
current.attachChild(child);
|
|
665
|
-
current = child;
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
// ASSERT - Verify consistency at each level
|
|
669
|
-
verifyTreeMirror(root);
|
|
670
|
-
verifyNoCycles(root);
|
|
671
|
-
|
|
672
|
-
const errors = validateTreeConsistency(root);
|
|
673
|
-
expect(errors).toEqual([]);
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
it('should maintain consistency with wide hierarchies', () => {
|
|
677
|
-
// ARRANGE
|
|
678
|
-
const parent = new SimpleWorkflow('Parent');
|
|
679
|
-
const children: SimpleWorkflow[] = [];
|
|
680
|
-
|
|
681
|
-
// ACT - Create 100 children
|
|
682
|
-
for (let i = 0; i < 100; i++) {
|
|
683
|
-
const child = new SimpleWorkflow(`Child-${i}`);
|
|
684
|
-
parent.attachChild(child);
|
|
685
|
-
children.push(child);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
// ASSERT - Verify all children
|
|
689
|
-
children.forEach(child => {
|
|
690
|
-
verifyBidirectionalLink(parent, child);
|
|
691
|
-
});
|
|
692
|
-
|
|
693
|
-
// ASSERT - Verify tree mirror
|
|
694
|
-
verifyTreeMirror(parent);
|
|
695
|
-
|
|
696
|
-
const errors = validateTreeConsistency(parent);
|
|
697
|
-
expect(errors).toEqual([]);
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
it('should maintain consistency during rapid attach/detach cycles', () => {
|
|
701
|
-
// ARRANGE
|
|
702
|
-
const parent1 = new SimpleWorkflow('Parent1');
|
|
703
|
-
const parent2 = new SimpleWorkflow('Parent2');
|
|
704
|
-
const child = new SimpleWorkflow('Child', parent1);
|
|
705
|
-
|
|
706
|
-
// ACT - Rapid reparenting (100 cycles)
|
|
707
|
-
for (let i = 0; i < 100; i++) {
|
|
708
|
-
if (i % 2 === 0) {
|
|
709
|
-
parent1.detachChild(child);
|
|
710
|
-
parent2.attachChild(child);
|
|
711
|
-
} else {
|
|
712
|
-
parent2.detachChild(child);
|
|
713
|
-
parent1.attachChild(child);
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
// ASSERT - Verify consistency after each cycle
|
|
717
|
-
const expectedParent = i % 2 === 0 ? parent2 : parent1;
|
|
718
|
-
expect(child.parent).toBe(expectedParent);
|
|
719
|
-
expect(child.node.parent).toBe(expectedParent.node);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// ASSERT - Final verification
|
|
723
|
-
verifyTreeMirror(parent1);
|
|
724
|
-
verifyTreeMirror(parent2);
|
|
725
|
-
});
|
|
726
|
-
|
|
727
|
-
it('should handle complex multi-level reparenting', () => {
|
|
728
|
-
// ARRANGE - Create complex tree structure
|
|
729
|
-
const root1 = new SimpleWorkflow('Root1');
|
|
730
|
-
const branch1 = new SimpleWorkflow('Branch1', root1);
|
|
731
|
-
const leaf1a = new SimpleWorkflow('Leaf1A', branch1);
|
|
732
|
-
const leaf1b = new SimpleWorkflow('Leaf1B', branch1);
|
|
733
|
-
|
|
734
|
-
const root2 = new SimpleWorkflow('Root2');
|
|
735
|
-
const branch2 = new SimpleWorkflow('Branch2', root2);
|
|
736
|
-
|
|
737
|
-
// ACT - Reparent branch1 (and its children) to root2
|
|
738
|
-
root1.detachChild(branch1);
|
|
739
|
-
root2.attachChild(branch1);
|
|
740
|
-
|
|
741
|
-
// ASSERT - Verify tree structure
|
|
742
|
-
verifyTreeMirror(root2);
|
|
743
|
-
|
|
744
|
-
// Verify root1 has no children
|
|
745
|
-
expect(root1.children).toEqual([]);
|
|
746
|
-
|
|
747
|
-
// Verify root2 has both branches
|
|
748
|
-
expect(root2.children.length).toBe(2);
|
|
749
|
-
|
|
750
|
-
// Verify branch1 still has its children
|
|
751
|
-
expect(branch1.children).toEqual([leaf1a, leaf1b]);
|
|
752
|
-
|
|
753
|
-
// Verify all bidirectional links
|
|
754
|
-
verifyBidirectionalLink(root2, branch1);
|
|
755
|
-
verifyBidirectionalLink(root2, branch2);
|
|
756
|
-
verifyBidirectionalLink(branch1, leaf1a);
|
|
757
|
-
verifyBidirectionalLink(branch1, leaf1b);
|
|
758
|
-
|
|
759
|
-
const errors = validateTreeConsistency(root2);
|
|
760
|
-
expect(errors).toEqual([]);
|
|
761
|
-
});
|
|
762
|
-
});
|
|
763
|
-
});
|
|
764
|
-
|
|
765
|
-
// ============================================================================
|
|
766
|
-
// Property-Based Tests
|
|
767
|
-
// ============================================================================
|
|
768
|
-
|
|
769
|
-
describe('Bidirectional Consistency: Property-Based Tests', () => {
|
|
770
|
-
it('should satisfy round-trip property', () => {
|
|
771
|
-
// ARRANGE
|
|
772
|
-
const root = new SimpleWorkflow('Root');
|
|
773
|
-
const child1 = new SimpleWorkflow('Child1', root);
|
|
774
|
-
const child2 = new SimpleWorkflow('Child2', root);
|
|
775
|
-
|
|
776
|
-
// Capture initial children count
|
|
777
|
-
const initialChildCount = root.children.length;
|
|
778
|
-
const initialNodeChildCount = root.node.children.length;
|
|
779
|
-
|
|
780
|
-
// ACT - Detach and reattach
|
|
781
|
-
root.detachChild(child1);
|
|
782
|
-
root.attachChild(child1);
|
|
783
|
-
|
|
784
|
-
// ASSERT - Should maintain same children (order may change after detach/reattach)
|
|
785
|
-
expect(root.children.length).toBe(initialChildCount);
|
|
786
|
-
expect(root.node.children.length).toBe(initialNodeChildCount);
|
|
787
|
-
expect(root.children).toContain(child1);
|
|
788
|
-
expect(root.children).toContain(child2);
|
|
789
|
-
|
|
790
|
-
// ASSERT - Verify mirror invariant maintained
|
|
791
|
-
verifyTreeMirror(root);
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
it('should satisfy idempotence property', () => {
|
|
795
|
-
// ARRANGE
|
|
796
|
-
const parent = new SimpleWorkflow('Parent');
|
|
797
|
-
const child = new SimpleWorkflow('Child', parent);
|
|
798
|
-
|
|
799
|
-
// Capture state
|
|
800
|
-
const childrenBefore = [...parent.children];
|
|
801
|
-
const nodeChildrenBefore = [...parent.node.children];
|
|
802
|
-
|
|
803
|
-
// ACT & ASSERT - Already attached - should throw
|
|
804
|
-
expect(() => {
|
|
805
|
-
parent.attachChild(child);
|
|
806
|
-
}).toThrow(/already attached/);
|
|
807
|
-
|
|
808
|
-
// ASSERT - State unchanged after error
|
|
809
|
-
expect(parent.children).toEqual(childrenBefore);
|
|
810
|
-
expect(parent.node.children).toEqual(nodeChildrenBefore);
|
|
811
|
-
|
|
812
|
-
verifyTreeMirror(parent);
|
|
813
|
-
});
|
|
814
|
-
|
|
815
|
-
it('should satisfy commutativity property for siblings', () => {
|
|
816
|
-
// ARRANGE
|
|
817
|
-
const parent = new SimpleWorkflow('Parent');
|
|
818
|
-
const child1 = new SimpleWorkflow('Child1');
|
|
819
|
-
const child2 = new SimpleWorkflow('Child2');
|
|
820
|
-
const child3 = new SimpleWorkflow('Child3');
|
|
821
|
-
|
|
822
|
-
// ACT - Attach in order 1, 2, 3
|
|
823
|
-
parent.attachChild(child1);
|
|
824
|
-
parent.attachChild(child2);
|
|
825
|
-
parent.attachChild(child3);
|
|
826
|
-
|
|
827
|
-
const structure1 = [...parent.children];
|
|
828
|
-
|
|
829
|
-
// Clean up
|
|
830
|
-
parent.detachChild(child1);
|
|
831
|
-
parent.detachChild(child2);
|
|
832
|
-
parent.detachChild(child3);
|
|
833
|
-
|
|
834
|
-
// Attach in order 3, 2, 1
|
|
835
|
-
parent.attachChild(child3);
|
|
836
|
-
parent.attachChild(child2);
|
|
837
|
-
parent.attachChild(child1);
|
|
838
|
-
|
|
839
|
-
const structure2 = [...parent.children];
|
|
840
|
-
|
|
841
|
-
// ASSERT - Same children (in insertion order)
|
|
842
|
-
expect(structure1).toEqual([child1, child2, child3]);
|
|
843
|
-
expect(structure2).toEqual([child3, child2, child1]);
|
|
844
|
-
|
|
845
|
-
verifyTreeMirror(parent);
|
|
846
|
-
});
|
|
847
|
-
});
|