Deep Plan — Research-First PRD Generation

SkillAI & models

Deep project planning — research subagents (codebase / HQ / repo) + 3-tier 15-question interview (Strategic / Architecture / Quality) with smart-skip and pushback. Use for large or strategically important PRDs. For lightweight planning, use /plan instead. Adversarial spec review is delegated to /review-plan after generation.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Deep Plan — Research-First PRD Generation skill

What this skill tells your AI

The instructions your AI receives, as published by indigoai-us/hq-core in .claude/skills/deep-plan/SKILL.md and read by ahel’s review.

Create execution-ready PRDs with full HQ context awareness, parallel research subagents, and a structured three-tier deep interview. Use this skill when the project is large, strategically important, touches unfamiliar code, or warrants the 10-15 minute upfront cost. For small ideas, tweaks, or fast captures, use the lightweight /plan skill instead.

Important: Do NOT implement. Just create the PRD.

Work Mesh Live — trusted bind (do this first)

Before any other tool call that touches project work, bind the session per .claude/skills/_shared/work-mesh-live-bind.md (US-011):

bash core/scripts/work-mesh-live-bind-trusted.sh \
  --company "{co}" --project "{project}" --task "{task}"

Omit --task when unknown. This writes workspace/sessions/<sid>/meta.yaml and reconciles with observation.trustedContext (no --trusted CLI flag).

Step 0: Company Anchor (from user input)

Resolve the company with the shared resolver — never by hand, and never from the first word alone:

bash core/scripts/resolve-company.sh --prompt "{the user's full input}"

It returns {"company":"<slug>","source":"session|prompt|none"}: the company bound for this session by /startwork wins, then a whole-token scan of the entire input (longest slug wins), then nothing. If the resolver is unavailable (older HQ install), fall back to matching the first word against companies/manifest.yaml top-level keys.

How to check: Read companies/manifest.yaml. Extract top-level keys (company slugs). If the first word exactly matches one of those slugs:

  1. Set {co} = matched slug for the entire flow. Strip the slug — the remaining text is the project description
  2. Announce: "Anchored on {co}"
  3. Load policies (frontmatter-only) — For each file in companies/{co}/policies/ (skip example-policy.md, README.md, and any _digest.md leftover), run bash core/scripts/read-policy-frontmatter.sh {file}. Note enforcement: hard titles. For hard-enforcement policies only, additionally read the ## Rule section with a targeted range. Policy digests (**/policies/_digest.md) are retired — SessionStart now injects matching policies via inject-policy-on-trigger; do not look for or prefer a digest file. Apply hard rules as constraints throughout the PRD
  4. Scope qmd searches — If company has qmd_collections in manifest, use -c {collection} for all qmd calls
  5. Pre-load repos — Extract {co}.repos[] from manifest. Present as repo options in the Architecture tier repo question
  6. Scope workers — Filter to company workers (companies/{co}/workers/) + public workers (core/workers/public/)
  7. Scope projects — Only search companies/{co}/projects/ for existing project collision check

If source is none — do not silently assume personal scope. Ask the user which company this belongs to, or whether it is personal/HQ work, before creating any project files. The full input text is the project description either way.

Step 1: Get Project Description

If user provided input, use as starting point. If empty, ask the user: "Describe what you want to build or accomplish." Wait for response.

Step 2: Scan HQ Context

Before asking questions, explore HQ. Resolve mode from Step 0 + input:

  • company mode — a company slug was anchored in Step 0
  • repo mode — no company anchor but a target repo is mentioned or resolvable from input
  • personal/HQ mode — neither of the above (personal projects, HQ infrastructure work)

If {co} is anchored, scope all searches to that company.

Companies & Context (only if mode in (company, repo)):

  • Read agents-companies.md (roles, priorities, three-tier roster) — needed to route cross-company PRDs
  • Read companies/manifest.yaml (companies already listed there — never Glob for company discovery)
  • Skip both if already anchored in Step 0: Step 0 already loaded manifest and matched the company. Re-reading is pure waste
  • Skip entirely for personal/HQ mode: no company routing needed, no repo to map

Workers (only if mode in (company, repo) AND the description plausibly needs a worker — otherwise skip):

  • Read core/workers/registry.yaml (workers already indexed there — never Glob for worker discovery). Skip if the description is clearly code/infra work not matching a worker skill
  • If anchored: filter to company workers (companies/{co}/workers/) + public workers (core/workers/public/)
  • Skip entirely for personal/HQ mode

