Skip to content

Break handler↔module concrete-type dependency via shared interfaces package#78

Merged
intel352 merged 5 commits intomainfrom
copilot/fix-bidirectional-dependency
Feb 23, 2026
Merged

Break handler↔module concrete-type dependency via shared interfaces package#78
intel352 merged 5 commits intomainfrom
copilot/fix-bidirectional-dependency

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

  • Explore codebase: handlers/pipeline.go, module/pipeline_executor.go, module/pipeline_step_registry.go, engine.go
  • Create interfaces/pipeline.go — define EventRecorder, PipelineRunner, StepRegistryProvider interfaces
  • Update module/pipeline_executor.go — alias EventRecorder to interfaces.EventRecorder; add SetLogger/SetEventRecorder/Run methods to Pipeline
  • Update handlers/pipeline.go — replace *module.Pipeline/*module.StepRegistry/module.EventRecorder with interfaces.*; inject logger/recorder at configuration time (not per-execution) to avoid hot-path mutations
  • Update engine.go — update PipelineAdder interface to use interfaces.PipelineRunner
  • Add mockPipelineRunner, mockEventRecorder, TestPipelineHandler_MockRunner, TestPipelineHandler_InjectionAtConfigTime tests
  • Fix test comment to "without depending on concrete module types"
  • Build, lint, and run affected tests — all pass
Original prompt

This section details on the original issue you should resolve

<issue_title>Bidirectional handler↔module dependency in handlers/pipeline.go</issue_title>
<issue_description>## Problem
The handlers package directly imports and holds concrete types from the module package (*module.Pipeline, *module.StepRegistry). This creates a bidirectional dependency and means handlers cannot be tested without instantiating real module types.

Fix Direction

Define PipelineRunner and StepRegistry interfaces in a shared package (e.g. workflow/interfaces or as part of the plugin contract). Have handlers depend on these interfaces; module implements them. This breaks the import cycle and enables proper unit testing of handlers with mocks.

Context

See docs/DEFERRED_ISSUES.md — Architecture section.</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…ckage

- Create interfaces/pipeline.go with EventRecorder, PipelineRunner, StepRegistryProvider
- Add SetLogger, SetEventRecorder, Run methods to module.Pipeline
- Alias module.EventRecorder to interfaces.EventRecorder
- Update handlers/pipeline.go to use interfaces (removes module import)
- Update engine.go PipelineAdder to use interfaces.PipelineRunner
- Add mockPipelineRunner test to demonstrate mock-based handler testing

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix bidirectional handler and module dependency in pipeline Break handler↔module concrete-type dependency via shared interfaces package Feb 23, 2026
Copilot AI requested a review from intel352 February 23, 2026 02:11
@intel352 intel352 marked this pull request as ready for review February 23, 2026 02:35
Copilot AI review requested due to automatic review settings February 23, 2026 02:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR decouples handlers from module concrete types by introducing a neutral interfaces package for shared contracts, enabling handler unit testing with mocks and reducing cross-package coupling.

Changes:

  • Added interfaces package defining PipelineRunner, EventRecorder, and StepRegistryProvider.
  • Updated module.Pipeline to implement interfaces.PipelineRunner (type alias for EventRecorder, plus SetLogger, SetEventRecorder, Run).
  • Updated handlers/pipeline.go and engine.go to use interfaces.PipelineRunner, plus a new mock-based handler test.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
module/pipeline_executor.go Aliases EventRecorder to shared interface and adds PipelineRunner methods (SetLogger, SetEventRecorder, Run).
interfaces/pipeline.go Introduces shared interfaces to break handler↔module concrete-type dependency.
handlers/pipeline.go Removes module dependency by storing/running pipelines via interfaces.PipelineRunner.
engine.go Updates PipelineAdder signature to accept interfaces.PipelineRunner.
handlers/pipeline_test.go Adds a mock PipelineRunner and verifies handler execution works with mocks.

@intel352
Copy link
Contributor

@copilot apply changes based on the comments in this thread

- SetLogger/SetEventRecorder now propagate to all already-registered pipelines
- AddPipeline now injects logger/recorder immediately if already set on the handler
- ExecuteWorkflow only calls Run() — no mutation on the hot path
- Add mockEventRecorder and TestPipelineHandler_InjectionAtConfigTime test
- Fix test comment: "without depending on concrete module types"

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
@intel352 intel352 merged commit 25defdf into main Feb 23, 2026
13 of 14 checks passed
@intel352 intel352 deleted the copilot/fix-bidirectional-dependency branch February 23, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bidirectional handler↔module dependency in handlers/pipeline.go

3 participants