feat: Core DI migration — service conclave + IPC pipeline #17

Merged
Virgil merged 16 commits from feat/core-di-migration into dev 2026-03-24 22:11:07 +00:00
Member

Summary

Migrates core-agent from manual service wiring to full Core framework DI.

Phase 1: IPC Message Types

  • 12 typed messages: AgentStarted/Completed, QAResult, PRCreated/Merged/NeedsReview, QueueDrained, PokeQueue, HarvestComplete/Rejected, InboxMessage

Phase 2: Core Wiring

  • *core.Core injected into PrepSubsystem and monitor.Subsystem
  • Services registered with lifecycle hooks

Phase 3: IPC Migration

  • CompletionNotifier interface removed
  • c.ACTION(messages.AgentCompleted{}) replaces callbacks
  • Monitor registers IPC handlers in SetCore()

Phase 4: Completion Pipeline

  • Discrete IPC handlers: QA → PRCreated → Verify → PRMerged/PRNeedsReview
  • Legacy inline fallback removed from dispatch goroutine
  • findWorkspaceByPR() for PR event routing

Phase 5: Config + Locks

  • agents.yaml loaded once into c.Config() at startup
  • canDispatchAgent reads from shared config
  • c.Lock("drain") replaces local mutex

Service Conclave

  • Register() factories for agentic/monitor/brain
  • core.New(WithService(agentic.Register), WithService(monitor.Register), ...)
  • initServices() closure eliminated
  • Commands use c.ServiceStartup()/c.ServiceShutdown()

Depends on: core/go PR #28 (feat/service-options)

Test plan

  • go build ./... passes
  • go test ./pkg/agentic/... passes
  • go test ./pkg/monitor/... passes
  • go test ./pkg/messages/... passes
  • core-agent version works
  • core-agent check works

🤖 Generated with Claude Code
Co-Authored-By: Virgil virgil@lethean.io

## Summary Migrates core-agent from manual service wiring to full Core framework DI. ### Phase 1: IPC Message Types - 12 typed messages: AgentStarted/Completed, QAResult, PRCreated/Merged/NeedsReview, QueueDrained, PokeQueue, HarvestComplete/Rejected, InboxMessage ### Phase 2: Core Wiring - `*core.Core` injected into PrepSubsystem and monitor.Subsystem - Services registered with lifecycle hooks ### Phase 3: IPC Migration - `CompletionNotifier` interface removed - `c.ACTION(messages.AgentCompleted{})` replaces callbacks - Monitor registers IPC handlers in `SetCore()` ### Phase 4: Completion Pipeline - Discrete IPC handlers: QA → PRCreated → Verify → PRMerged/PRNeedsReview - Legacy inline fallback removed from dispatch goroutine - `findWorkspaceByPR()` for PR event routing ### Phase 5: Config + Locks - agents.yaml loaded once into `c.Config()` at startup - `canDispatchAgent` reads from shared config - `c.Lock("drain")` replaces local mutex ### Service Conclave - `Register()` factories for agentic/monitor/brain - `core.New(WithService(agentic.Register), WithService(monitor.Register), ...)` - `initServices()` closure eliminated - Commands use `c.ServiceStartup()`/`c.ServiceShutdown()` **Depends on:** core/go PR #28 (feat/service-options) ## Test plan - [x] `go build ./...` passes - [x] `go test ./pkg/agentic/...` passes - [x] `go test ./pkg/monitor/...` passes - [x] `go test ./pkg/messages/...` passes - [x] `core-agent version` works - [x] `core-agent check` works 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 6 commits 2026-03-24 16:46:27 +00:00
12 message types covering: agent lifecycle (Started/Completed),
QA+PR pipeline (QAResult/PRCreated/PRMerged/PRNeedsReview),
queue orchestration (QueueDrained/PokeQueue/RateLimitDetected),
monitor events (HarvestComplete/HarvestRejected/InboxMessage).

These replace the CompletionNotifier and ChannelNotifier callback
interfaces with typed broadcast messages via c.ACTION().

Co-Authored-By: Virgil <virgil@lethean.io>
Phase 2 of Core DI migration:
- Add *core.Core field + SetCore() to PrepSubsystem and monitor.Subsystem
- Register agentic/monitor/brain as Core services with lifecycle hooks
- Mark SetCompletionNotifier and SetNotifier as deprecated (removed in Phase 3)
- Fix monitor test to match actual event names
- initServices() now wires Core refs before legacy callbacks