Existing Projects:

  • If anchored: qmd search "prd.json" --json -n 20 -c {co} (scoped) or search companies/{co}/projects/ directly
  • If not anchored: qmd search "prd.json" --json -n 20 — existing projects across all companies and personal

Knowledge (use single qmd hybrid query, not Grep, not vsearch+search pair):

  • If anchored + company has qmd_collections: qmd query "<description keywords>" -c {collection} --json -n 10
  • If not anchored: qmd query "<description keywords>" --json -n 10 — hybrid BM25 + vector + re-ranking for related knowledge, prior work, workers

Company Policies (anchored only):

  • Already loaded in Step 0 (frontmatter-only). Do NOT re-read here. Note constraints from that scan

Repo Policies (if repo resolved):

  • If target repo identified, list files in {repoPath}/.claude/policies/ (if dir exists; skip README.md / _digest.md), then for each run bash core/scripts/read-policy-frontmatter.sh {file}. Do not prefer a digest file (retired). For hard-enforcement policies, additionally read the ## Rule section

Target Repo (if repo specified or discovered):

  • If anchored: company repos already pre-loaded from manifest. Present as options
  • If target repo has a qmd collection (e.g. my-app): qmd query "<description keywords>" -c {collection} --json -n 10 — hybrid search for related code, patterns, existing implementations
  • Present: "Found related code: {list of relevant files}"

Present:

Scanned HQ:
- Mode: {company | repo | personal/HQ}
- Company: {co} (anchored) | TBD | n/a
- Workers: {relevant list or "skipped"}
- Existing projects: {list or "none matching"}
- Relevant knowledge: {if any}
- Policies: {count loaded, or "none"}
- Category: [company-specific | cross-company | personal | HQ infrastructure]

Step 2.5: Infrastructure Pre-Check

Before generating the PRD, verify infrastructure exists for the target company/repo:

  1. Company: If project targets a company, read companies/manifest.yaml. If company has knowledge: null, flag: "Company {co} has no knowledge repo. Create one? [Y/n]" — if yes, create embedded repo at companies/{co}/knowledge/ with git init, and update manifest.yaml.

  2. Repo: If repoPath specified and doesn't exist locally, flag: "Repo not found at {path}. Clone it or create new?" Add to manifest.yaml if missing.

  3. qmd collection: If company has qmd_collections: [] in manifest, flag and offer to create collection.

Fix any gaps before proceeding.

Step 3: Get + Validate Project Name

Ask the user for project slug (or infer from description). Then:

  1. If {co} already set by Step 0: use it directly (skip company detection) If NOT set: determine company from context (infer from description, repo, or ask the user)
  2. Check if companies/{co}/projects/{name}/ exists (also check personal/projects/{name}/ for personal/HQ)
    • If exists: ask the user "Project exists. Continue editing or choose different name?"
  3. Validate slug format (lowercase, hyphens only)

Step 3.5: Brainstorm Detection

Now that {co} and {slug} are resolved, check if a brainstorm file exists:

companies/{co}/projects/{slug}/brainstorm.md

If found:

  1. Read it. Extract YAML frontmatter (status, source_idea_id)

  2. If status: "promoted" — warn the user: "This brainstorm was already promoted to a PRD. Open existing prd.json instead?"

  3. Extract brainstorm context for use in Step 3.7 (Research) and Step 4 (Interview):

    • brainstorm.context — from ## Context section (problem description, pain points)
    • brainstorm.recommendation — from ## Recommendation section (approach, rationale)
    • brainstorm.rejectedApproaches — from rejected/discarded options (anti-patterns to avoid)
    • brainstorm.unknowns — from ## What We Don't Know section (open questions, risks)
    • brainstorm.techChoices — any mentioned tech stack, data models, architecture preferences
    • brainstorm.integrations — identified external services
    • brainstorm.workers — identified relevant workers, repos
  4. Enrich interview questions (NOT collapse to confirmations). Brainstorm context is added to each question as additional context, but the full question is still asked one-at-a-time:

    • Each question in Step 4 gets a "Brainstorm suggested: {relevant finding}" line added to the question text, alongside the standard options
    • The user still answers the full question — brainstorm context informs their answer, it doesn't replace the question
    • Example: STRATEGIC-1 (Demand Reality) shows "Brainstorm suggested: {brainstorm.context pain points}" but still asks the full question and expects a specific answer
  5. Mandatory questions from brainstorm unknowns. Items from brainstorm.unknowns ("What We Don't Know") become mandatory interview questions that cannot be smart-skipped, regardless of research findings. These represent gaps the brainstorm session explicitly identified as unresolved. For each unknown:

    • Map to the closest Question Bank question (e.g., an unknown about auth → ARCHITECTURE-2)
    • If no close match, add as an ad-hoc question in the relevant tier
    • Mark as mandatory: true in the question tracking — smart-skip logic is bypassed
  6. Higher smart-skip threshold with brainstorm. When brainstorm.md exists, the smart-skip condition for any question requires both brainstorm AND research to clearly answer the question with consistent, unambiguous findings. If brainstorm says one thing and research says another, the question must be asked to resolve the conflict.

  7. Research agents incorporate brainstorm. Step 3.7's Agent 2 (HQ Context Scanner) already includes brainstorm enrichment in its prompt (see {brainstorm_context} variable). When brainstorm.md is detected here, that variable is populated with the brainstorm's recommended approach, rejected approaches, and open questions — so the research brief reflects brainstorm context.

