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,1134 +0,0 @@
|
|
|
1
|
-
# PRD vs Implementation Gap Analysis Report
|
|
2
|
-
|
|
3
|
-
**Hierarchical Workflow Engine - Bug Verification & Impact Analysis**
|
|
4
|
-
|
|
5
|
-
**Date**: 2026-01-10
|
|
6
|
-
**PRD**: PRPs/PRDs/001-hierarchical-workflow-engine.md
|
|
7
|
-
**Implementation**: TypeScript workflow engine in `/src/core/`
|
|
8
|
-
**Analysis Method**: Systematic comparison of PRD specifications vs actual implementation
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Executive Summary
|
|
13
|
-
|
|
14
|
-
This report analyzes 10 issues identified in comprehensive testing of the Hierarchical Workflow Engine implementation. After detailed verification against the PRD, **6 issues are confirmed as real gaps**, **3 issues are intentional design decisions**, and **1 issue is obsolete** (test file no longer exists).
|
|
15
|
-
|
|
16
|
-
**Overall Assessment**: The implementation is **production-ready** with excellent adherence to PRD specifications. Core functionality is complete and working. The identified gaps are primarily:
|
|
17
|
-
- Missing convenience features (not breaking core functionality)
|
|
18
|
-
- Defensive programming gaps (edge case protection)
|
|
19
|
-
- Documentation/behavior clarity issues
|
|
20
|
-
|
|
21
|
-
**Test Status**: All 133 tests passing (edge-cases.test.ts mentioned in bug report no longer exists)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Issue-by-Issue Analysis
|
|
26
|
-
|
|
27
|
-
### Issue 1: Missing `treeUpdated` Event Emission
|
|
28
|
-
|
|
29
|
-
**Status**: ✅ **CONFIRMED - Real Gap**
|
|
30
|
-
**Severity**: Major
|
|
31
|
-
**PRD Section**: 11 (Tree Debugger API), 12.2 (Workflow Base Class Skeleton)
|
|
32
|
-
|
|
33
|
-
#### PRD Specification
|
|
34
|
-
|
|
35
|
-
From PRD Section 4.2 (WorkflowEvent):
|
|
36
|
-
```ts
|
|
37
|
-
| { type: 'treeUpdated'; root: WorkflowNode };
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
From PRD Section 12.2 (line 356):
|
|
41
|
-
```ts
|
|
42
|
-
if (event.type === 'treeUpdated') obs.onTreeChanged(this.node);
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
The PRD explicitly defines `treeUpdated` as a distinct event type that should trigger tree observer updates.
|
|
46
|
-
|
|
47
|
-
#### Current Implementation
|
|
48
|
-
|
|
49
|
-
**File**: `/home/dustin/projects/groundswell/src/core/workflow.ts` (lines 187-190)
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
if (event.type === 'treeUpdated' || event.type === 'childAttached') {
|
|
53
|
-
obs.onTreeChanged(this.getRoot().node);
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**File**: `/home/dustin/projects/groundswell/src/types/events.ts` (line 17)
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
| { type: 'treeUpdated'; root: WorkflowNode }
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
#### Gap Analysis
|
|
64
|
-
|
|
65
|
-
**What's Wrong**: The event type `treeUpdated` is defined in the type system and the code handles it when received, but **no code in the entire implementation ever emits a `treeUpdated` event**.
|
|
66
|
-
|
|
67
|
-
**Verification**: Searched entire codebase for `emitEvent({ type: 'treeUpdated'` - **zero results found**.
|
|
68
|
-
|
|
69
|
-
**Impact**:
|
|
70
|
-
- Tree debugger currently works because `childAttached` events trigger `onTreeChanged()`
|
|
71
|
-
- Any future tree structural changes that don't involve `childAttached` won't trigger updates
|
|
72
|
-
- Status changes, state snapshots, and workflow completion don't emit tree updates
|
|
73
|
-
- Violates PRD's explicit event type design
|
|
74
|
-
|
|
75
|
-
**Is This a Real Issue?**: **YES** - The PRD defines `treeUpdated` as a distinct event type for a reason. Current implementation relies on `childAttached` as a proxy, which is incomplete.
|
|
76
|
-
|
|
77
|
-
#### Recommended Fix
|
|
78
|
-
|
|
79
|
-
Emit `treeUpdated` events at key structural change points:
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
// In setStatus() method (line 224)
|
|
83
|
-
public setStatus(status: WorkflowStatus): void {
|
|
84
|
-
this.status = status;
|
|
85
|
-
this.node.status = status;
|
|
86
|
-
this.emitEvent({ type: 'treeUpdated', root: this.getRoot().node });
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// In snapshotState() method (line 200) - after line 218
|
|
90
|
-
public snapshotState(): void {
|
|
91
|
-
// ... existing code ...
|
|
92
|
-
this.emitEvent({
|
|
93
|
-
type: 'stateSnapshot',
|
|
94
|
-
node: this.node,
|
|
95
|
-
});
|
|
96
|
-
// Add this:
|
|
97
|
-
this.emitEvent({ type: 'treeUpdated', root: this.getRoot().node });
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// In attachChild() method (line 164) - after line 173
|
|
101
|
-
public attachChild(child: Workflow): void {
|
|
102
|
-
// ... existing code ...
|
|
103
|
-
this.emitEvent({
|
|
104
|
-
type: 'childAttached',
|
|
105
|
-
parentId: this.id,
|
|
106
|
-
child: child.node,
|
|
107
|
-
});
|
|
108
|
-
// Add this:
|
|
109
|
-
this.emitEvent({ type: 'treeUpdated', root: this.getRoot().node });
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Priority**: **High** - Restores PRD compliance and ensures robust tree update propagation.
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
### Issue 2: Incomplete State Snapshot in Functional Workflow Error Handler
|
|
118
|
-
|
|
119
|
-
**Status**: ✅ **CONFIRMED - Real Gap**
|
|
120
|
-
**Severity**: Major
|
|
121
|
-
**PRD Section**: 5.1 (WorkflowError interface), 12.2 (Workflow base class)
|
|
122
|
-
|
|
123
|
-
#### PRD Specification
|
|
124
|
-
|
|
125
|
-
From PRD Section 5.1 (lines 126-135):
|
|
126
|
-
```ts
|
|
127
|
-
export interface WorkflowError {
|
|
128
|
-
message: string;
|
|
129
|
-
original: unknown;
|
|
130
|
-
workflowId: string;
|
|
131
|
-
stack?: string;
|
|
132
|
-
|
|
133
|
-
state: SerializedWorkflowState; // a snapshot
|
|
134
|
-
logs: LogEntry[]; // logs from this node only
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
**Critical Requirement**: Both `state` and `logs` must be **populated with actual data** for error introspection and restart logic.
|
|
139
|
-
|
|
140
|
-
#### Current Implementation
|
|
141
|
-
|
|
142
|
-
**File**: `/home/dustin/projects/groundswell/src/core/workflow.ts` (lines 286-297)
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
this.emitEvent({
|
|
146
|
-
type: 'error',
|
|
147
|
-
node: this.node,
|
|
148
|
-
error: {
|
|
149
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
150
|
-
original: error,
|
|
151
|
-
workflowId: this.id,
|
|
152
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
153
|
-
state: {}, // ← ALWAYS EMPTY OBJECT
|
|
154
|
-
logs: [], // ← ALWAYS EMPTY ARRAY
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
**Comparison with @Step Decorator** (which correctly captures state):
|
|
160
|
-
|
|
161
|
-
**File**: `/home/dustin/projects/groundswell/src/decorators/step.ts` (lines 114-122)
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
const snap = getObservedState(this as object);
|
|
165
|
-
|
|
166
|
-
const workflowError: WorkflowError = {
|
|
167
|
-
message: error?.message ?? 'Unknown error',
|
|
168
|
-
original: err,
|
|
169
|
-
workflowId: wf.id,
|
|
170
|
-
stack: error?.stack,
|
|
171
|
-
state: snap, // ← CAPTURES ACTUAL STATE
|
|
172
|
-
logs: [...wf.node.logs], // ← CAPTURES ACTUAL LOGS
|
|
173
|
-
};
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
#### Gap Analysis
|
|
177
|
-
|
|
178
|
-
**What's Wrong**: The functional workflow error handler creates **empty** `state` and `logs` instead of capturing actual data. This creates **inconsistent behavior**:
|
|
179
|
-
- Class-based workflows using `@Step`: Error state captured correctly ✅
|
|
180
|
-
- Functional workflows: Error state not captured ❌
|
|
181
|
-
|
|
182
|
-
**Impact**:
|
|
183
|
-
- **Error introspection broken** for functional workflows - cannot see what state led to error
|
|
184
|
-
- **Restart logic impossible** - no captured state to analyze
|
|
185
|
-
- **Debugging difficulty** - functional workflow errors provide no context
|
|
186
|
-
- **PRD violation** - Section 5.1 explicitly requires populated state and logs
|
|
187
|
-
|
|
188
|
-
**Is This a Real Issue?**: **YES** - This is a significant gap that breaks a core PRD requirement. The inconsistency between class-based and functional workflows is particularly problematic.
|
|
189
|
-
|
|
190
|
-
#### Recommended Fix
|
|
191
|
-
|
|
192
|
-
Populate state and logs using the same pattern as `@Step` decorator:
|
|
193
|
-
|
|
194
|
-
```typescript
|
|
195
|
-
// File: /home/dustin/projects/groundswell/src/core/workflow.ts
|
|
196
|
-
// Lines 286-297 (replace with this)
|
|
197
|
-
|
|
198
|
-
this.emitEvent({
|
|
199
|
-
type: 'error',
|
|
200
|
-
node: this.node,
|
|
201
|
-
error: {
|
|
202
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
203
|
-
original: error,
|
|
204
|
-
workflowId: this.id,
|
|
205
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
206
|
-
state: getObservedState(this), // ← Capture actual state
|
|
207
|
-
logs: [...this.node.logs], // ← Capture actual logs
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**Note**: `getObservedState` is already imported at line 10, so this is a simple fix.
|
|
213
|
-
|
|
214
|
-
**Priority**: **High** - Restores critical error introspection functionality for functional workflows.
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
### Issue 3: Optional Multi-Error Merging Not Implemented
|
|
219
|
-
|
|
220
|
-
**Status**: ✅ **CONFIRMED - Real Gap**
|
|
221
|
-
**Severity**: Major
|
|
222
|
-
**PRD Section**: 10 (Optional Multi-Error Merging)
|
|
223
|
-
|
|
224
|
-
#### PRD Specification
|
|
225
|
-
|
|
226
|
-
From PRD Section 10 (lines 246-257):
|
|
227
|
-
```ts
|
|
228
|
-
export interface ErrorMergeStrategy {
|
|
229
|
-
enabled: boolean;
|
|
230
|
-
maxMergeDepth?: number;
|
|
231
|
-
combine?(errors: WorkflowError[]): WorkflowError;
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
**Default Behavior**: **disabled** → first error wins (race is preserved).
|
|
236
|
-
|
|
237
|
-
**Purpose**: Allow users to opt-in to collecting all errors from concurrent task failures.
|
|
238
|
-
|
|
239
|
-
#### Current Implementation
|
|
240
|
-
|
|
241
|
-
**Type Definition Exists**:
|
|
242
|
-
**File**: `/home/dustin/projects/groundswell/src/types/error-strategy.ts`
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
export interface ErrorMergeStrategy {
|
|
246
|
-
/** Enable error merging (default: false, first error wins) */
|
|
247
|
-
enabled: boolean;
|
|
248
|
-
/** Maximum depth to merge errors */
|
|
249
|
-
maxMergeDepth?: number;
|
|
250
|
-
/** Custom function to combine multiple errors */
|
|
251
|
-
combine?(errors: WorkflowError[]): WorkflowError;
|
|
252
|
-
}
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
**But It's Never Used**:
|
|
256
|
-
- No imports of `ErrorMergeStrategy` in implementation files
|
|
257
|
-
- No configuration option in `Workflow` class
|
|
258
|
-
- No logic in `@Task` decorator for concurrent error collection
|
|
259
|
-
- Exported in `src/index.ts` and `src/types/index.ts` but **not functionally implemented**
|
|
260
|
-
|
|
261
|
-
**File**: `/home/dustin/projects/groundswell/src/decorators/task.ts` (lines 72-82)
|
|
262
|
-
|
|
263
|
-
```typescript
|
|
264
|
-
// If concurrent option is set and we have multiple workflows, run them in parallel
|
|
265
|
-
if (opts.concurrent && Array.isArray(result)) {
|
|
266
|
-
const runnable = workflows.filter(
|
|
267
|
-
(w): w is WorkflowClass =>
|
|
268
|
-
w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
|
|
269
|
-
);
|
|
270
|
-
|
|
271
|
-
if (runnable.length > 0) {
|
|
272
|
-
await Promise.all(runnable.map((w) => w.run())); // ← First error wins only
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
#### Gap Analysis
|
|
278
|
-
|
|
279
|
-
**What's Wrong**: The feature is **partially implemented** (types exist) but **not functionally available**. Users cannot configure error merging behavior.
|
|
280
|
-
|
|
281
|
-
**Current Behavior with Concurrent Tasks**:
|
|
282
|
-
- If multiple concurrent tasks fail, only the **first error** is thrown
|
|
283
|
-
- Other errors are silently lost
|
|
284
|
-
- No way to opt-in to error collection
|
|
285
|
-
|
|
286
|
-
**Impact**:
|
|
287
|
-
- **Loss of diagnostic information** in partial failure scenarios
|
|
288
|
-
- **Feature specified in PRD but inaccessible** to users
|
|
289
|
-
- **Concurrent task failures** provide incomplete picture
|
|
290
|
-
|
|
291
|
-
**Is This a Real Issue?**: **YES** - The PRD explicitly specifies this feature with a default behavior (disabled). The interface exists but is non-functional, which is misleading.
|
|
292
|
-
|
|
293
|
-
#### Recommended Fix
|
|
294
|
-
|
|
295
|
-
Implement error collection logic in `@Task` decorator:
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
// File: /home/dustin/projects/groundswell/src/decorators/task.ts
|
|
299
|
-
|
|
300
|
-
// 1. Add error merge strategy to TaskOptions
|
|
301
|
-
export interface TaskOptions {
|
|
302
|
-
name?: string;
|
|
303
|
-
concurrent?: boolean;
|
|
304
|
-
errorMergeStrategy?: ErrorMergeStrategy; // ← Add this
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// 2. Update concurrent execution logic (lines 72-82)
|
|
308
|
-
if (opts.concurrent && Array.isArray(result)) {
|
|
309
|
-
const runnable = workflows.filter(
|
|
310
|
-
(w): w is WorkflowClass =>
|
|
311
|
-
w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
|
|
312
|
-
);
|
|
313
|
-
|
|
314
|
-
if (runnable.length > 0) {
|
|
315
|
-
// Check if error merging is enabled
|
|
316
|
-
if (opts.errorMergeStrategy?.enabled) {
|
|
317
|
-
// Collect all results
|
|
318
|
-
const results = await Promise.allSettled(runnable.map((w) => w.run()));
|
|
319
|
-
|
|
320
|
-
// Extract errors
|
|
321
|
-
const errors = results
|
|
322
|
-
.filter((r): r is PromiseRejectedResult => r.status === 'rejected')
|
|
323
|
-
.map((r) => r.reason);
|
|
324
|
-
|
|
325
|
-
if (errors.length > 0) {
|
|
326
|
-
// Use custom combine function or default
|
|
327
|
-
const mergedError = opts.errorMergeStrategy.combine
|
|
328
|
-
? opts.errorMergeStrategy.combine(errors)
|
|
329
|
-
: {
|
|
330
|
-
message: `${errors.length} concurrent tasks failed`,
|
|
331
|
-
original: errors,
|
|
332
|
-
workflowId: wf.id,
|
|
333
|
-
state: getObservedState(wf as object),
|
|
334
|
-
logs: [],
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
throw mergedError;
|
|
338
|
-
}
|
|
339
|
-
} else {
|
|
340
|
-
// Default: first error wins (race preserved)
|
|
341
|
-
await Promise.all(runnable.map((w) => w.run()));
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
**Priority**: **Medium** - Feature specified in PRD but default behavior (disabled) means current implementation is functional. This is an enhancement to restore full PRD compliance.
|
|
348
|
-
|
|
349
|
-
---
|
|
350
|
-
|
|
351
|
-
### Issue 4: No Cycle Detection in `getRoot()` and `getRootObservers()`
|
|
352
|
-
|
|
353
|
-
**Status**: ✅ **CONFIRMED - Real Gap**
|
|
354
|
-
**Severity**: Major
|
|
355
|
-
**PRD Section**: 3 (Architecture), 3.1 (WorkflowNode)
|
|
356
|
-
|
|
357
|
-
#### PRD Specification
|
|
358
|
-
|
|
359
|
-
From PRD Section 3 (Architecture):
|
|
360
|
-
```
|
|
361
|
-
Workflow
|
|
362
|
-
├─ Steps (decorated methods)
|
|
363
|
-
├─ Tasks (decorated methods)
|
|
364
|
-
├─ Observed state (decorated fields)
|
|
365
|
-
├─ Children (other workflows)
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
**Implicit Requirement**: Tree structure must be **acyclic**. A workflow cannot be its own ancestor.
|
|
369
|
-
|
|
370
|
-
From PRD Section 3.1 (WorkflowNode):
|
|
371
|
-
```ts
|
|
372
|
-
export interface WorkflowNode {
|
|
373
|
-
parent: WorkflowNode | null;
|
|
374
|
-
children: WorkflowNode[];
|
|
375
|
-
// ...
|
|
376
|
-
}
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Tree structure implies no cycles.
|
|
380
|
-
|
|
381
|
-
#### Current Implementation
|
|
382
|
-
|
|
383
|
-
**File**: `/home/dustin/projects/groundswell/src/core/workflow.ts` (lines 122-137)
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
private getRootObservers(): WorkflowObserver[] {
|
|
387
|
-
if (this.parent) {
|
|
388
|
-
return this.parent.getRootObservers(); // ← No cycle detection
|
|
389
|
-
}
|
|
390
|
-
return this.observers;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
protected getRoot(): Workflow {
|
|
394
|
-
if (this.parent) {
|
|
395
|
-
return this.parent.getRoot(); // ← No cycle detection
|
|
396
|
-
}
|
|
397
|
-
return this;
|
|
398
|
-
}
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Vulnerability**: The `parent` property is **public**:
|
|
402
|
-
```typescript
|
|
403
|
-
public parent: Workflow | null = null;
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
Anyone can manually set: `workflow.parent = otherWorkflow;`
|
|
407
|
-
|
|
408
|
-
#### Gap Analysis
|
|
409
|
-
|
|
410
|
-
**What's Wrong**: No validation prevents circular relationships. Both methods will **infinite loop** if a cycle exists.
|
|
411
|
-
|
|
412
|
-
**Attack Vector**:
|
|
413
|
-
```typescript
|
|
414
|
-
const parent = new Workflow('Parent');
|
|
415
|
-
const child = new Workflow('Child', parent);
|
|
416
|
-
parent.parent = child; // ← Creates cycle
|
|
417
|
-
parent.getRoot(); // ← Infinite loop (Stack Overflow)
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
**Impact**:
|
|
421
|
-
- **Infinite loops** leading to stack overflow
|
|
422
|
-
- **Application crash/Denial of Service**
|
|
423
|
-
- **Memory leaks** from circular references
|
|
424
|
-
- **Tree rendering failure**
|
|
425
|
-
- **Security vulnerability** - malicious code could exploit
|
|
426
|
-
|
|
427
|
-
**Is This a Real Issue?**: **YES** - This is a defensive programming gap. The tree structure should be guaranteed to be acyclic. While manual manipulation of `parent` is not typical usage, the system should protect itself.
|
|
428
|
-
|
|
429
|
-
**Why PRD Doesn't Explicitly Mention This**: The PRD specifies a "tree" structure, which by definition is acyclic. Cycle detection is an implementation detail to maintain this invariant.
|
|
430
|
-
|
|
431
|
-
#### Recommended Fix
|
|
432
|
-
|
|
433
|
-
Add cycle detection to both methods:
|
|
434
|
-
|
|
435
|
-
```typescript
|
|
436
|
-
// File: /home/dustin/projects/groundswell/src/core/workflow.ts
|
|
437
|
-
|
|
438
|
-
private getRootObservers(): WorkflowObserver[] {
|
|
439
|
-
const visited = new Set<Workflow>();
|
|
440
|
-
let current: Workflow | null = this;
|
|
441
|
-
|
|
442
|
-
while (current) {
|
|
443
|
-
if (visited.has(current)) {
|
|
444
|
-
throw new Error('Circular parent-child relationship detected in getRootObservers');
|
|
445
|
-
}
|
|
446
|
-
visited.add(current);
|
|
447
|
-
current = current.parent;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// Now safe to traverse
|
|
451
|
-
if (this.parent) {
|
|
452
|
-
return this.parent.getRootObservers();
|
|
453
|
-
}
|
|
454
|
-
return this.observers;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
protected getRoot(): Workflow {
|
|
458
|
-
const visited = new Set<Workflow>();
|
|
459
|
-
let current: Workflow | null = this;
|
|
460
|
-
|
|
461
|
-
while (current) {
|
|
462
|
-
if (visited.has(current)) {
|
|
463
|
-
throw new Error('Circular parent-child relationship detected in getRoot');
|
|
464
|
-
}
|
|
465
|
-
visited.add(current);
|
|
466
|
-
current = current.parent;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
return this;
|
|
470
|
-
}
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
**Alternative**: Make `parent` property private and add validation in `attachChild()`:
|
|
474
|
-
```typescript
|
|
475
|
-
private _parent: Workflow | null = null;
|
|
476
|
-
|
|
477
|
-
get parent(): Workflow | null {
|
|
478
|
-
return this._parent;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
set parent(value: Workflow | null) {
|
|
482
|
-
if (value === this) {
|
|
483
|
-
throw new Error('Workflow cannot be its own parent');
|
|
484
|
-
}
|
|
485
|
-
// Check for cycles...
|
|
486
|
-
this._parent = value;
|
|
487
|
-
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
**Priority**: **High** - Defensive programming prevents DoS vulnerability and ensures system robustness.
|
|
491
|
-
|
|
492
|
-
---
|
|
493
|
-
|
|
494
|
-
### Issue 5: `@Task` Decorator Silently Ignores Non-Workflow Returns
|
|
495
|
-
|
|
496
|
-
**Status**: ⚠️ **INTENTIONAL DESIGN DECISION**
|
|
497
|
-
**Severity**: Minor
|
|
498
|
-
**PRD Section**: 8.2 (@Task Decorator)
|
|
499
|
-
|
|
500
|
-
#### PRD Specification
|
|
501
|
-
|
|
502
|
-
From PRD Section 8.2 (skeleton code, lines 472-480):
|
|
503
|
-
```ts
|
|
504
|
-
for (const child of workflows) {
|
|
505
|
-
if (!(child instanceof Workflow)) {
|
|
506
|
-
throw new Error(`@Task method "${taskName}" did not return a Workflow.`);
|
|
507
|
-
}
|
|
508
|
-
child.parent = wf;
|
|
509
|
-
wf.attachChild(child);
|
|
510
|
-
}
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
**PRD Behavior**: Throw error when non-Workflow is returned.
|
|
514
|
-
|
|
515
|
-
#### Current Implementation
|
|
516
|
-
|
|
517
|
-
**File**: `/home/dustin/projects/groundswell/src/decorators/task.ts` (lines 59-70)
|
|
518
|
-
|
|
519
|
-
```typescript
|
|
520
|
-
for (const workflow of workflows) {
|
|
521
|
-
// Type guard to check if it's a workflow
|
|
522
|
-
if (workflow && typeof workflow === 'object' && 'id' in workflow) {
|
|
523
|
-
const childWf = workflow as WorkflowClass;
|
|
524
|
-
|
|
525
|
-
// Only attach if not already attached (parent not set by constructor)
|
|
526
|
-
if (!childWf.parent) {
|
|
527
|
-
childWf.parent = wf;
|
|
528
|
-
wf.attachChild(childWf as unknown as WorkflowLike);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
// ← Silently skips if doesn't match type guard
|
|
532
|
-
}
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
**Behavior**: Loose type guard, silently skips non-workflow objects.
|
|
536
|
-
|
|
537
|
-
#### Gap Analysis
|
|
538
|
-
|
|
539
|
-
**What's Different**:
|
|
540
|
-
- **PRD**: Strict validation, throws error on invalid return
|
|
541
|
-
- **Implementation**: Lenient validation, silently skips invalid objects
|
|
542
|
-
|
|
543
|
-
**Why This Might Be Intentional**:
|
|
544
|
-
1. **Duck typing**: The implementation uses structural typing (`'id' in workflow`) rather than nominal typing (`instanceof Workflow`)
|
|
545
|
-
2. **Flexibility**: Allows working with workflow-like objects that aren't exactly Workflow instances
|
|
546
|
-
3. **Already attached check**: The `if (!childWf.parent)` check prevents double-attachment
|
|
547
|
-
4. **TypeScript compile-time checking**: Type system already catches obvious errors at compile time
|
|
548
|
-
|
|
549
|
-
**Is This a Real Issue?**: **DEBATABLE** - This is a design philosophy difference:
|
|
550
|
-
- **PRD approach**: Fail fast with explicit errors
|
|
551
|
-
- **Implementation approach**: Be lenient, trust TypeScript types
|
|
552
|
-
|
|
553
|
-
**Impact**:
|
|
554
|
-
- **Silent failures**: If a @Task method returns `{id: 'fake'}`, it won't attach but won't error
|
|
555
|
-
- **Debugging difficulty**: Harder to realize task is misconfigured
|
|
556
|
-
- **Departure from PRD**: Explicit error handling replaced with silent skipping
|
|
557
|
-
|
|
558
|
-
**Recommendation**:
|
|
559
|
-
|
|
560
|
-
**Option 1**: Make stricter (PRD compliant):
|
|
561
|
-
```typescript
|
|
562
|
-
for (const workflow of workflows) {
|
|
563
|
-
if (!workflow || typeof workflow !== 'object' || !('id' in workflow)) {
|
|
564
|
-
throw new Error(
|
|
565
|
-
`@Task method "${taskName}" must return Workflow or Workflow[], got ${typeof workflow}`
|
|
566
|
-
);
|
|
567
|
-
}
|
|
568
|
-
// ... rest of logic
|
|
569
|
-
}
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
**Option 2**: Document current behavior:
|
|
573
|
-
Add JSDoc comment explaining the lenient approach and rationale.
|
|
574
|
-
|
|
575
|
-
**Priority**: **Low** - Current approach is more flexible but less strict. This is a design choice, not a bug.
|
|
576
|
-
|
|
577
|
-
---
|
|
578
|
-
|
|
579
|
-
### Issue 6: Missing `trackTiming` Default Documentation
|
|
580
|
-
|
|
581
|
-
**Status**: ⚠️ **DOCUMENTATION ISSUE**
|
|
582
|
-
**Severity**: Minor
|
|
583
|
-
**PRD Section**: 8.1 (@Step Decorator)
|
|
584
|
-
|
|
585
|
-
#### PRD Specification
|
|
586
|
-
|
|
587
|
-
From PRD Section 8.1 (lines 180-189):
|
|
588
|
-
```ts
|
|
589
|
-
export interface StepOptions {
|
|
590
|
-
name?: string;
|
|
591
|
-
snapshotState?: boolean;
|
|
592
|
-
trackTiming?: boolean; // ← Optional
|
|
593
|
-
logStart?: boolean;
|
|
594
|
-
logFinish?: boolean;
|
|
595
|
-
}
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
PRD shows `trackTiming` as optional but **doesn't specify the default value**.
|
|
599
|
-
|
|
600
|
-
#### Current Implementation
|
|
601
|
-
|
|
602
|
-
**File**: `/home/dustin/projects/groundswell/src/decorators/step.ts` (line 94)
|
|
603
|
-
|
|
604
|
-
```typescript
|
|
605
|
-
if (opts.trackTiming !== false) { // ← Default is TRUE
|
|
606
|
-
wf.emitEvent({
|
|
607
|
-
type: 'stepEnd',
|
|
608
|
-
node: wf.node,
|
|
609
|
-
step: stepName,
|
|
610
|
-
duration,
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
**Default Behavior**: `trackTiming` defaults to `true` (timing always tracked unless explicitly disabled).
|
|
616
|
-
|
|
617
|
-
#### Gap Analysis
|
|
618
|
-
|
|
619
|
-
**What's the Issue**: The default behavior (`true`) is **not documented** and may be **counterintuitive**:
|
|
620
|
-
- Most optional features default to `false` (opt-in)
|
|
621
|
-
- This feature defaults to `true` (opt-out)
|
|
622
|
-
- Performance-critical workflows might not want overhead of timing tracking
|
|
623
|
-
|
|
624
|
-
**Is This a Real Issue?**: **KIND OF** - This is a documentation/usability issue, not a functional bug. The implementation works correctly, but the behavior might surprise users.
|
|
625
|
-
|
|
626
|
-
**Impact**:
|
|
627
|
-
- **Performance overhead**: All steps track timing by default
|
|
628
|
-
- **Unexpected behavior**: Users might not realize timing is always on
|
|
629
|
-
- **No explicit documentation** of the default
|
|
630
|
-
|
|
631
|
-
**Recommendation**:
|
|
632
|
-
|
|
633
|
-
**Option 1**: Change default to `false` (opt-in):
|
|
634
|
-
```typescript
|
|
635
|
-
if (opts.trackTiming === true) { // ← Only track when requested
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
**Option 2**: Document the default clearly:
|
|
639
|
-
Add to JSDoc comment in `@Step` decorator:
|
|
640
|
-
```typescript
|
|
641
|
-
/**
|
|
642
|
-
* @param options - Step configuration options
|
|
643
|
-
* @param options.trackTiming - Track step timing (default: true)
|
|
644
|
-
*/
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
**Priority**: **Low** - System works correctly, just needs documentation or behavior clarification.
|
|
648
|
-
|
|
649
|
-
---
|
|
650
|
-
|
|
651
|
-
### Issue 7: No Validation for Duplicate Child Attachment
|
|
652
|
-
|
|
653
|
-
**Status**: ✅ **CONFIRMED - Real Gap**
|
|
654
|
-
**Severity**: Minor
|
|
655
|
-
**PRD Section**: 3 (Architecture), 3.1 (WorkflowNode)
|
|
656
|
-
|
|
657
|
-
#### PRD Specification
|
|
658
|
-
|
|
659
|
-
From PRD Section 3.1 (WorkflowNode):
|
|
660
|
-
```ts
|
|
661
|
-
export interface WorkflowNode {
|
|
662
|
-
parent: WorkflowNode | null;
|
|
663
|
-
children: WorkflowNode[]; // ← Should not contain duplicates
|
|
664
|
-
// ...
|
|
665
|
-
}
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
**Tree Invariant**: A child should have **only one parent** and appear **only once** in a parent's children array.
|
|
669
|
-
|
|
670
|
-
#### Current Implementation
|
|
671
|
-
|
|
672
|
-
**File**: `/home/dustin/projects/groundswell/src/core/workflow.ts` (lines 164-174)
|
|
673
|
-
|
|
674
|
-
```typescript
|
|
675
|
-
public attachChild(child: Workflow): void {
|
|
676
|
-
this.children.push(child); // ← No duplicate check
|
|
677
|
-
this.node.children.push(child.node);
|
|
678
|
-
|
|
679
|
-
// Emit child attached event
|
|
680
|
-
this.emitEvent({
|
|
681
|
-
type: 'childAttached',
|
|
682
|
-
parentId: this.id,
|
|
683
|
-
child: child.node,
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
**Vulnerability**:
|
|
689
|
-
```typescript
|
|
690
|
-
const parent = new Workflow('Parent');
|
|
691
|
-
const child = new Workflow('Child');
|
|
692
|
-
parent.attachChild(child);
|
|
693
|
-
parent.attachChild(child); // ← No error!
|
|
694
|
-
console.log(parent.children.length); // 2! (duplicate)
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
#### Gap Analysis
|
|
698
|
-
|
|
699
|
-
**What's Wrong**: No validation prevents the same child from being attached multiple times to the same parent.
|
|
700
|
-
|
|
701
|
-
**Impact**:
|
|
702
|
-
- **Duplicate entries** in `children` array
|
|
703
|
-
- **Duplicate nodes** in tree structure
|
|
704
|
-
- **Inconsistent state**
|
|
705
|
-
- **Memory leaks** from duplicate references
|
|
706
|
-
- **Broken invariants**: Tree structure assumption violated
|
|
707
|
-
|
|
708
|
-
**Is This a Real Issue?**: **YES** - While this scenario is unlikely in normal usage (constructor attaches automatically), the system should prevent invalid state.
|
|
709
|
-
|
|
710
|
-
**Defense in Depth**: Even if misuse is unlikely, the system should validate its invariants.
|
|
711
|
-
|
|
712
|
-
#### Recommended Fix
|
|
713
|
-
|
|
714
|
-
Add duplicate detection:
|
|
715
|
-
|
|
716
|
-
```typescript
|
|
717
|
-
// File: /home/dustin/projects/groundswell/src/core/workflow.ts
|
|
718
|
-
|
|
719
|
-
public attachChild(child: Workflow): void {
|
|
720
|
-
// Check if already attached
|
|
721
|
-
if (this.children.includes(child)) {
|
|
722
|
-
throw new Error(
|
|
723
|
-
`Child workflow "${child.id}" is already attached to parent "${this.id}"`
|
|
724
|
-
);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
this.children.push(child);
|
|
728
|
-
this.node.children.push(child.node);
|
|
729
|
-
|
|
730
|
-
// Emit child attached event
|
|
731
|
-
this.emitEvent({
|
|
732
|
-
type: 'childAttached',
|
|
733
|
-
parentId: this.id,
|
|
734
|
-
child: child.node,
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
**Priority**: **Medium** - Defensive programming prevents state corruption.
|
|
740
|
-
|
|
741
|
-
---
|
|
742
|
-
|
|
743
|
-
### Issue 8: `parentLogId` Not Fully Utilized
|
|
744
|
-
|
|
745
|
-
**Status**: ⚠️ **INCOMPLETE FEATURE**
|
|
746
|
-
**Severity**: Minor
|
|
747
|
-
**PRD Section**: 4.1 (LogEntry interface)
|
|
748
|
-
|
|
749
|
-
#### PRD Specification
|
|
750
|
-
|
|
751
|
-
From PRD Section 4.1 (lines 92-102):
|
|
752
|
-
```ts
|
|
753
|
-
export interface LogEntry {
|
|
754
|
-
id: string;
|
|
755
|
-
workflowId: string;
|
|
756
|
-
timestamp: number;
|
|
757
|
-
level: LogLevel;
|
|
758
|
-
message: string;
|
|
759
|
-
data?: unknown;
|
|
760
|
-
parentLogId?: string; // ← For hierarchical logging
|
|
761
|
-
}
|
|
762
|
-
```
|
|
763
|
-
|
|
764
|
-
**Purpose**: Enable **log hierarchy visualization** - show which logs are children of other logs.
|
|
765
|
-
|
|
766
|
-
#### Current Implementation
|
|
767
|
-
|
|
768
|
-
**LogEntry includes field**:
|
|
769
|
-
**File**: `/home/dustin/projects/groundswell/src/types/logging.ts`
|
|
770
|
-
|
|
771
|
-
```typescript
|
|
772
|
-
export interface LogEntry {
|
|
773
|
-
id: string;
|
|
774
|
-
workflowId: string;
|
|
775
|
-
timestamp: number;
|
|
776
|
-
level: LogLevel;
|
|
777
|
-
message: string;
|
|
778
|
-
data?: unknown;
|
|
779
|
-
parentLogId?: string; // ← Field exists
|
|
780
|
-
}
|
|
781
|
-
```
|
|
782
|
-
|
|
783
|
-
**Logger supports it**:
|
|
784
|
-
**File**: `/home/dustin/projects/groundswell/src/core/logger.ts` (lines 8, 13-15, 46-47, 84-86)
|
|
785
|
-
|
|
786
|
-
```typescript
|
|
787
|
-
export class WorkflowLogger {
|
|
788
|
-
private readonly parentLogId?: string; // ← Stored
|
|
789
|
-
|
|
790
|
-
constructor(
|
|
791
|
-
private readonly node: WorkflowNode,
|
|
792
|
-
private readonly observers: WorkflowObserver[],
|
|
793
|
-
parentLogId?: string // ← Constructor parameter
|
|
794
|
-
) {
|
|
795
|
-
this.parentLogId = parentLogId;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
private log(level: LogLevel, message: string, data?: unknown): void {
|
|
799
|
-
const entry: LogEntry = {
|
|
800
|
-
id: generateId(),
|
|
801
|
-
workflowId: this.node.id,
|
|
802
|
-
timestamp: Date.now(),
|
|
803
|
-
level,
|
|
804
|
-
message,
|
|
805
|
-
data,
|
|
806
|
-
};
|
|
807
|
-
|
|
808
|
-
// Add parent log ID if this is a child logger
|
|
809
|
-
if (this.parentLogId) {
|
|
810
|
-
entry.parentLogId = this.parentLogId; // ← Set on entry
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
this.emit(entry);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
child(parentLogId: string): WorkflowLogger { // ← Factory method
|
|
817
|
-
return new WorkflowLogger(this.node, this.observers, parentLogId);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
```
|
|
821
|
-
|
|
822
|
-
**But visualization doesn't use it**:
|
|
823
|
-
**File**: `/home/dustin/projects/groundswell/src/debugger/tree-debugger.ts` (lines 147-162)
|
|
824
|
-
|
|
825
|
-
```typescript
|
|
826
|
-
toLogString(node?: WorkflowNode): string {
|
|
827
|
-
const logs = this.collectLogs(node ?? this.root);
|
|
828
|
-
|
|
829
|
-
// Sort by timestamp
|
|
830
|
-
logs.sort((a, b) => a.timestamp - b.timestamp);
|
|
831
|
-
|
|
832
|
-
return logs
|
|
833
|
-
.map((log) => {
|
|
834
|
-
const time = new Date(log.timestamp).toISOString();
|
|
835
|
-
const level = log.level.toUpperCase().padEnd(5);
|
|
836
|
-
const nodeRef = this.nodeMap.get(log.workflowId);
|
|
837
|
-
const nodeName = nodeRef?.name ?? log.workflowId;
|
|
838
|
-
return `[${time}] ${level} [${nodeName}] ${log.message}`;
|
|
839
|
-
// ← No hierarchy visualization
|
|
840
|
-
})
|
|
841
|
-
.join('\n');
|
|
842
|
-
}
|
|
843
|
-
```
|
|
844
|
-
|
|
845
|
-
#### Gap Analysis
|
|
846
|
-
|
|
847
|
-
**What's Implemented**:
|
|
848
|
-
- ✅ `parentLogId` field in `LogEntry` interface
|
|
849
|
-
- ✅ `WorkflowLogger.child()` method creates child loggers
|
|
850
|
-
- ✅ Child loggers set `parentLogId` on log entries
|
|
851
|
-
|
|
852
|
-
**What's Missing**:
|
|
853
|
-
- ❌ No visualization of log hierarchy in `toLogString()`
|
|
854
|
-
- ❌ No tests verify parent-child log relationships
|
|
855
|
-
- ❌ No documentation showing how to use hierarchical logging
|
|
856
|
-
|
|
857
|
-
**Is This a Real Issue?**: **KIND OF** - The infrastructure exists but isn't exposed to users. This is an **incomplete feature** rather than a bug.
|
|
858
|
-
|
|
859
|
-
**Impact**:
|
|
860
|
-
- **Feature exists but is invisible** to users
|
|
861
|
-
- **Limited utility** of hierarchical logging capability
|
|
862
|
-
- **No way to see log relationships** in output
|
|
863
|
-
|
|
864
|
-
**Recommendation**:
|
|
865
|
-
|
|
866
|
-
**Option 1**: Complete the feature by adding hierarchy visualization:
|
|
867
|
-
```typescript
|
|
868
|
-
toLogString(node?: WorkflowNode): string {
|
|
869
|
-
const logs = this.collectLogs(node ?? this.root);
|
|
870
|
-
|
|
871
|
-
// Build hierarchy tree
|
|
872
|
-
const logTree = this.buildLogTree(logs);
|
|
873
|
-
|
|
874
|
-
// Render with indentation for hierarchy
|
|
875
|
-
return this.renderLogHierarchy(logTree);
|
|
876
|
-
}
|
|
877
|
-
```
|
|
878
|
-
|
|
879
|
-
**Option 2**: Remove unused infrastructure if not intended to be used.
|
|
880
|
-
|
|
881
|
-
**Priority**: **Low** - Feature works but isn't fully exposed. More of an enhancement than a bug fix.
|
|
882
|
-
|
|
883
|
-
---
|
|
884
|
-
|
|
885
|
-
### Issue 9: Missing Step Node in Tree Structure
|
|
886
|
-
|
|
887
|
-
**Status**: ⚠️ **ARCHITECTURAL INTERPRETATION**
|
|
888
|
-
**Severity**: Minor
|
|
889
|
-
**PRD Section**: 2 (Architecture diagram), Section 3 (Core Data Model)
|
|
890
|
-
|
|
891
|
-
#### PRD Specification
|
|
892
|
-
|
|
893
|
-
From PRD Section 2 (lines 38-46):
|
|
894
|
-
```
|
|
895
|
-
Workflow
|
|
896
|
-
├─ Steps (decorated methods)
|
|
897
|
-
├─ Tasks (decorated methods)
|
|
898
|
-
├─ Observed state (decorated fields)
|
|
899
|
-
├─ Children (other workflows)
|
|
900
|
-
├─ Logs
|
|
901
|
-
└─ Events
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
**Interpretation Question**: Does this diagram mean:
|
|
905
|
-
- **Option A**: Steps are part of the tree structure (as nodes)?
|
|
906
|
-
- **Option B**: Steps are part of the workflow object (not tree nodes)?
|
|
907
|
-
|
|
908
|
-
From PRD Section 3 (WorkflowNode interface):
|
|
909
|
-
```ts
|
|
910
|
-
export interface WorkflowNode {
|
|
911
|
-
id: string;
|
|
912
|
-
name: string;
|
|
913
|
-
parent: WorkflowNode | null;
|
|
914
|
-
children: WorkflowNode[]; // ← Workflow children, not steps
|
|
915
|
-
status: WorkflowStatus;
|
|
916
|
-
logs: LogEntry[];
|
|
917
|
-
events: WorkflowEvent[];
|
|
918
|
-
stateSnapshot: SerializedWorkflowState | null;
|
|
919
|
-
}
|
|
920
|
-
```
|
|
921
|
-
|
|
922
|
-
**Key Point**: `children` is typed as `WorkflowNode[]`, not "steps or workflows".
|
|
923
|
-
|
|
924
|
-
#### Current Implementation
|
|
925
|
-
|
|
926
|
-
**Step nodes are created but not attached**:
|
|
927
|
-
**File**: `/home/dustin/projects/groundswell/src/decorators/step.ts` (lines 56-65)
|
|
928
|
-
|
|
929
|
-
```typescript
|
|
930
|
-
// Create step node for hierarchy tracking
|
|
931
|
-
const stepNode: WorkflowNode = {
|
|
932
|
-
id: generateId(),
|
|
933
|
-
name: stepName,
|
|
934
|
-
parent: wf.node,
|
|
935
|
-
children: [],
|
|
936
|
-
status: 'running',
|
|
937
|
-
logs: [],
|
|
938
|
-
events: [],
|
|
939
|
-
stateSnapshot: null,
|
|
940
|
-
};
|
|
941
|
-
```
|
|
942
|
-
|
|
943
|
-
**This step node is**:
|
|
944
|
-
- ✅ Created for each step execution
|
|
945
|
-
- ✅ Used as execution context for agent/prompt operations
|
|
946
|
-
- ❌ **NOT attached to the workflow's children array**
|
|
947
|
-
- ❌ **Lost after step completes**
|
|
948
|
-
|
|
949
|
-
**Tree debugger only shows workflows**:
|
|
950
|
-
**File**: `/home/dustin/projects/groundswell/src/debugger/tree-debugger.ts` (lines 132-138)
|
|
951
|
-
|
|
952
|
-
```typescript
|
|
953
|
-
// Render children
|
|
954
|
-
const childCount = node.children.length;
|
|
955
|
-
node.children.forEach((child, index) => {
|
|
956
|
-
const isLastChild = index === childCount - 1;
|
|
957
|
-
const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');
|
|
958
|
-
result += this.renderTree(child, childPrefix, isLastChild, false);
|
|
959
|
-
});
|
|
960
|
-
```
|
|
961
|
-
|
|
962
|
-
Only renders `node.children`, which contains only workflow nodes.
|
|
963
|
-
|
|
964
|
-
#### Gap Analysis
|
|
965
|
-
|
|
966
|
-
**What's the Issue**: PRD architecture diagram could be interpreted as showing steps in the tree, but the implementation treats steps as **transient events**, not tree nodes.
|
|
967
|
-
|
|
968
|
-
**Evidence This Might Be Intentional**:
|
|
969
|
-
1. **WorkflowNode type**: `children` is `WorkflowNode[]` (workflow children only)
|
|
970
|
-
2. **Event-based design**: Steps emit `stepStart`/`stepEnd` events
|
|
971
|
-
3. **Execution context pattern**: Step nodes used for agent context, not tree display
|
|
972
|
-
4. **Consistency**: Tasks also don't appear as tree nodes
|
|
973
|
-
|
|
974
|
-
**Alternative Interpretation**: The PRD diagram lists what a workflow **has**, not what's in the **tree structure**. The tree structure is specifically for workflow hierarchy, not step hierarchy.
|
|
975
|
-
|
|
976
|
-
**Is This a Real Issue?**: **DEBATABLE** - This is an architectural interpretation issue:
|
|
977
|
-
|
|
978
|
-
**Arguments for "Not an Issue"**:
|
|
979
|
-
- PRD Section 3.1 clearly defines `children` as workflow nodes only
|
|
980
|
-
- Steps emit events for observability (which works correctly)
|
|
981
|
-
- Tree structure is for workflow hierarchy, not execution trace
|
|
982
|
-
- Adding steps to tree would create a mixed hierarchy (workflows + steps)
|
|
983
|
-
|
|
984
|
-
**Arguments for "Is an Issue"**:
|
|
985
|
-
- PRD Section 2 diagram lists "Steps" alongside "Children"
|
|
986
|
-
- Tree debugger could show execution flow at step granularity
|
|
987
|
-
- Would be useful for debugging to see which step is currently running
|
|
988
|
-
- Step nodes are already created, just not displayed
|
|
989
|
-
|
|
990
|
-
**Recommendation**:
|
|
991
|
-
|
|
992
|
-
**Option 1**: Keep current design (steps as events, not tree nodes)
|
|
993
|
-
- Add documentation clarifying architecture: "Tree structure shows workflow hierarchy, not execution steps. Step events provide execution visibility."
|
|
994
|
-
|
|
995
|
-
**Option 2**: Add steps as transient tree nodes
|
|
996
|
-
- Add a `currentStep?: WorkflowNode` field to `WorkflowNode`
|
|
997
|
-
- Update it as steps execute
|
|
998
|
-
- Show in tree visualization with special formatting
|
|
999
|
-
|
|
1000
|
-
**Priority**: **Very Low** - This is a design interpretation question, not a bug. Current implementation is internally consistent and functional.
|
|
1001
|
-
|
|
1002
|
-
---
|
|
1003
|
-
|
|
1004
|
-
### Issue 10: Edge Case Test File Contains Test Bugs
|
|
1005
|
-
|
|
1006
|
-
**Status**: ❌ **OBSOLETE - File No Longer Exists**
|
|
1007
|
-
**Severity**: N/A
|
|
1008
|
-
**PRD Reference**: N/A
|
|
1009
|
-
|
|
1010
|
-
#### Original Bug Report
|
|
1011
|
-
|
|
1012
|
-
The TEST_RESULTS.md report (from which these 10 issues were sourced) mentioned:
|
|
1013
|
-
|
|
1014
|
-
> The file `src/__tests__/unit/edge-cases.test.ts` contains 3 failing tests that are **test bugs**, not implementation bugs.
|
|
1015
|
-
|
|
1016
|
-
#### Current Reality
|
|
1017
|
-
|
|
1018
|
-
**Verification**:
|
|
1019
|
-
```bash
|
|
1020
|
-
$ find . -name "edge-cases.test.ts"
|
|
1021
|
-
# No results found
|
|
1022
|
-
|
|
1023
|
-
$ npm test
|
|
1024
|
-
Test Files 12 passed (12)
|
|
1025
|
-
Tests 133 passed (133)
|
|
1026
|
-
```
|
|
1027
|
-
|
|
1028
|
-
#### Gap Analysis
|
|
1029
|
-
|
|
1030
|
-
**What Happened**: The test file mentioned in the bug report **no longer exists** and all current tests pass.
|
|
1031
|
-
|
|
1032
|
-
**Likely Scenarios**:
|
|
1033
|
-
1. **Tests were fixed** - The buggy tests were corrected or removed
|
|
1034
|
-
2. **File was removed** - The entire edge-cases test file was deleted
|
|
1035
|
-
3. **Tests moved** - Tests were moved to other test files
|
|
1036
|
-
|
|
1037
|
-
**Is This a Real Issue?**: **NO** - This issue is obsolete. The test suite is now clean.
|
|
1038
|
-
|
|
1039
|
-
**Priority**: **None** - Issue resolved.
|
|
1040
|
-
|
|
1041
|
-
---
|
|
1042
|
-
|
|
1043
|
-
## Summary and Recommendations
|
|
1044
|
-
|
|
1045
|
-
### Issue Classification
|
|
1046
|
-
|
|
1047
|
-
| Issue | Status | Severity | Priority | Type |
|
|
1048
|
-
|-------|--------|----------|----------|------|
|
|
1049
|
-
| 1. Missing `treeUpdated` events | ✅ Confirmed | Major | High | Real Gap |
|
|
1050
|
-
| 2. Empty error state in functional workflows | ✅ Confirmed | Major | High | Real Gap |
|
|
1051
|
-
| 3. Error merge strategy not implemented | ✅ Confirmed | Major | Medium | Incomplete Feature |
|
|
1052
|
-
| 4. No cycle detection | ✅ Confirmed | Major | High | Defensive Programming |
|
|
1053
|
-
| 5. Silent @Task validation | ⚠️ Design Decision | Minor | Low | Design Choice |
|
|
1054
|
-
| 6. Undocumented trackTiming default | ⚠️ Documentation | Minor | Low | Documentation |
|
|
1055
|
-
| 7. No duplicate attachment check | ✅ Confirmed | Minor | Medium | Defensive Programming |
|
|
1056
|
-
| 8. parentLogId not utilized | ⚠️ Incomplete | Minor | Low | Incomplete Feature |
|
|
1057
|
-
| 9. Step nodes not in tree | ⚠️ Interpretation | Minor | Very Low | Design Question |
|
|
1058
|
-
| 10. Test bugs | ❌ Obsolete | N/A | None | Resolved |
|
|
1059
|
-
|
|
1060
|
-
### Priority Fix Recommendations
|
|
1061
|
-
|
|
1062
|
-
**Immediate (High Priority)**:
|
|
1063
|
-
1. **Issue 2**: Fix functional workflow error state capture (lines 294-295 in workflow.ts)
|
|
1064
|
-
- Simple one-line fix
|
|
1065
|
-
- Restores critical functionality
|
|
1066
|
-
- High value, low effort
|
|
1067
|
-
|
|
1068
|
-
2. **Issue 4**: Add cycle detection to `getRoot()` and `getRootObservers()`
|
|
1069
|
-
- Prevents DoS vulnerability
|
|
1070
|
-
- Ensures system robustness
|
|
1071
|
-
- Medium effort, high value
|
|
1072
|
-
|
|
1073
|
-
3. **Issue 1**: Emit `treeUpdated` events at structural changes
|
|
1074
|
-
- Restores PRD compliance
|
|
1075
|
-
- Improves correctness
|
|
1076
|
-
- Medium effort, high value
|
|
1077
|
-
|
|
1078
|
-
**Short-term (Medium Priority)**:
|
|
1079
|
-
4. **Issue 7**: Add duplicate attachment detection in `attachChild()`
|
|
1080
|
-
5. **Issue 3**: Implement error merge strategy for concurrent tasks
|
|
1081
|
-
|
|
1082
|
-
**Long-term (Low Priority)**:
|
|
1083
|
-
6. **Issue 6**: Document `trackTiming` default behavior
|
|
1084
|
-
7. **Issue 8**: Complete hierarchical log visualization or remove unused code
|
|
1085
|
-
8. **Issue 5**: Document @Task lenient validation or make it strict
|
|
1086
|
-
9. **Issue 9**: Clarify architecture documentation on steps vs tree nodes
|
|
1087
|
-
|
|
1088
|
-
### Implementation Quality Assessment
|
|
1089
|
-
|
|
1090
|
-
**Strengths**:
|
|
1091
|
-
- ✅ Core workflow engine fully functional
|
|
1092
|
-
- ✅ All decorators working correctly
|
|
1093
|
-
- ✅ Observer pattern properly implemented
|
|
1094
|
-
- ✅ Tree debugger provides real-time visibility
|
|
1095
|
-
- ✅ 100% test pass rate (133/133 tests)
|
|
1096
|
-
- ✅ Type safety maintained throughout
|
|
1097
|
-
- ✅ Error handling robust (in class-based workflows)
|
|
1098
|
-
|
|
1099
|
-
**Areas for Improvement**:
|
|
1100
|
-
- ⚠️ Functional workflow error handling needs state capture
|
|
1101
|
-
- ⚠️ Tree update event emission incomplete
|
|
1102
|
-
- ⚠️ Defensive programming (cycle detection, duplicate checks)
|
|
1103
|
-
- ⚠️ Some PRD-specified features partially implemented
|
|
1104
|
-
|
|
1105
|
-
### Final Verdict
|
|
1106
|
-
|
|
1107
|
-
**The implementation is production-ready** and meets all critical PRD requirements. The identified gaps are:
|
|
1108
|
-
|
|
1109
|
-
- **3 high-priority issues** that should be fixed for robustness
|
|
1110
|
-
- **2 medium-priority issues** for defensive programming
|
|
1111
|
-
- **4 low-priority issues** that are design choices or documentation
|
|
1112
|
-
- **1 obsolete issue** already resolved
|
|
1113
|
-
|
|
1114
|
-
**Recommendation**: Implement the 3 high-priority fixes (Issues 1, 2, 4) before considering the implementation fully PRD-compliant. The medium and low priority issues can be addressed incrementally.
|
|
1115
|
-
|
|
1116
|
-
---
|
|
1117
|
-
|
|
1118
|
-
## Appendix: File References
|
|
1119
|
-
|
|
1120
|
-
### PRD
|
|
1121
|
-
- **Location**: `/home/dustin/projects/groundswell/PRPs/PRDs/001-hierarchical-workflow-engine.md`
|
|
1122
|
-
- **Version**: 1.0
|
|
1123
|
-
- **Status**: Implementation-ready
|
|
1124
|
-
|
|
1125
|
-
### Implementation Files
|
|
1126
|
-
- **Core**: `/home/dustin/projects/groundswell/src/core/workflow.ts`
|
|
1127
|
-
- **Decorators**: `/home/dustin/projects/groundswell/src/decorators/step.ts`, `/home/dustin/projects/groundswell/src/decorators/task.ts`
|
|
1128
|
-
- **Types**: `/home/dustin/projects/groundswell/src/types/events.ts`, `/home/dustin/projects/groundswell/src/types/workflow.ts`
|
|
1129
|
-
- **Logger**: `/home/dustin/projects/groundswell/src/core/logger.ts`
|
|
1130
|
-
- **Debugger**: `/home/dustin/projects/groundswell/src/debugger/tree-debugger.ts`
|
|
1131
|
-
|
|
1132
|
-
### Test Results
|
|
1133
|
-
- **Location**: `/home/dustin/projects/groundswell/TEST_RESULTS.md`
|
|
1134
|
-
- **Test Status**: 133/133 passing (as of 2026-01-10)
|