A task that reports a roadblock but finishes successfully (Done/WaitingForReview/
Failed/Cancelled) had no way to answer it short of a full reset-and-rerun, losing
the run's context. Adds a reply textbox + Send button to the existing ROADBLOCK
card, modeled on the AskUser question card, that resumes the session via
ContinueTaskAsync with the user's own text. Gated on LatestRunSessionId (disabled
with a hint when there's nothing to resume); failures surface through the footer
error strip instead of a modal.
Per-list optional VerifyCommand (list_config.verify_command) runs via
VerifyCommandRunner in the list's working dir right after a successful
merge/continue-merge, before the task is allowed to reach Done. A
non-zero exit or timeout leaves the merge in place but keeps the task
out of Done and reports StatusVerifyFailed with an output excerpt
through MergeResultDto/review_task; no command configured behaves
exactly as before. Merges against the same repo are now serialized
per working dir so a running verify can't be interrupted by a second
merge landing mid-build. Adds the field to the List Settings modal
(en/de localized) and covers success/failure/timeout in
TaskMergeServiceTests + VerifyCommandRunnerTests.
"Let Claude handle it" now creates one ClaudeDo task per run to host the
ConPTY session (Idle/IsManual, never queued) instead of an untracked
ad-hoc tile, so the run has a real title, diff, and review outcome.
Since the handler merges its own changes straight into the list's
working dir, the task never gets a WorktreeEntity; its review range
lives as new HandlerBaseCommit/HandlerHeadCommit columns on TaskEntity
instead, reusing the existing commit-range diff machinery and keeping
it out of the worktrees overview entirely.
A full model id like claude-sonnet-4-6 in list_config.model never matched any
ModelPresets row (only bare aliases did), so every run under it landed on the
hardcoded 30-turn/DefaultLevel fallback instead of the sonnet preset row -
this is what killed two autonomous tasks at the 30-turn limit.
ModelRegistry.TryNormalizeAlias (non-throwing: exact match, then substring
match against a full model id) lets ModelPresets.For resolve a full model id
to its alias's preset row. For a model that still doesn't resolve, the
hardcoded 30 is replaced by a caller-supplied fallbackMaxTurns, and TaskRunner
now passes AppSettings.DefaultMaxTurns there - so that setting has a real
effect instead of being dead, matching the direction already noted in
docs/open.md.
Interactive planning sessions launched with --permission-mode plan, which
gates EVERY MCP tool call regardless of --allowedTools (verified: even a
read-only mcp__claudedo__list_task_lists is denied under plan mode). So the
session prompted the user on the first CreateChildTask -- the whole point of
a planning session.
Switch BuildPlanningStartArgs/BuildPlanningResumeArgs to --permission-mode
default, which honours the allowlist. File edits stay blocked via the planning
system prompt + AllowedTools omitting Write/Edit/Bash. Resume also re-passes
--allowedTools, since the CLI does not restore it across --resume.
The earlier 'glob does not match' hypothesis was empirically falsified:
mcp__claudedo__*, the bare server name, and the explicit tool name all allow
the tool with zero permission_denials in default mode.
HasChangesAsync counted untracked files, so a stray file in the shared
target working dir (e.g. left by a concurrent session) blocked merge
preflights even though nothing tracked changed. Add an includeUntracked
overload defaulting to true, and pass includeUntracked: false only from
the two target-working-tree merge preflights (TaskMergeService.MergeAsync,
PlanningMergeOrchestrator.StartAsync). Auto-commit and the worktree
cleanup data-loss guard keep counting untracked files, since those
callers need to know about them.
diff --git headers pack two paths on one space-delimited line, which broke
for unquoted paths containing spaces and for git's C-style octal-quoted
paths (non-ASCII filenames). Add quote-aware header splitting plus a git
unquote helper, and prefer the unambiguous "--- a/"/"+++ b/" lines to
correct the file's identity when present.
- GitService.MergeFfOnlyAsync had no callers anywhere in code; removed.
- AgentMcpTools moved out of LifecycleMcpTools.cs into External/AgentMcpTools.cs (no behavior change).
- Worker CLAUDE.md described ZitadelAuthProvider as a Phase 2 stub; it's fully implemented (OIDC discovery + refresh-token flow), updated both mentions.