Effect: Interview depth is preserved even with brainstorm. Questions are richer (pre-loaded with brainstorm context as suggested answers) but still asked in full. The brainstorm's explicit unknowns become mandatory deep-dives. This prevents the "brainstorm answered everything → shallow PRD" failure mode.

If not found: proceed normally (no change to existing behavior). All smart-skip thresholds use the default (research-only) conditions.

Step 3.55: Design Detection

Also check for a design artifact produced by /storyboard in design-led mode at companies/{co}/projects/{slug}/design/design.md.

If found:

  1. Read it — surface(s) used, design rationale, and a proposed screen/story list.
  2. Set metadata.designRef to design/design.md (plus any referenced Figma URL). Seed candidate stories from the design's screen list, and add each screen's resolved interaction as enrichment to the Architecture-tier questions (mirrors brainstorm enrichment — informs questions, does not collapse them).
  3. This is the design-led handoff: /storyboard explored visuals first, and /deep-plan now hardens them into a full PRD.

If not found: proceed normally.

Step 3.6: Open Session Journal

Spec: core/knowledge/public/hq-core/journal-spec.md. Open a session journal at the project_dir so research, decisions, and dead ends survive context compaction:

.claude/skills/_shared/journal.sh open deep-plan "{project_dir}"

Where {project_dir} = companies/{co}/projects/{slug}/ or personal/projects/{slug}/ for personal/HQ. The helper:

  • Creates {project_dir}/journal/{ISO8601}-deep-plan.md with frontmatter (status: active, skill: deep-plan)
  • Writes a session-scoped pointer under .claude/state/active-journal.d/ so this session's autocapture hook + later steps append to this file
  • Stays open across /handoff boundaries — only /handoff and /checkpoint close it

Subsequent steps (3.7 research synthesis, 4 interview decisions, 8.5 resolved/deferred questions) append curated entries via the same helper. The autocapture PostToolUse hook appends ## Auto-capture lines for any Agent / WebFetch / WebSearch / AskUserQuestion calls.

Skip if: journal helper unavailable (fail-soft).

Step 3.7: Research Phase (Phase 1 — Subagents)

Before asking interview questions, gather context via parallel research subagents. Research artifacts persist to disk (not chat) so they survive session handoffs and are available to execution workers.

Output directory: {project_dir}/research/ (alongside brainstorm.md and prd.json). Where {project_dir} = companies/{co}/projects/{slug}/ or personal/projects/{slug}/ for personal/HQ projects.

mkdir -p {project_dir}/research

Brainstorm-Research Reuse Check (before dispatch)

If Step 3.5 detected an existing brainstorm.md, check whether its research is fresh enough to reuse before dispatching Agent 2 (HQ Context Scanner):

  1. Check brainstorm.md YAML frontmatter for research_persisted: true.
  2. Check that {project_dir}/research/hq-context.md exists.
  3. Compute brainstorm.md mtime. If within 2 days (172800s) of now, set {reuse_hq_context} = true. Otherwise {reuse_hq_context} = false.

Bash reference:

if [[ -f "{project_dir}/research/hq-context.md" ]] \
   && grep -q '^research_persisted: true' "{project_dir}/brainstorm.md" 2>/dev/null; then
  mtime=$(stat -f %m "{project_dir}/brainstorm.md" 2>/dev/null || stat -c %Y "{project_dir}/brainstorm.md")
  age=$(( $(date +%s) - mtime ))
  if (( age < 172800 )); then echo "reuse"; else echo "stale"; fi
