After simplifying to just Coder (t-314), generalize the Coder harness pattern into a reusable abstraction. The Coder is valuable because of its programmatic lifecycle (init → work → verify → commit/rollback), not because it's specifically for coding.
The Coder harness follows this lifecycle:
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Init │ ──► │ Work │ ──► │ Verify │ ──► │ Commit │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
│ │ │ │
▼ ▼ ▼ ▼
Check env Agent loop Programmatic Finalize
Detect state with tools validation or rollback
This pattern could apply to other domains:
-- Omni/Agent/Harness.hs
data HarnessConfig a = HarnessConfig
{ harnessName :: Text
, harnessInit :: IO (Either Text a) -- Setup, returns context
, harnessVerify :: a -> IO VerifyResult -- Programmatic validation
, harnessCommit :: a -> Text -> IO (Either Text ()) -- Finalize
, harnessRollback :: a -> IO () -- Cleanup on failure
, harnessTools :: [Engine.Tool] -- Tools available during work phase
, harnessSystemPrompt :: a -> Text -- Prompt with context
, harnessMaxVerifyRetries :: Int
}
data VerifyResult
= VerifySuccess
| VerifyFailed Text -- Error message for agent to fix
runHarness :: Text -> HarnessConfig a -> Text -> IO (Either Text HarnessResult)
coderHarness :: CoderConfig -> HarnessConfig CoderContext
coderHarness cfg = HarnessConfig
{ harnessName = "coder"
, harnessInit = runCoderInit cfg
, harnessVerify = \_ -> runCoderVerify cfg -- lint, build, test
, harnessCommit = \_ summary -> runCoderCommit cfg summary
, harnessRollback = \_ -> runCoderRecovery (coderWorkDir cfg)
, harnessTools = coderTools
, harnessSystemPrompt = coderSystemPrompt cfg
, harnessMaxVerifyRetries = coderMaxVerifyRetries cfg
}
1. Reusability: New harnesses can be created by implementing the interface 2. Consistency: All harnesses follow the same lifecycle 3. Testability: Each phase can be tested independently 4. Extensibility: Add new harnesses without changing core infrastructure
1. Create Omni/Agent/Harness.hs with the abstraction 2. Refactor Coder to use the harness 3. Verify Coder still works 4. Document how to create new harnesses