Co-Authored-By: Virgil <virgil@lethean.io>
Phase 3 of Core DI migration:
- Remove CompletionNotifier interface from pkg/agentic
- dispatch.go emits messages.AgentStarted/AgentCompleted via c.ACTION()
- monitor registers IPC handlers in SetCore() — handleAgentStarted/handleAgentCompleted
- Remove circular callback wiring (SetCompletionNotifier) from main.go
- Export ReadStatus for cross-package use
- Update run/orchestrator to use SetCore() instead of SetCompletionNotifier()

Services now communicate through typed messages, not direct references.

Co-Authored-By: Virgil <virgil@lethean.io>
Each package exposes Register(c *Core) Result for core.WithService():
- agentic.Register: creates PrepSubsystem, wires IPC handlers, lifecycle
- monitor.Register: creates Subsystem, wires IPC handler, lifecycle
- brain.Register: creates Direct, registers service

main.go updated for core.New() returning Result.
Ready for core.New(WithService(agentic.Register)) pattern.

Co-Authored-By: Virgil <virgil@lethean.io>
Services are now registered during Core construction:
  core.New(
      core.WithService(agentic.Register),
      core.WithService(monitor.Register),
      core.WithService(brain.Register),
  )

- Remove initServices() closure — services created once in conclave
- Commands use c.ServiceStartup()/c.ServiceShutdown() for lifecycle
- Service instances retrieved via c.Config() for MCP tool registration
- run/orchestrator reduced to ServiceStartup + block + ServiceShutdown
- run/task uses conclave's agentic instance

Co-Authored-By: Virgil <virgil@lethean.io>
Phase 4 complete:
- Auto-PR handler emits PRCreated message
- Verify handler listens for PRCreated, emits PRMerged/PRNeedsReview
- findWorkspaceByPR() for workspace lookup from PR events
- Remove legacy inline fallback from dispatch goroutine

Phase 5 complete:
- agents.yaml loaded once at startup into c.Config()
- canDispatchAgent reads from c.Config() (no re-parsing)
- drainQueue uses c.Lock("drain") when Core available

Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 17:42:19 +00:00
- agentic.PrepSubsystem implements Startable/Stoppable
- monitor.Subsystem implements Startable/Stoppable (OnStartup/OnShutdown)
- Register factories use c.RegisterService() — auto-discovers interfaces
- Register factories return instances via Result.Value
- main.go uses ServiceFor[T]() instead of ConfigGet — typed retrieval
- No more c.Config().Set("x.instance") workaround

Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 20:36:21 +00:00
Register factories no longer call c.RegisterService() explicitly.
WithService auto-discovers name from package path and registers.
Eliminates double-registration error.

Uses WithOption("name", "core-agent") for Options struct.

Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 20:51:54 +00:00
- process: registered as WithService in core.New()
- MCP: registered as WithName("mcp") in core.New(), retrieves
  agentic/monitor/brain via ServiceFor during construction
- Commands use ServiceFor to access services — no captured vars
- initMCP closure eliminated
- No service creation after core.New() completes

Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 21:16:22 +00:00
- core.New() includes mcp.Register — auto-discovers subsystems
- mcp/serve commands use c.Service("mcp") for typed retrieval
- ServiceStartup called once before Cli().Run()
- run/task and run/orchestrator registered by agentic.OnStartup
- Removed ServiceFor generics — c.Service() returns instances directly

Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 21:24:33 +00:00
Commands moved to their owning services:
- agentic: run/task, run/orchestrator, prep, status, prompt, extract
- mcp: mcp, serve (in core/mcp OnStartup)
- main.go: version, check, env (app-level only)

ServiceStartup before Cli().Run() — services register commands in OnStartup.
ServiceShutdown on exit.

Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 21:33:03 +00:00
Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 21:36:21 +00:00
Virgil added 1 commit 2026-03-24 21:40:06 +00:00
Co-Authored-By: Virgil <virgil@lethean.io>
Virgil added 1 commit 2026-03-24 21:50:23 +00:00
Virgil added 1 commit 2026-03-24 21:53:48 +00:00
Co-Authored-By: Virgil <virgil@lethean.io>
Virgil merged commit 42642d8702 into dev 2026-03-24 22:11:07 +00:00
Sign in to join this conversation.
No description provided.