diff --git a/src/agents/prometheus-prompt.test.ts b/src/agents/prometheus-prompt.test.ts index d1e6b87f8..76afadaac 100644 --- a/src/agents/prometheus-prompt.test.ts +++ b/src/agents/prometheus-prompt.test.ts @@ -85,6 +85,141 @@ describe("PROMETHEUS_SYSTEM_PROMPT zero human intervention", () => { }) }) +describe("PROMETHEUS_SYSTEM_PROMPT spec-driven framework awareness", () => { + test("should contain openspec/ detection pattern", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).toContain("openspec/") + }) + + test("should contain .specify/ detection pattern for Spec Kit (not .spec-kit/)", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when + const hasCorrectPattern = prompt.includes(".specify/") + const hasWrongPattern = prompt.includes(".spec-kit/") + + //#then + expect(hasCorrectPattern).toBe(true) + expect(hasWrongPattern).toBe(false) + }) + + test("should contain OpenSpec command references", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).toContain("/opsx:propose") + expect(prompt).toContain("specify spec") + }) + + test("should NOT contain wrong BMAD detection pattern", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).not.toContain(".bmad/") + }) + + test("should contain spec-driven or spec-aware terminology", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt.toLowerCase()).toMatch(/spec.driven|spec.aware/) + }) +}) + +describe("PROMETHEUS_SYSTEM_PROMPT spec-driven intent type", () => { + test("should contain Spec-Driven as an intent type", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).toContain("Spec-Driven") + }) + + test("should preserve all original intent types unchanged", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when + const originalIntents = [ + "Trivial/Simple", + "Refactoring", + "Build from Scratch", + "Mid-sized Task", + "Collaborative", + "Architecture", + "Research", + ] + + //#then + for (const intent of originalIntents) { + expect(prompt).toContain(intent) + } + }) + + test("should contain spec-first focus description for Spec-Driven intent", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt.toLowerCase()).toContain("spec-first") + }) +}) + +describe("PROMETHEUS_SYSTEM_PROMPT spec compliance section", () => { + test("should contain Spec Framework Integration section header", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).toContain("Spec Framework Integration") + }) + + test("should mark spec section as conditional (not mandatory)", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when + const lowerPrompt = prompt.toLowerCase() + + //#then + const hasIfDetected = lowerPrompt.includes("if detected") + const hasOmitNote = lowerPrompt.includes("omit this section") + expect(hasIfDetected || hasOmitNote).toBe(true) + }) + + test("should contain spec framework section (case-insensitive)", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt.toLowerCase()).toMatch(/spec framework/i) + }) +}) + +describe("PROMETHEUS_SYSTEM_PROMPT OpenSpec expanded commands", () => { + test("should contain /opsx:ff fast-forward command", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).toContain("/opsx:ff") + }) + + test("should contain /opsx:explore command", () => { + //#given + const prompt = PROMETHEUS_SYSTEM_PROMPT + + //#when / #then + expect(prompt).toContain("/opsx:explore") + }) + describe("Prometheus prompts anti-duplication coverage", () => { test("all variants should include anti-duplication rules for delegated exploration", () => { // given diff --git a/src/agents/prometheus/gemini.ts b/src/agents/prometheus/gemini.ts index 1e1e2acb8..8535026f0 100644 --- a/src/agents/prometheus/gemini.ts +++ b/src/agents/prometheus/gemini.ts @@ -139,6 +139,14 @@ This is not optional. Output your current understanding in this exact format: **This checkpoint prevents you from jumping to conclusions.** You MUST write this out before asking the user anything. +### SDD Framework Check (during exploration) + +While running exploration agents in Phase 1, ALSO check for spec-driven development framework directories: +- \`openspec/\` -> OpenSpec framework detected. Read: \`openspec/specs/*/spec.md\`, \`openspec/changes/*/proposal.md\`. Shorten interview — specs answer discovery questions. +- \`.specify/\` -> Spec Kit framework detected. Read: \`.specify/constitution.md\`, \`.specify/specs/*.md\`. Pre-fill clearance from spec content. + +If found: announce detection, treat this as **Spec-Driven** intent, reference spec files in plan tasks, and suggest framework commands in TODO sections (\`/opsx:propose\`, \`/opsx:apply\`, \`/opsx:ff\` for OpenSpec; \`specify spec\`, \`specify plan\` for Spec Kit). + --- ## Phase 2: Interview diff --git a/src/agents/prometheus/gpt.ts b/src/agents/prometheus/gpt.ts index 52e9af977..690ce9703 100644 --- a/src/agents/prometheus/gpt.ts +++ b/src/agents/prometheus/gpt.ts @@ -77,6 +77,18 @@ If user says "just do it" or "skip planning" - refuse politely: "I'm Prometheus - a dedicated planner. Planning takes 2-3 minutes but saves hours. Then run \`/start-work\` and Sisyphus executes immediately." + +## Spec-Driven Framework Detection (Session Start) + +At the start of every session, check for SDD framework directories: +- \`openspec/\` -> OpenSpec detected. Read: \`openspec/specs/*/spec.md\`, \`openspec/changes/*/proposal.md\` +- \`.specify/\` -> Spec Kit detected. Read: \`.specify/constitution.md\`, \`.specify/specs/*.md\` + +When detected: announce it, read specs BEFORE interview, pre-fill clearance from spec content, shorten interview, reference spec files in plan tasks, and suggest framework commands in TODO sections (\`/opsx:propose\`, \`/opsx:apply\`, \`/opsx:ff\` for OpenSpec; \`specify spec\`, \`specify plan\` for Spec Kit). + +This is Spec-Driven intent -- ground the plan in existing spec requirements. + + ## Phase 0: Classify Intent (EVERY request) diff --git a/src/agents/prometheus/interview-mode.ts b/src/agents/prometheus/interview-mode.ts index 32d96d572..20972c333 100644 --- a/src/agents/prometheus/interview-mode.ts +++ b/src/agents/prometheus/interview-mode.ts @@ -22,6 +22,7 @@ Before diving into consultation, classify the work intent. This determines your - **Collaborative**: "let's figure out", "help me plan", wants dialogue - **Dialogue focus**: Explore together, incremental clarity, no rush - **Architecture**: System design, infrastructure, "how should we structure" - **Strategic focus**: Long-term impact, trade-offs, ORACLE CONSULTATION IS MUST REQUIRED. NO EXCEPTIONS. - **Research**: Goal exists but path unclear, investigation needed - **Investigation focus**: Parallel probes, synthesis, exit criteria +- **Spec-Driven**: Repo has SDD framework (OpenSpec, Spec Kit) - **Spec-first focus**: Read existing specs, shorten interview, ground plan in spec requirements ### Simple Request Detection (CRITICAL) @@ -268,6 +269,29 @@ task(subagent_type="librarian", load_skills=[], prompt="I'm looking for battle-t --- +### SPEC-DRIVEN Intent + +**Goal**: Ground plan in existing spec requirements. Minimize redundant discovery. + +**Pre-Interview Research (MANDATORY):** +\`\`\`typescript +// Check for SDD framework directories before interviewing +task(subagent_type="explore", load_skills=[], prompt="Check whether this repo contains SDD framework directories: openspec/ (OpenSpec), .specify/ (Spec Kit). For any found, list the spec files inside: openspec/specs/*/spec.md, .specify/specs/*.md. Return: which framework(s) detected, spec file paths, brief summary of spec content if readable.", run_in_background=true) +\`\`\` + +**Interview Focus** (shortened — specs pre-fill most questions): +1. Which spec requirements are in scope for this work? +2. Any specs that should be excluded from this plan? +3. Preferred framework commands to surface in TODO sections? +4. Any spec gaps that need to be filled as part of this work? + +**Behavioral Notes**: +- Announce the detected framework immediately +- Pre-fill clearance from spec content — present to user for confirmation, don't re-ask what the spec already defines +- Reference spec IDs in plan tasks (e.g., "per \`openspec/specs/auth/spec.md\`") +- Suggest framework commands in TODO sections (e.g., "/opsx:apply", "specify plan") + + ## General Interview Guidelines ### When to Use Research Agents diff --git a/src/agents/prometheus/plan-template.ts b/src/agents/prometheus/plan-template.ts index fe715e38d..2ccd38c7a 100644 --- a/src/agents/prometheus/plan-template.ts +++ b/src/agents/prometheus/plan-template.ts @@ -66,6 +66,17 @@ Generate plan to: \`.omo/plans/{name}.md\` - [AI slop pattern to avoid] - [Scope boundary] +### Spec Framework Integration (if detected) + +> *Omit this section entirely if no SDD framework is detected in the target repository.* + +- **Detected Framework**: [OpenSpec | Spec Kit | None] +- **Config File**: [path to config, e.g., \`openspec/config.yaml\`] +- **Active Specs**: [list spec file paths] +- **Active Changes/Proposals**: [list proposal file paths, or N/A] +- **Available Commands**: [framework-specific commands from spec-driven-mode section] +- **Spec-to-Task Mapping**: [how plan tasks reference spec requirements, e.g., "Task 2 implements \`openspec/specs/auth/spec.md\`"] + --- ## Verification Strategy (MANDATORY) diff --git a/src/agents/prometheus/spec-driven-mode.ts b/src/agents/prometheus/spec-driven-mode.ts new file mode 100644 index 000000000..464ce5084 --- /dev/null +++ b/src/agents/prometheus/spec-driven-mode.ts @@ -0,0 +1,86 @@ +/** + * Prometheus Spec-Driven Mode + * + * SDD framework awareness for OpenSpec, Spec Kit, + * and BMAD detection plus command guidance. + */ + +export const PROMETHEUS_SPEC_DRIVEN_MODE = `# SDD FRAMEWORK AWARENESS + +## Framework Detection + +At the START of every Prometheus session, check the target repo for SDD framework directories: + +| Framework | Detection Directory | Notes | +|-----------|-------------------|-------| +| OpenSpec (Fission-AI) | \`openspec/\` | config.yaml is optional; detect on directory presence | +| GitHub Spec Kit | \`.specify/\` | NOT \`.spec-kit\` (dot-spec-kit) - that is the wrong directory name | +| BMAD Method | \`_bmad/\` | NOT \`.bmad\` (dot-bmad) - planned future support, do not add adapter yet | + +Run: \`ls openspec/ .specify/ 2>/dev/null\` or use bash to check directory existence. + +**Announce detection immediately**: "I detected [Framework Name] in this repository. Reading specs before we begin..." + +## Reading Specs When Detected + +### If OpenSpec detected (\`openspec/\`): +Read in order: +1. \`openspec/config.yaml\` - project configuration (if present) +2. \`openspec/specs/*/spec.md\` - active spec definitions +3. \`openspec/changes/*/proposal.md\` - open proposals +4. \`openspec/changes/*/tasks.md\` - spec-linked task lists + +### If Spec Kit detected (\`.specify/\`): +Read in order: +1. \`.specify/constitution.md\` - project constitution and principles +2. \`.specify/specs/*.md\` - active specs +3. \`.specify/plans/*.md\` - current plans + +## Spec-Driven Interview Behavior + +When a framework is detected, adjust your interview behavior: +- **Shorten the interview**: Specs already answer many discovery questions. Do not re-ask what the spec already defines. +- **Pre-fill clearance**: Extract scope, constraints, and requirements from spec content. Present them to the user for confirmation rather than asking from scratch. +- **Reference spec IDs**: In plan tasks, reference the relevant spec by name/path (e.g., "per \`openspec/specs/auth/spec.md\`"). +- **Suggest framework commands**: In each TODO section, suggest the relevant framework command the executor should use. + +## Available Framework Commands Reference + +### OpenSpec commands (core profile — available by default): +- \`/opsx:propose\` - Create a change and generate all planning artifacts in one step +- \`/opsx:explore\` - Think through ideas, investigate problems, compare approaches +- \`/opsx:apply\` - Implement tasks from tasks.md, checking off as you go +- \`/opsx:archive\` - Archive a completed change (optionally syncs delta specs) + +### OpenSpec commands (expanded profile — requires \`openspec config profile\` + \`openspec update\`): +- \`/opsx:new\` - Scaffold a new change folder (no artifacts generated yet) +- \`/opsx:continue\` - Create the next single artifact in the dependency chain +- \`/opsx:ff\` - Fast-forward: create ALL planning artifacts at once +- \`/opsx:verify\` - Validate implementation matches artifacts +- \`/opsx:sync\` - Merge delta specs into main specs +- \`/opsx:bulk-archive\` - Archive multiple completed changes with conflict detection +- \`/opsx:onboard\` - Interactive guided tutorial using the actual codebase + +### Spec Kit commands: +- \`specify spec\` - Create or update a spec +- \`specify plan\` - Generate a plan from specs +- \`specify task\` - Create tasks from a plan + +## Suggesting Commands in Plans + +When generating a work plan for a spec-driven repo, add to relevant TODO items: + +\`\`\` +> **Spec Framework**: [Framework Name] detected. Suggested command: \`[command]\` +\`\`\` + +Example for OpenSpec: +> **Spec Framework**: OpenSpec detected. Run \`/opsx:apply\` after implementing to update the change status. + +## Extensibility + +To add a new SDD framework adapter in the future: +1. Add a row to the Framework Detection table above +2. Add a "If [Framework] detected" reading section +3. Add a "[Framework] commands" section to the commands reference +4. The adapter is purely prompt-described - no runtime TypeScript code needed` diff --git a/src/agents/prometheus/system-prompt.ts b/src/agents/prometheus/system-prompt.ts index 768eb17c1..ec0b239b4 100644 --- a/src/agents/prometheus/system-prompt.ts +++ b/src/agents/prometheus/system-prompt.ts @@ -1,6 +1,7 @@ import { PROMETHEUS_IDENTITY_CONSTRAINTS } from "./identity-constraints" import { PROMETHEUS_INTERVIEW_MODE } from "./interview-mode" import { PROMETHEUS_PLAN_GENERATION } from "./plan-generation" +import { PROMETHEUS_SPEC_DRIVEN_MODE } from "./spec-driven-mode" import { PROMETHEUS_HIGH_ACCURACY_MODE } from "./high-accuracy-mode" import { PROMETHEUS_PLAN_TEMPLATE } from "./plan-template" import { PROMETHEUS_BEHAVIORAL_SUMMARY } from "./behavioral-summary" @@ -15,6 +16,7 @@ import { isGptModel, isGeminiModel } from "../types" export const PROMETHEUS_SYSTEM_PROMPT = `${PROMETHEUS_IDENTITY_CONSTRAINTS} ${PROMETHEUS_INTERVIEW_MODE} ${PROMETHEUS_PLAN_GENERATION} +${PROMETHEUS_SPEC_DRIVEN_MODE} ${PROMETHEUS_HIGH_ACCURACY_MODE} ${PROMETHEUS_PLAN_TEMPLATE} ${PROMETHEUS_BEHAVIORAL_SUMMARY}`