A failed auto-commit still advances the workflow from the old HEAD
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
|
||||
- Merge finalization keeps no durable progress; cleanup runs before the task is closed
|
||||
`internal/agents/mergein.go:303–324` runs push → notes → fast-forward → `RemoveTask` → `MergeTask`. A crash or error after the push leaves an active task with no worktree; a retried Merge fails in `Snapshot`, or squashes to no change and closes with an empty `merge_commit`. Have the `finalizing` marker record the squash commit; on startup, a recorded commit that is an ancestor of origin/<default> finishes notes, fast-forward, removal and MergeTask idempotently, otherwise the marker is cleared and an error is filed.
|
||||
- A failed auto-commit still advances the workflow from the old HEAD
|
||||
A `CommitAll` error is only logged (`internal/agents/manager.go:838–841`) and `FinishStage` still runs (`:885–889`), so `RecordStage` stores the old `git.Head` (`internal/agents/workflows.go:349–356`), the next stage branches without the turn's work, and `discardStages` later deletes the worktree that held it. On commit failure, treat the turn as unfinished: skip FinishStage, the handoff and the summary, and file the error in the task's inbox.
|
||||
- Codex mid-turn delivery deletes input before the steer is accepted
|
||||
Queued inputs are deleted or marked delivered and recorded as `user.message` (`internal/agents/queue.go:119`, `:158`; `internal/agents/inbox.go:404`) before `Steer`, whose error is only logged (`internal/agents/codex.go:167–174`). Return the consumed ids from `deliverMidTurn`; when Steer fails, re-insert the inputs in order and clear `delivered_at` so the turn-end Deliver sends them.
|
||||
- Inbox answer validation isn't atomic with resolving the question
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ Compaction is vendor-agnostic: `POST /api/sessions/{id}/compact` (the transcript
|
||||
|
||||
Task agents spawn parallel work as subtasks (see "Subtasks").
|
||||
|
||||
Agents don't commit; byre does. Each `user.message` event that starts a turn records `head`, the worktree's `HEAD` when the turn started. When a turn ends, byre runs `git add --all` and commits if anything changed (`git.CommitAll`), as the session's creator, with the first sentence of the turn's final message as the message (`commitMessage` in `internal/agents/manager.go`); `turn.ended` then carries the new sha as `commit`. A failed commit is logged and the turn still ends.
|
||||
Agents don't commit; byre does. Each `user.message` event that starts a turn records `head`, the worktree's `HEAD` when the turn started. When a turn ends, byre runs `git add --all` and commits if anything changed (`git.CommitAll`), as the session's creator, with the first sentence of the turn's final message as the message (`commitMessage` in `internal/agents/manager.go`); `turn.ended` then carries the new sha as `commit`. A failed commit files a `session_error` in the task's inbox and the turn ends unfinished: no summary, no handoff, no merge finalize, and a workflow stage neither finishes nor records its output, so the next stage never branches from a `HEAD` that lacks the turn's work.
|
||||
|
||||
A session runs on one of two vendors, picked by the model it is created with (`workflow.VendorOf` in `internal/workflow/workflow.go`): `gpt-*` models run on Codex (`codex app-server`), every other model on Claude Code. The UI's model list is `models` in `web/src/task.ts`; a live session's picker offers only its own vendor's models, and the API refuses (400) a switch to the other vendor's model. Both vendors sit behind `agentProcess` (`internal/agents/process.go`), and both end a turn through the same `turnEnded`, so commits, turn summaries, snapshots, handoffs, merges and deliveries don't depend on the vendor.
|
||||
|
||||
|
||||
@@ -871,13 +871,15 @@ func (m *Manager) turnEnded(ctx context.Context, l *live, res endResult) error {
|
||||
m.mu.Unlock()
|
||||
|
||||
finished := !res.isError && !interrupted && strings.TrimSpace(res.result) != ""
|
||||
handoff := compacting && finished
|
||||
|
||||
payload := res.payload
|
||||
sha, err := git.CommitAll(l.dir, commitMessage(res), l.gitName, l.gitEmail)
|
||||
if err != nil {
|
||||
slog.Error("commit turn", "session", l.id, "err", err)
|
||||
m.fileError(l, fmt.Sprintf("byre couldn't commit the turn's work, so the turn counts as unfinished: %v", err))
|
||||
finished = false
|
||||
}
|
||||
handoff := compacting && finished
|
||||
if sha != "" {
|
||||
payload["commit"] = sha
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user