Deep Plan — Research-First PRD Generation
SkillAI & modelsDeep 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.
No other account needed.
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:
- Set
{co}= matched slug for the entire flow. Strip the slug — the remaining text is the project description - Announce: "Anchored on {co}"
- Load policies (frontmatter-only) — For each file in
companies/{co}/policies/(skipexample-policy.md,README.md, and any_digest.mdleftover), runbash core/scripts/read-policy-frontmatter.sh {file}. Noteenforcement: hardtitles. For hard-enforcement policies only, additionally read the## Rulesection with a targeted range. Policy digests (**/policies/_digest.md) are retired — SessionStart now injects matching policies viainject-policy-on-trigger; do not look for or prefer a digest file. Apply hard rules as constraints throughout the PRD - Scope qmd searches — If company has
qmd_collectionsin manifest, use-c {collection}for allqmdcalls - Pre-load repos — Extract
{co}.repos[]from manifest. Present as repo options in the Architecture tier repo question - Scope workers — Filter to company workers (
companies/{co}/workers/) + public workers (core/workers/public/) - 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 searchcompanies/{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; skipREADME.md/_digest.md), then for each runbash core/scripts/read-policy-frontmatter.sh {file}. Do not prefer a digest file (retired). For hard-enforcement policies, additionally read the## Rulesection
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:
-
Company: If project targets a company, read
companies/manifest.yaml. If company hasknowledge: null, flag: "Company {co} has no knowledge repo. Create one? [Y/n]" — if yes, create embedded repo atcompanies/{co}/knowledge/withgit init, and update manifest.yaml. -
Repo: If
repoPathspecified and doesn't exist locally, flag: "Repo not found at {path}. Clone it or create new?" Add tomanifest.yamlif missing. -
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:
- 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) - Check if
companies/{co}/projects/{name}/exists (also checkpersonal/projects/{name}/for personal/HQ)- If exists: ask the user "Project exists. Continue editing or choose different name?"
- 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:
-
Read it. Extract YAML frontmatter (
status,source_idea_id) -
If
status: "promoted"— warn the user: "This brainstorm was already promoted to a PRD. Open existing prd.json instead?" -
Extract brainstorm context for use in Step 3.7 (Research) and Step 4 (Interview):
brainstorm.context— from## Contextsection (problem description, pain points)brainstorm.recommendation— from## Recommendationsection (approach, rationale)brainstorm.rejectedApproaches— from rejected/discarded options (anti-patterns to avoid)brainstorm.unknowns— from## What We Don't Knowsection (open questions, risks)brainstorm.techChoices— any mentioned tech stack, data models, architecture preferencesbrainstorm.integrations— identified external servicesbrainstorm.workers— identified relevant workers, repos
-
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
-
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: truein the question tracking — smart-skip logic is bypassed
-
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.
-
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:
- Read it — surface(s) used, design rationale, and a proposed screen/story list.
- Set
metadata.designReftodesign/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). - This is the design-led handoff:
/storyboardexplored visuals first, and/deep-plannow 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.mdwith 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
/handoffboundaries — only/handoffand/checkpointclose 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):
- Check
brainstorm.mdYAML frontmatter forresearch_persisted: true. - Check that
{project_dir}/research/hq-context.mdexists. - Compute
brainstorm.mdmtime. 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 inresearch/.{reuse_hq_context} = falseandhq-context.mdexists 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.mdor 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.
| Agent | Condition | Output |
|---|---|---|
| Codebase Scanner | {repoPath} exists | research/codebase-scan.md |
| HQ Context Scanner | {reuse_hq_context} is false | research/hq-context.md (overwrites if stale) |
| Repo Deep-Read | {repoPath} exists | research/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:
- Read all files in
{project_dir}/research/that were written by agents - 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)
-
Display to user: "Research complete. {N} findings across {agent count} scans. Key constraints: {list}."
-
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
-
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.
-
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.
-
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.
-
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