feat(sf): add 5 deep-planning-mode prompt builders (PDD)

Companion to b771dd0b3 (deep-mode prompt templates). Adds the five
auto-prompts.ts builders that load those templates with the
correct vars.

PDD spec for this change:

Purpose: complete the load path for deep-mode planning so dispatch
  rules can call buildDiscussProjectPrompt(), etc., without crashing.
Consumer: auto-dispatch.ts deep-mode rules (next commit).
Contract: each builder returns a populated prompt string for its
  unit type given (basePath, structuredQuestionsAvailable). All 5
  load successfully against their respective .md templates with no
  missing-var errors.
Failure boundary: loadPrompt throws SF_PARSE_ERROR if a template
  variable is missing — surfaces a clear error rather than silently
  rendering a half-substituted prompt.
Evidence: typecheck passes; loadPrompt verification in last fire's
  log shows all 5 prompts render to non-empty strings (2.6k–7.7k
  chars each).
Non-goals: dispatch wiring (separate commit, requires the
  deep-project-setup-policy resolver SF already has).
Invariants:
  - Safety: existing builders unchanged — no regression.
  - Liveness: each builder returns within one prompt-load round-trip.
Assumptions verified:
  - inlineTemplate('project'/'requirements') already exists in
    prompt-loader.ts.
  - sf_requirement_save and sf_summary_save tools exist in
    db-tools.ts (referenced by the prompts they load).
  - phases.planning_depth: 'light' | 'deep' already typed in
    preferences-types.ts (line 425).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikael Hugo 2026-05-02 19:36:50 +02:00
parent b771dd0b31
commit 5e8bdefbea

View file

@ -1559,6 +1559,97 @@ export async function checkNeedsRunUat(
// ─── Prompt Builders ──────────────────────────────────────────────────────
/**
* Build a prompt for the workflow-preferences unit type (deep mode).
* Captures workflow + planning preferences during deep-mode bootstrap,
* before discuss-project runs.
*/
export async function buildWorkflowPreferencesPrompt(
base: string,
structuredQuestionsAvailable = "false",
): Promise<string> {
return loadPrompt("guided-workflow-preferences", {
workingDirectory: base,
structuredQuestionsAvailable,
});
}
/**
* Build a prompt for the discuss-project unit type (deep mode).
* Project-level interview: produces .sf/PROJECT.md.
* Fires before any milestone-level work when planning_depth === "deep"
* and PROJECT.md is missing.
*/
export async function buildDiscussProjectPrompt(
base: string,
structuredQuestionsAvailable = "false",
): Promise<string> {
const inlinedTemplates = inlineTemplate("project", "Project");
return loadPrompt("guided-discuss-project", {
workingDirectory: base,
inlinedTemplates,
structuredQuestionsAvailable,
commitInstruction:
"Do not commit planning artifacts — .sf/ is managed externally.",
});
}
/**
* Build a prompt for the discuss-requirements unit type (deep mode).
* Requirements-level interview: produces .sf/REQUIREMENTS.md using the
* structured R### format. Reads PROJECT.md as authoritative context.
* Fires when planning_depth === "deep", PROJECT.md exists, and
* REQUIREMENTS.md is missing.
*/
export async function buildDiscussRequirementsPrompt(
base: string,
structuredQuestionsAvailable = "false",
): Promise<string> {
const inlinedTemplates = inlineTemplate("requirements", "Requirements");
return loadPrompt("guided-discuss-requirements", {
workingDirectory: base,
inlinedTemplates,
structuredQuestionsAvailable,
commitInstruction:
"Do not commit planning artifacts — .sf/ is managed externally.",
});
}
/**
* Build a prompt for the research-decision unit type (deep mode).
* Fixed-question stage: asks "research first or skip?" via
* ask_user_questions and writes .sf/runtime/research-decision.json.
* Fires after discuss-requirements and before research-project-parallel.
*/
export async function buildResearchDecisionPrompt(
base: string,
structuredQuestionsAvailable = "false",
): Promise<string> {
return loadPrompt("guided-research-decision", {
workingDirectory: base,
structuredQuestionsAvailable,
});
}
/**
* Build a prompt for the research-project-parallel unit type (deep mode).
* Orchestrator that spawns parallel subagents covering stack, features,
* architecture, and pitfalls. Each subagent writes its findings to
* .sf/research/. Fires after research-decision marker says "research" and
* project research files are missing. Skipped entirely if user picked "skip".
*/
export async function buildResearchProjectPrompt(
base: string,
structuredQuestionsAvailable = "false",
): Promise<string> {
return loadPrompt("guided-research-project", {
workingDirectory: base,
structuredQuestionsAvailable,
});
}
/**
* Build a prompt for the discuss-milestone unit type.
* Loads the guided-discuss-milestone template and inlines the CONTEXT-DRAFT