buildPlaybookRunBootstrapPrompt is the prompt for playbook-run tasks. Adds an explicit `flow show playbook ` context-load step and frames the run's brief as an authoritative snapshot — the session must execute against that snapshot, not re-read the live playbook brief (which may drift between
(runSlug, playbookSlug string, isFirstRun bool)
| 775 | // quotes, backticks, or dollar signs — because it gets shell-quoted |
| 776 | // as a single positional argument to `claude`. |
| 777 | // |
| 778 | // The session's UUID is pre-allocated by `flow do` and passed via |
| 779 | // `claude --session-id <uuid>`, so there is no self-registration step |
| 780 | // here. The session loads context in order: task brief + task updates, |
| 781 | // then (if any) project brief + project updates, then CLAUDE.md files |
| 782 | // in the work_dir. The flow skill enforces this sequence too; the |
| 783 | // bootstrap prompt is a backup in case the skill isn't auto-activated. |
| 784 | // Kept for callers (and tests) that don't track first-run state. New |
| 785 | // callers should use buildBootstrapPromptForKindV2 to opt into the |
| 786 | // first-run variant when relevant. |
| 787 | func buildBootstrapPromptForKind(slug, kind, playbookSlug string) string { |
| 788 | return buildBootstrapPromptForKindV2(slug, kind, playbookSlug, false) |
| 789 | } |
| 790 | |
| 791 | // buildBootstrapPromptForKindV2 is the kind-aware dispatcher with first- |
| 792 | // run awareness for playbook runs. When isFirstRun=true on a playbook |
| 793 | // run, a richer "capture-aggressive" prompt is emitted that nudges the |
| 794 | // session to harvest scripts, edge cases, and decision rules back into |
| 795 | // the live playbook brief / sidecar files. |
| 796 | func buildBootstrapPromptForKindV2(slug, kind, playbookSlug string, isFirstRun bool) string { |
| 797 | if kind == "playbook_run" { |
| 798 | return buildPlaybookRunBootstrapPrompt(slug, playbookSlug, isFirstRun) |
| 799 | } |
| 800 | return buildTaskBootstrapPrompt(slug) |
| 801 | } |
| 802 | |
| 803 | // buildTaskBootstrapPrompt is the prompt for regular tasks. |
| 804 | func buildTaskBootstrapPrompt(slug string) string { |
| 805 | return fmt.Sprintf( |
| 806 | "You are the execution session for flow task %s. Do ALL of the following in order before touching code:\n"+ |
| 807 | "1. Invoke the flow skill via the Skill tool. This loads the operating manual that governs how this session works: workflows, bootstrap contract, KB discipline, and scope-creep detection.\n"+ |
| 808 | "2. Run: flow show task. Read the file at the brief: path AND every file listed under updates:. Files listed under other: are sidecar references — load on demand when relevant, not eagerly.\n"+ |
| 809 | "3. If a project is listed on the task, run: flow show project <that-project-slug>. Read its brief AND every file under updates:. Files under other: are on-demand references.\n"+ |
| 810 | "4. Read CLAUDE.md in your work_dir and any nested CLAUDE.md files under subdirectories you will modify. These override any assumption from the brief.\n"+ |
| 811 | "5. Only then begin work. If any brief section is blank or unclear, ASK — do not infer.", |
| 812 | slug, |
| 813 | ) |
| 814 | } |
| 815 | |
| 816 | // buildPlaybookRunBootstrapPrompt is the prompt for playbook-run tasks. |
| 817 | // Adds an explicit `flow show playbook <slug>` context-load step and |
no outgoing calls