commit 7c9a3425706574f27753c548295234632ac77165
Author: Coder Agent <coder@agents.omni>
Date: Wed Feb 18 12:44:39 2026
Auto-detect agent author via OMNI_AUTHOR env var
In Omni/Pipeline/Dev.hs spawnDev, set OMNI_AUTHOR=agent:engineer in
the spawned process environment so agents running inside the pipeline
automatically get correct attribution.
In Omni/Task.hs parseAuthor, check OMNI_AUTHOR env var as fallback
when no --author flag is given. Explicit --author still takes
precedence; if neither is set, defaults to Human.
Task-Id: t-635
diff --git a/Omni/Pipeline/Dev.hs b/Omni/Pipeline/Dev.hs
index aa32615e..5e9371b7 100644
--- a/Omni/Pipeline/Dev.hs
+++ b/Omni/Pipeline/Dev.hs
@@ -16,6 +16,7 @@ import qualified Omni.Pipeline.Core as Core
import qualified Omni.Pipeline.Git as Git
import qualified Omni.Task.Core as Task
import qualified System.Directory as Dir
+import qualified System.Environment as Env
import qualified System.Exit as Exit
import qualified System.IO as IO
import qualified System.Process as Process
@@ -114,10 +115,15 @@ spawnDev cfg workspace task patchset maybeReviewFeedback dbRowId = do
logHandle <- IO.openFile logFile IO.WriteMode
IO.hSetBuffering logHandle IO.LineBuffering
+ -- Inherit current environment and add OMNI_AUTHOR for agent attribution
+ parentEnv <- Env.getEnvironment
+ let agentEnv = Just (("OMNI_AUTHOR", "agent:engineer") : parentEnv)
+
-- Spawn pi directly with stdout/stderr to log file
let cp =
(Process.proc "pi" piArgs)
{ Process.cwd = Just workspace,
+ Process.env = agentEnv,
Process.std_in = Process.NoStream,
Process.std_out = Process.UseHandle logHandle,
Process.std_err = Process.UseHandle logHandle,
diff --git a/Omni/Task.hs b/Omni/Task.hs
index c5b525b0..97225215 100644
--- a/Omni/Task.hs
+++ b/Omni/Task.hs
@@ -21,7 +21,7 @@ import qualified Omni.Task.MigrationTest as MigrationTest
import qualified Omni.Task.RaceTest as RaceTest
import qualified Omni.Test as Test
import System.Directory (createDirectoryIfMissing, doesFileExist, removeFile)
-import System.Environment (setEnv)
+import System.Environment (lookupEnv, setEnv)
import qualified Test.Tasty as Tasty
import Web.HttpApiData (parseQueryParam)
import Prelude (read)
@@ -344,15 +344,14 @@ doComment :: GlobalOpts -> String -> String -> Maybe String -> IO ()
doComment GlobalOpts {..} tidStr message authorStr = do
for_ globalDb (setEnv "TASK_DB_PATH")
let tid = T.pack tidStr
- author = parseAuthor authorStr
+ author <- parseAuthor authorStr
updatedTask <- addComment tid (T.pack message) author
if globalJson
then outputJson updatedTask
else putStrLn <| "Added comment to task: " <> T.unpack tid
-parseAuthor :: Maybe String -> CommentAuthor
-parseAuthor Nothing = Human
-parseAuthor (Just s) = case map Char.toLower s of
+parseAuthor :: Maybe String -> IO CommentAuthor
+parseAuthor (Just s) = pure <| case map Char.toLower s of
"human" -> Human
"system" -> System
"agent:engineer" -> Agent Engineer
@@ -361,6 +360,19 @@ parseAuthor (Just s) = case map Char.toLower s of
"agent:productmgr" -> Agent ProductMgr
"agent" -> Agent Engineer
_ -> Human
+parseAuthor Nothing = do
+ envAuthor <- lookupEnv "OMNI_AUTHOR"
+ case envAuthor of
+ Nothing -> pure Human
+ Just s -> pure <| case map Char.toLower s of
+ "human" -> Human
+ "system" -> System
+ "agent:engineer" -> Agent Engineer
+ "agent:reviewer" -> Agent Reviewer
+ "agent:designer" -> Agent Designer
+ "agent:productmgr" -> Agent ProductMgr
+ "agent" -> Agent Engineer
+ _ -> Human
-- | list command
listParser :: Cli.Parser (IO ())