refactor(prompts): split the list-handler prompt per session phase

Both merge-helper ConPTY sessions loaded PromptKind.MergeHelper, so the
post-handoff session received the phase 0-2 dedupe/enhance instructions and was
told to ignore them by its brief alone.

Split into MergeHelperTriage (phases 0-2 + handoff) and MergeHelperExecute
(phases 3-5), so each session carries only its own phases. Consolidated the
generic ask-the-user rule to one place per prompt, scoped Phase 5's summary to
what the execute session actually knows, and moved the dedupe/enhance bilanz to
the triage handoff. Regression guards assert neither prompt carries the other's
phase headings and that the shared-checkout git rule stays in execute.
This commit is contained in:
mika kuns
2026-08-06 21:00:41 +02:00
parent d5730a8405
commit a7ff1b3a2f
5 changed files with 129 additions and 35 deletions
+28 -12
View File
@@ -4,7 +4,7 @@ using System.Text.Json;
namespace ClaudeDo.Data;
public enum PromptKind { System, Planning, PlanningInitial, Retry, DailyPrep, WeeklyReport, ImprovementChild, Refine, MergeHelper, MergeHelperInitial, MergeHelperHandoff }
public enum PromptKind { System, Planning, PlanningInitial, Retry, DailyPrep, WeeklyReport, ImprovementChild, Refine, MergeHelperTriage, MergeHelperExecute, MergeHelperInitial, MergeHelperHandoff }
/// <summary>
/// How a prompt kind's on-disk override (if any) relates to the bundled default.
@@ -38,7 +38,8 @@ public static class PromptFiles
PromptKind.WeeklyReport => "weekly-report.md",
PromptKind.ImprovementChild => "improvement-child.md",
PromptKind.Refine => "refine.md",
PromptKind.MergeHelper => "merge-helper-system.md",
PromptKind.MergeHelperTriage => "merge-helper-triage.md",
PromptKind.MergeHelperExecute => "merge-helper-execute.md",
PromptKind.MergeHelperInitial => "merge-helper-initial.md",
PromptKind.MergeHelperHandoff => "merge-helper-handoff.md",
_ => throw new ArgumentOutOfRangeException(nameof(kind))
@@ -211,7 +212,8 @@ public static class PromptFiles
PromptKind.WeeklyReport => WeeklyReportDefault,
PromptKind.ImprovementChild => ImprovementChildDefault,
PromptKind.Refine => RefineDefault,
PromptKind.MergeHelper => MergeHelperDefault,
PromptKind.MergeHelperTriage => MergeHelperTriageDefault,
PromptKind.MergeHelperExecute => MergeHelperExecuteDefault,
PromptKind.MergeHelperInitial => MergeHelperInitialDefault,
PromptKind.MergeHelperHandoff => MergeHelperHandoffDefault,
_ => ""
@@ -404,12 +406,14 @@ public static class PromptFiles
task, stop.
""";
private const string MergeHelperDefault = """
You are the ClaudeDo list handler, running as an interactive session with the user watching. Work autonomously and decide things yourself by default. Ask the user only for decisions that are genuinely theirs to make: merging a duplicate task, a task whose intent is too unclear to act on safely, a diff that looks wrong or risky, or a conflict resolution you cannot resolve with confidence. Everything else, decide and keep moving.
private const string MergeHelperTriageDefault = """
You are the ClaudeDo list handler, running as an interactive session with the user watching. Work autonomously and decide things yourself by default. Ask the user only for decisions that are genuinely theirs to make: merging a duplicate task, or a task whose intent is too unclear to act on safely. Everything else, decide and keep moving.
Your job: take the tasks listed in the brief and drive the whole set to merged, Done work reading them first, removing duplicates, sharpening what stays, running it, then reviewing and merging each result. You act through the mcp__claudedo__* tools. Read the brief file first (the kickoff message gives its path); it names the list, its repo, and every task's id, title and status. All tasks belong to that one list and one repo.
Your job: take the tasks listed in the brief and get the set ready to run reading them all first, removing duplicates, then sharpening what stays. You act through the mcp__claudedo__* tools. Read the brief file first (the kickoff message gives its path); it names the list, its repo, and every task's id, title and status. All tasks belong to that one list and one repo.
Work the five phases in order. Do not start a phase before the previous one is finished.
A second session takes over after you to run, review and merge these tasks. Your deliverable is a clean, sharpened set of task descriptions you never run or merge anything yourself, and you touch no git state.
Work the three phases in order. Do not start a phase before the previous one is finished.
## Phase 0 Read everything
The brief is the primary source: it already lists every task's title, id, status and full description. Read it in full before acting. Only call batch_get_tasks if you need something the brief does not carry for a specific task, e.g. parent/child links. Do not act on any single task before you have read them all Phase 1 needs the whole set in view.
@@ -438,7 +442,20 @@ public static class PromptFiles
If a task visibly bundles several independent features, or has a blocker that is not resolved by anything in its own description, do not force it into one description. Propose splitting it to the user; if they agree, create the pieces with add_task/add_subtask and only move the pieces the user confirmed into "surviving tasks" for the phases below. Split only what the task already asks for the "do not invent requirements" rule still applies.
## Handoff
Once every surviving task is enhanced, call handoff_list_handler with this session's task id and the surviving task ids, in the order you intend to run them. That opens a fresh session to carry out phases 35 with just that list, without dragging along this session's dedupe/rewrite context. Say a short goodbye line, then stop do not continue into phase 3 yourself.
Once every surviving task is enhanced, print your triage summary one line per task from the brief:
title dedupe action (kept / merged into X / cancelled as duplicate of X) enhanced (yes/no).
Then call handoff_list_handler with this session's task id and the surviving task ids, in the order you intend them to run. That opens a fresh session to carry out the run/review/merge phases with just that list, without dragging along this session's dedupe/rewrite context. Say a short goodbye line, then stop do not continue into phase 3 yourself.
""";
private const string MergeHelperExecuteDefault = """
You are the ClaudeDo list handler, running as an interactive session with the user watching. Work autonomously and decide things yourself by default. Ask the user only for decisions that are genuinely theirs to make: a diff that looks wrong or risky, or a conflict resolution you cannot resolve with confidence. Everything else, decide and keep moving.
Your job: take the tasks listed in the brief and drive them to merged, Done work running them, then reviewing and merging each result. You act through the mcp__claudedo__* tools. Read the brief file first (the kickoff message gives its path); it names the list, its repo, and every task's id, title and status. All tasks belong to that one list and one repo.
A prior session already read, deduplicated and sharpened these tasks; their descriptions are ready to run as written. Start at Phase 3.
Work the three phases in order. Do not start a phase before the previous one is finished.
## Phase 3 Run
Do NOT use run_task_now for a batch there is a single override slot and the second call fails with "override slot busy".
@@ -478,11 +495,10 @@ public static class PromptFiles
Rules for the whole session:
- Never use raw `git merge`, `git reset`, or `git checkout` to force a merge. Drive merges through the MCP tools; hand-resolution is only for markers the tools left and cannot finish.
- Ask the user for anything ambiguous, risky, or destructive.
## Phase 5 Summary
Print one line per task from the original brief:
title dedupe action (kept / merged into X / cancelled as duplicate of X) enhanced (yes/no) final status merge commit (if any) conflicts resolved (if any).
Print one line per task from the brief:
title final status merge commit (if any) conflicts resolved (if any).
Then list anything you skipped or left for the user and why, and any follow-ups worth turning into new tasks.
""";
@@ -507,7 +523,7 @@ public static class PromptFiles
Repo: {repo}
A prior session already read, deduped and enhanced this list's tasks. Pick up at phase 3
for the tasks below their descriptions are already sharpened, so don't redo phases 02.
for the tasks below their descriptions are already sharpened.
{tasks}