fi

Behavior:

  • {reuse_hq_context} = true: skip Agent 2. Announce: "Reusing research/hq-context.md from brainstorm (<N> hours old) — skipping HQ Context Scanner". Leave the file untouched; the Synthesis step at the end of Step 3.7 already reads every file in research/.
  • {reuse_hq_context} = false and hq-context.md exists but stale/unflagged: dispatch Agent 2 normally — it will overwrite the stale file. Announce: "Brainstorm hq-context.md is stale (>2d) — re-running HQ Context Scanner".
  • No hq-context.md or no brainstorm: dispatch Agent 2 normally, no announcement change.

Agents 1 (Codebase Scanner) and 3 (Repo Deep-Read) always run when {repoPath} exists — brainstorm does not produce those files.

Agent Dispatch

Spawn agents in parallel using the Agent tool. Each agent writes its findings to a specific file. The main session waits for all agents to complete before proceeding.

Resolve {repoPath} from Step 2 context (company manifest repos, user input, or brainstorm references). If no repo is identifiable, set {repoPath} = null.

AgentConditionOutput
Codebase Scanner{repoPath} existsresearch/codebase-scan.md
HQ Context Scanner{reuse_hq_context} is falseresearch/hq-context.md (overwrites if stale)
Repo Deep-Read{repoPath} existsresearch/repo-analysis.md

If {repoPath} is null (non-code project): only consider Agent 2 (HQ Context). Skip Agents 1 and 3. If {reuse_hq_context} is also true, no agents dispatch at all — proceed directly to Synthesis, which will still pick up the brainstorm's hq-context.md and landscape.md.


Agent 1 — Codebase Scanner
Spawn Agent (subagent_type: Explore) with prompt:

"Scan the repository at {repoPath} to understand its architecture for a new project: '{description}'.

Search for and document:
1. **Project structure**: Read CLAUDE.md (if exists), package.json/Cargo.toml/go.mod, and top-level directory layout
2. **Tech stack**: Framework, language version, ORM/DB client, auth system, CSS approach, test framework
3. **Existing patterns**: How are routes/endpoints structured? How are components organized? What naming conventions are used?
4. **Data models**: Read schema files, migration directories, or type definitions for existing entities
5. **Auth system**: How is authentication handled? What middleware/guards exist? What roles are defined?
6. **Key integrations**: External services already wired up (Stripe, SendGrid, analytics, etc.)

Write a structured markdown report to: {project_dir}/research/codebase-scan.md

Format:
# Codebase Scan: {repo name}

## Tech Stack
- Framework: ...
- Language: ...
- Database: ...
- Auth: ...
- Testing: ...

## Architecture Patterns
(describe routing, component, and data patterns)

## Existing Data Models
(list entities with key fields and relationships)

