From f8b5f2580e730a8affbccec8b5bde9b96b1f9fc2 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Thu, 5 Mar 2026 23:03:02 +0000 Subject: executor: persist log paths at execution create time, not just at end Add LogPather interface; ClaudeRunner implements it via ExecLogDir(). Pool pre-populates stdout_path/stderr_path/artifact_dir on the execution record before CreateExecution, so paths are in the DB from the moment a task starts running. ClaudeRunner.Run() skips path assignment when already set by the pool. Also update scripts/debug-execution to derive paths from the known convention (/executions//) as a fallback for historical records that predate this change. Co-Authored-By: Claude Sonnet 4.6 --- internal/executor/executor.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'internal/executor/executor.go') diff --git a/internal/executor/executor.go b/internal/executor/executor.go index 51f468e..eb23c02 100644 --- a/internal/executor/executor.go +++ b/internal/executor/executor.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log/slog" + "path/filepath" "sync" "time" @@ -12,6 +13,13 @@ import ( "github.com/google/uuid" ) +// LogPather is an optional interface runners can implement to provide the log +// directory for an execution before it starts. The pool uses this to persist +// log paths at CreateExecution time rather than waiting until execution ends. +type LogPather interface { + ExecLogDir(execID string) string +} + // Runner executes a single task and returns the result. type Runner interface { Run(ctx context.Context, t *task.Task, exec *storage.Execution) error @@ -115,6 +123,16 @@ func (p *Pool) execute(ctx context.Context, t *task.Task) { Status: "RUNNING", } + // Pre-populate log paths so they're available in the DB immediately — + // before the subprocess starts — enabling live tailing and debugging. + if lp, ok := p.runner.(LogPather); ok { + if logDir := lp.ExecLogDir(execID); logDir != "" { + exec.StdoutPath = filepath.Join(logDir, "stdout.log") + exec.StderrPath = filepath.Join(logDir, "stderr.log") + exec.ArtifactDir = logDir + } + } + // Record execution start. if err := p.store.CreateExecution(exec); err != nil { p.logger.Error("failed to create execution record", "error", err) -- cgit v1.2.3