## Integrations
(list external services with how they're connected)

## Relevant Existing Code
(files/patterns directly relevant to: '{description}')

Keep the report factual and concise — no recommendations, just findings."
Agent 2 — HQ Context Scanner
Spawn Agent (subagent_type: Explore) with prompt:

"Scan HQ context for a new project '{slug}' ({description}) for company '{co}'.

Search for:
1. **Existing projects**: Read companies/{co}/projects/ — list any related or overlapping projects with their status
2. **Company workers**: Read companies/{co}/workers/ (if exists) + workers/registry.yaml — list workers relevant to this project's domain
3. **Company knowledge**: Search companies/{co}/knowledge/ for documents related to '{description keywords}'
4. **Company policies**: List companies/{co}/policies/ — note any hard-enforcement policies that constrain this project
5. **Related repos**: Check companies/manifest.yaml for {co}'s repos — note which might be relevant
{brainstorm_context}

Write a structured markdown report to: {project_dir}/research/hq-context.md

Format:
# HQ Context: {slug}

## Related Projects
(list with status and overlap description, or 'None found')

## Relevant Workers
(list with skills that apply)

## Knowledge Base Findings
(relevant docs with paths)

## Applicable Policies
(hard-enforcement policies with rule summaries)

## Available Repos
(company repos from manifest)

## Brainstorm Findings
(if brainstorm.md exists: recommended approach, rejected approaches, open questions — otherwise 'No brainstorm')

Keep the report factual and concise — no recommendations, just findings."

Brainstorm enrichment: If brainstorm.md was detected in Step 3.5, append to the Agent 2 prompt:

{brainstorm_context} = "
6. **Brainstorm context**: Read {project_dir}/brainstorm.md — extract:
   - Recommended approach and its rationale
   - Rejected approaches and why
   - 'What We Don't Know' items (open questions)
   - Any mentioned tech choices, data models, or architecture preferences
"

If no brainstorm: {brainstorm_context} = ""

Agent 3 — Repo Deep-Read
Spawn Agent (subagent_type: Explore) with prompt:

"Deep-read the repository at {repoPath} for recent activity and test patterns relevant to: '{description}'.

Search for:
1. **Recent git history**: Run `git log --oneline -30` — summarize recent development themes and active areas
2. **Test structure**: Find test directories, test file patterns, test commands in package.json/scripts. Note coverage configuration if present
3. **Recent changes**: Run `git diff --stat HEAD~10` — what files are actively being modified?
4. **CI/CD**: Check .github/workflows/, vercel.json, Dockerfile, deploy scripts — document the deployment pipeline
5. **Open issues/branches**: Run `git branch -r --list 'origin/feature/*'` — note active feature work that might conflict

Write a structured markdown report to: {project_dir}/research/repo-analysis.md

Format:
# Repo Analysis: {repo name}

## Recent Development
(themes from last 30 commits)

## Active Areas
(files/directories with most recent changes)

## Test Infrastructure
- Framework: ...
- Test command: ...
- Coverage: ...
- Test directories: ...

## CI/CD Pipeline
(deployment pipeline description)

## Active Branches
(feature branches that might overlap with this project)

Keep the report factual and concise — no recommendations, just findings."

Synthesis — Research Brief

After all agents complete, the main session reads the research files and writes a compact synthesis:

  1. Read all files in {project_dir}/research/ that were written by agents
  2. Synthesize into {project_dir}/research/research-brief.md:
# Research Brief: {slug}

## Key Findings
- {3-5 bullet points of most important discoveries across all agents}

## Pre-Answered Questions
(questions from the Question Bank that research already answers — list question ID + finding)

## Open Questions Surfaced
(new questions raised by research that should be asked during interview)

## Constraints Discovered
(hard policies, existing patterns, or technical constraints that limit options)

## Brainstorm Alignment
(if brainstorm exists: how research findings align/conflict with brainstorm's recommendation — otherwise omit)
  1. Display to user: "Research complete. {N} findings across {agent count} scans. Key constraints: {list}."

  2. Append synthesis to journal (curated layer):

.claude/skills/_shared/journal.sh append "{project_dir}" findings "Research synthesis: key findings — {3-5 bullets}; pre-answered — {list of question IDs}; open questions surfaced — {list}; constraints — {list}"

This preserves the research thinking even if research-brief.md is later edited or the session compacts before PRD finalization.

The research brief is the primary input for smart-skip logic in Step 4. When a question's smart-skip condition references "research," it means checking research-brief.md for pre-answered questions.

Step 4: Deep Interview (Phase 2 — One-at-a-Time)

Sequential one-at-a-time questioning using the Question Bank (see bottom of this file). Each question is asked via AskUserQuestion with 2-4 concrete options + a free text override. Questions are asked one at a time — never batched.

Minimum: 10 questions asked (including smart-skip confirmations). Target: 15. Track count throughout.

Interview Rules

  1. One question at a time. Ask a single question via AskUserQuestion. Wait for the response. Process it. Then ask the next question. Never combine multiple questions into one AskUserQuestion call.

  2. Pushback on vague answers. If the user's response matches the question's pushback pattern (vague, category-level, non-specific), push back once with the defined follow-up. After the pushback response, accept whatever the user provides — never push more than once per question.

  3. Anti-sycophancy. Never say "that's interesting," "great idea," "love that," or similar flattery. Instead, take a position on every answer: "That narrows scope well," "I'd challenge that — {reason}," "Strong signal — the pain is quantified." React substantively or move on silently.

  4. Smart-skip logic. Before asking each question, check its smart-skip condition against:

    • {project_dir}/research/research-brief.md (from Step 3.7)
    • {project_dir}/brainstorm.md (from Step 3.5, if exists)
    • Prior answers from earlier questions in this interview If the smart-skip condition is met, present the question's confirmation format instead of the full question. Confirmations still count toward the question minimum. Use AskUserQuestion with options: ["Confirm", "Modify — {free text}"].

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
84
Forks
15
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
deep-plan-indigoai-us
Source
github.com/indigoai-us/hq-core