ba

SkillSearch

Business Analyst agent. Use when starting a new feature requiring requirements elicitation BEFORE plan or cook. Asks probing questions, identifies hidden requirements, maps stakeholders, defines scope boundaries, and produces a structured Requirements Document that plan and cook consume.

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 ba skill

What this skill tells your AI

The instructions your AI receives, as published by rune-kit/rune in skills/ba/SKILL.md and read by ahel’s review.

Purpose

Business Analyst agent — the ROOT FIX for "Claude works a lot but produces nothing." BA forces deep understanding of WHAT to build before any code is written. It asks probing questions, identifies hidden requirements, maps stakeholders, defines scope boundaries, and produces a structured Requirements Document.

Wrong requirements shipped correctly is the most expensive bug. BA's job is to prevent it — measure clarity (Step 2.5), measure completeness (Step 3.5), and measure cross-dimension consistency (Step 3.6) before handoff.

Goal-first (advisory, 2026). The Requirements Document is the goal spec current models want up front. Where the platform has a native goal/outcome command — Claude Code /goal, Managed Agents Outcomes (rubric) — seed it from this document's scope boundaries + acceptance criteria so the whole run stays anchored to the agreed WHAT.

Triggers

  • Called by cook Phase 1 when task is product-oriented (not a simple bug fix)
  • Called by scaffold Phase 1 before any project generation
  • /rune ba <requirement> — manual invocation
  • Auto-trigger: when user description is > 50 words OR contains business terms (users, revenue, workflow, integration)

Calls (outbound)

  • scout (L2): scan existing codebase for context
  • research (L3): look up similar products, APIs, integrations
  • plan (L2): hand off Requirements Document for implementation planning
  • brainstorm (L2): when multiple approaches exist for a requirement
  • design (L2): when requirements include UI/UX components — hand off visual requirements

Called By (inbound)

  • cook (L1): before Phase 2 PLAN, when task is non-trivial
  • scaffold (L1): Phase 1, before any project generation
  • plan (L2): when plan receives vague requirements
  • brainstorm (L2): standalone ideation that picked an approach for a new feature with no spec — hands the chosen approach to ba for requirements before plan
  • mcp-builder (L2): requirements elicitation before MCP server design
  • User: /rune ba direct invocation

Cross-Hub Connections

  • baplan — ba produces requirements, plan produces implementation steps
  • babrainstorm — ba calls brainstorm when multiple requirement approaches exist
  • bacook — cook calls ba for non-trivial tasks, ba feeds requirements into cook's pipeline
  • bascaffold — scaffold requires ba output before project generation

Executable Steps

Step 1 — Intake & Classify

Read the user's request. Classify the requirement type:

TypeSignalDepth
Feature Request"add X", "build Y", "I want Z"Full BA cycle (Steps 1-7)
Bug Fix"broken", "error", "doesn't work"Skip BA → direct to debug
Refactor"clean up", "refactor", "restructure"Light BA (Step 1 + Step 4 only)
Integration"connect X to Y", "integrate with Z"Full BA + API research
Greenfield"new project", "build from scratch"Full BA + market context

If Bug Fix → skip BA, route to cook/debug directly. If Refactor → light version (Step 1 + Step 4 only). Skip Steps 2, 2.5, 3, 5, 6.

If existing codebase → invoke rune:scout for context before proceeding.

Step 1.4 — Synthesis Trigger Check

Before proceeding to elicitation, check whether the requirements are already in context. Re-asking what the user already told you is the second-most expensive bug.

Activate Synthesis Mode instead of standard elicitation if ANY of:

SignalThreshold
User pasted a spec / PRD / brief> 200 words describing the feature
Conversation has > 1000 words on this featureSufficient context already gathered
User said "synthesize" / "I already explained" / "just write the spec"Explicit synthesis request
Continuation — .rune/features/<name>/requirements.md exists with prior answersRe-elicitation would duplicate
Issue tracker has filled-in template (problem, story, acceptance criteria)Source already structured

In Synthesis Mode: extract answers from existing context, draft the Requirements Document with source citations for every section, then confirm rather than re-interview. Ask follow-ups ONLY on the 1-2 dimensions with genuine gaps. Skip steps 2, 2.5 if all 5 dimensions are filled or partial-but-acceptable.

Workflow detail + anti-patterns: references/synthesis-mode.md.

Step 1.5 — Out-of-Scope Match Check (READ)

Before any elicitation, check whether the request matches a concept previously rejected.

  1. Glob .out-of-scope/*.md — if directory absent, skip silently.
  2. For each file, parse YAML frontmatter (concept, aliases).
  3. Build a token map (lowercased, split on - and whitespace).
  4. Tokenize the user's request the same way.
  5. Compute lexical overlap per concept; keep the top match's confidence (0.0–1.0).

Action by confidence:

ConfidenceVerdictAction
≥ 0.8exact-matchSurface to user: "This matches a prior rejection (.out-of-scope/<slug>.md) — closed because [body's "Why out of scope" first sentence]. Do you still feel the same way?" Pause for user response before continuing.
0.5 – 0.79similarMention inline: "This is similar to a prior rejection (<slug>). Would you like to review it before we proceed?" Continue regardless of answer.
< 0.5no-matchContinue silently, no user-facing mention.

Emit outofscope.match signal with {concept, confidence, verdict} so downstream skills (cook, plan) inherit the context.

If verdict is exact-match AND user says "yes I still want it" → record their override reason in the Requirements Document ## Risks section AND mark priority_to_revisit: high in the existing .out-of-scope/<slug>.md (do NOT delete the file). The override forces the candidate up the revisit ladder; it doesn't erase the prior decision.

If verdict is exact-match AND user accepts the prior rejection → end the BA session with a one-line summary referencing the file. No further questions.

Format reference: references/out-of-scope-format.md.

Step 1.6 — Mid-Elicitation Reject WRITE Path

If the user explicitly rejects the feature at any point during elicitation (Steps 2-3) — common phrases: "scrap it", "actually nah, don't build this", "we won't do this", "kill the feature", "drop it" — STOP elicitation and write a .out-of-scope/<slug>.md record before ending the session.

Without this WRITE path, oral rejections vanish — the next session re-asks the same questions and the user has to re-reject. Step 1.5 (READ) only catches matches against existing files; Step 1.6 (WRITE) is what produces those files in the first place.

Procedure:

  1. Confirm rejection is durable, not deferral. Ask one clarifier:

    "Just to record this correctly: is this out of scope (project doesn't want this), or deferred (not now but maybe later)? Out-of-scope gets recorded so we don't re-litigate; deferred goes to backlog instead."

    • If deferred → route to backlog (no .out-of-scope/ write), end session with a one-line note
    • If out-of-scope → continue to step 2
  2. Capture the durable reason. Ask:

    "What's the reason this is out of scope? (project scope, technical constraint, strategic decision — not a temporary circumstance)"

    If the user gives a temporary reason ("we're busy"), reframe: "That's a deferral — should I route to backlog instead?"

  3. Generate slug (kebab-case, ≤40 chars, recognizable without opening the file).

  4. Lexical-similarity check: Glob .out-of-scope/*.md, parse each frontmatter's concept + aliases, compute overlap. If any existing concept has ≥0.7 overlap → APPEND to that file's prior_requests list and mark rejected_by: ba for this round. Do NOT create a duplicate.

  5. Write the file using the format in references/out-of-scope-format.md:

    • YAML frontmatter (concept, aliases, decision: rejected, rejected_at, rejected_by: ba, prior_requests, optional revisit_if)
    • Markdown body: concept name, "Why out of scope" (substantive reasoning from step 2), "What would change our mind" (if user volunteered signals)
  6. Emit outofscope.recorded signal carrying {slug, rejected_by: ba, prior_requests_count} so downstream skills know a new rejection landed.

  7. End BA session with one-line summary:

    "Recorded as out of scope in .out-of-scope/<slug>.md. Future similar requests will surface this. Override anytime by editing the file."

When NOT to write:

  • User merely defers ("not now") → backlog, not .out-of-scope/
  • User rejects a single requirement within a larger feature → adjust requirements doc Boundaries section, don't write a whole rejection file (the feature is still in scope)
  • Bug rejections (already fixed, not reproducible) → not BA's job; route to incident or close the issue
  • The match was already exact (≥0.8) and Step 1.5 surfaced it — user accepting the prior rejection just appends to prior_requests of the existing file (handled in Step 1.5 path)

Step 2.0 — Explore-First Pre-Check (HARD-GATE)

Before emitting ANY of the 5 elicitation questions, run the 4-item pre-check on each intended question:

  1. Is the answer in package.json / pyproject.toml / Cargo.toml / go.mod / pom.xml?
  2. Is the answer in README.md / CLAUDE.md / docs/?
  3. Is it inferable from file extensions, directory structure, or config files?
  4. Has the user answered it earlier in this conversation?

The gate is "tried to infer" — not "must succeed in inferring." If the file genuinely doesn't have the answer, the attempt itself is the gate.

Cache inferred answers in the requirements doc:

**Inferred from package.json**: TypeScript 5.4, Next.js 14.2, React 18.3
**Inferred from .github/workflows/**: CI runs on PRs targeting main

Worked examples + edge cases: references/explore-first.md.

Step 2 — Requirement Elicitation (the "5 Questions")

Ask exactly 5 probing questions, ONE AT A TIME (not all at once):

  1. WHO — "Who is the end user? What's their technical level? What are they doing right before and after using this feature?"
  2. WHAT — "What specific outcome do they need? What does 'done' look like from the user's perspective?"
  3. WHY — "Why do they need this? What problem does this solve? What happens if we don't build it?"
  4. BOUNDARIES — "What should this NOT do? What's explicitly out of scope?"
  5. CONSTRAINTS — "Any technical constraints? (existing APIs, performance requirements, security needs, deadlines)"
Question Discipline (MANDATORY)

Every question the user answers burns attention you don't get back. Protect it.

  1. Max 5 questions total across the whole BA session. If you find yourself wanting a 6th, the answer is in the first 5 or you're stalling — re-read, don't re-ask.
  2. Prefer yes/no or multiple-choice over open-ended. An open-ended question is a last resort when no reasonable option set exists.
    • BAD: "What auth strategy do you want?"
    • GOOD: "Auth: (a) email+password with JWT, (b) OAuth (Google/GitHub), (c) magic link, (d) I'll decide — pick one."
  3. Never ask what you can infer. If the answer is in the repo, the user's message, or the classification from Step 1 — don't ask it.
    • Wrong stack? → read package.json, don't ask.
    • Wrong audience? → check the README, don't ask.
    • Wrong framework? → check config files, don't ask.
  4. Cache the answer. Write each Q→A pair into the Requirements Document verbatim. If the user restarts the BA session on the same feature, reuse the cached answers — never re-ask what was already answered.
  5. Bundle yes/no questions after Q1 if the user is concise. A user who replies "y" / "n" / "skip" in 1-2 words tolerates a bundle. A user who replies with paragraphs wants the slow pace — keep one-at-a-time.

Every Q should earn its slot: removing it must leave the Requirements Document materially worse. If it wouldn't, cut the question.

Structured Elicitation Frameworks

Choose the framework that fits the requirement type. Use it to STRUCTURE the 5 Questions above, not replace them.

FrameworkWhen to UseStructure
PICOClinical, research, data-driven, or A/B testing featuresPopulation (who), Intervention (what change), Comparison (vs what), Outcome (measurable result)
INVESTUser stories for sprint-sized featuresIndependent, Negotiable, Valuable, Estimable, Small, Testable
Jobs-to-be-DoneProduct features, user workflows"When [situation], I want to [motivation] so I can [expected outcome]"

PICO Example (data feature):

P: Dashboard users monitoring real-time metrics
I: Add anomaly detection alerts
C: vs. current manual threshold setting
O: 30% faster incident detection (measurable KPI)

When to apply which:

  • Feature Request → INVEST (ensures stories are sprint-ready)
  • Data/Analytics/Research feature → PICO (forces measurable outcome definition)
  • Product/UX feature → Jobs-to-be-Done (keeps focus on user motivation)
  • Integration → 5 Questions only (frameworks add noise for plumbing tasks)

Step 2.5 — Ambiguity Scoring (Execution Gate)

After each question round, compute an Ambiguity Score to determine if requirements are clear enough to proceed. This prevents premature handoff to plan with vague inputs.

Scoring Formula
Ambiguity = 1 - weighted_average(dimensions)

Dimensions (weights vary by requirement type):
  Greenfield:  Goal (40%) + Constraints (30%) + Success Criteria (30%)
  Feature:     Goal (30%) + Constraints (30%) + Success Criteria (20%) + Integration (20%)
  Integration: Goal (20%) + Constraints (25%) + Success Criteria (20%) + API Contract (35%)
Dimension Scoring (0.0 – 1.0)
Dimension0.0 (Unknown)0.5 (Partial)1.0 (Clear)
Goal"Make it better""Improve dashboard performance""Dashboard loads in <2s with 10k rows"
ConstraintsNo constraints mentioned"Use existing DB""PostgreSQL 15, no new deps, GDPR compliant"
Success Criteria"It should work""Users can see their data""AC-1.1: GIVEN 10k rows WHEN page loads THEN render <2s"
Integration"Connect to the API""Use REST, need auth""POST /api/v2/orders, OAuth2, rate limit 100/min"
API Contract"It sends data somewhere""JSON payload to endpoint""OpenAPI spec provided, request/response schemas defined"
Threshold Gate
AmbiguityLevelAction
< 15%Crystal ClearProceed to Step 3 immediately
15-25%AcceptableProceed with noted assumptions — flag gaps in Requirements Doc
25-40%UnclearAsk 1-2 targeted follow-up questions on weakest dimension
> 40%BlockedDo NOT proceed. Re-ask the weakest dimension question with examples
Scoring After Each Question

After each of the 5 Questions (Step 2), update the score:

Round 1 (WHO):    Goal ≈ 0.3, others = 0.0 → Ambiguity ≈ 91%
Round 2 (WHAT):   Goal ≈ 0.7, Success ≈ 0.3 → Ambiguity ≈ 72%
Round 3 (WHY):    Goal ≈ 0.9, Success ≈ 0.5 → Ambiguity ≈ 47%
Round 4 (BOUNDS): Constraints ≈ 0.6 → Ambiguity ≈ 30%
Round 5 (CONSTR): Constraints ≈ 0.9 → Ambiguity ≈ 12% ✅

If Ambiguity drops below 15% before all 5 questions are asked (e.g., user provides a detailed PRD), skip remaining questions and proceed. The gate is about clarity, not ceremony.

Display Format

After completing Step 2, show the user:

Clarity Score: [100 - ambiguity]%
  Goal:             [██████████] 0.9
  Constraints:      [████████░░] 0.8
  Success Criteria: [██████░░░░] 0.6  ← weakest
  Status: ACCEPTABLE (ambiguity 23%) — proceeding with noted gaps

Step 2.6 — CONTEXT.md Cross-Reference Gate

After elicitation, before hidden-requirement discovery, scan the user's answers for assertions about current behavior — phrasings like "the system X", "the code does X", "we already X", "right now it X".

For each such assertion:

  1. Grep the codebase for evidence (function names, route handlers, schema definitions matching the asserted behavior).
  2. Compare grep results to the user's claim.
OutcomeAction
Grep confirms claimProceed; record term in CONTEXT.md if domain-relevant
Grep contradicts claimSurface the conflict immediately. "You said the system does X, but the code path I see does Y. Which is canonical?" Pause until resolved.
Grep returns nothingNote as unverified; ask user for the file/function name; do not record in CONTEXT.md until verified

This gate prevents the agent from silently transcribing user-asserted behavior that contradicts code — a common source of "the docs say X but the code does Y" drift.

Step 3 — Hidden Requirement Discovery

After the 5 questions, analyze for requirements the user DIDN'T mention:

Technical hidden requirements:

  • Authentication/authorization needed?
  • Rate limiting needed?
  • Data persistence needed? (what DB, what schema)
  • Error handling strategy?
  • Offline/fallback behavior?
  • Mobile responsiveness?
  • Accessibility requirements?
  • Internationalization?

Business hidden requirements:

  • What happens on failure? (graceful degradation)
  • What data needs to be tracked? (analytics events)
  • Who else is affected? (other teams, other systems)
  • What are the edge cases? (empty state, max limits, concurrent access)
  • Regulatory/compliance needs? (GDPR, PCI, HIPAA)

Present discovered hidden requirements to user: "I found N additional requirements you may not have considered: [list]. Which are relevant?"

Step 3.5 — Completeness Scoring (Options & Alternatives)

When presenting options, alternatives, or scope decisions to the user, rate each with a Completeness score (X/10):

ScoreMeaningGuidance
9-10Complete — all edge cases, full coverage, production-readyAlways recommend
7-8Covers happy path, skips some edgesAcceptable for MVP
4-6Shortcut — defers significant work to laterFlag trade-off explicitly
1-3Minimal viable, technical debt guaranteedOnly for time-critical emergencies

Always recommend the higher-completeness option unless the delta is truly expensive. With AI-assisted coding, the marginal cost of completeness is near-zero:

Task TypeHuman TeamAI-AssistedCompression
Boilerplate / scaffolding2 days15 min~100x
Test writing1 day15 min~50x
Feature implementation1 week30 min~30x
Bug fix + regression test4 hours15 min~20x

When showing effort estimates, always show both scales: (human: ~X / AI: ~Y). The compression ratio reframes "too expensive" into "15 minutes more."

Anti-pattern: "Choose B — it covers 90% of the value with less code." → If A is only 70 lines more, choose A. The last 10% is where production bugs hide.

Step 3.6 — Logic Consistency Check

After ambiguity + completeness pass, scan for cross-dimension contradictions. Ambiguity measures CLARITY of each dimension in isolation; this step measures CONSISTENCY across dimensions. A perfectly clear requirement can still contradict itself.

Checks

Run each, label verdict 🟢 pass / 🟡 warn / 🔴 fail:

#Check🔴 Fail🟢 Pass
1Every Acceptance Criterion traces to a User StoryAC orphaned1:N mapping clear
1bEvery EARS FR-n (Step 4.5) traces up to a User Story AND down to an ACFR has no AC (untested promise) or no story (orphan behavior)FR → story + AC both present
2Every Business Rule (Q5) is enforced in an AC or Exception FlowRule has no enforcement pathRule → specific AC or exception
3Scope IN ∩ Scope OUT = ∅Direct overlap in phrasingSets disjoint
4Every user-story flow has a terminal stateState loop without exit conditionTerminal state explicit
5Dependencies (Step 4) ⊂ Constraints acknowledged (Q5)Dependency never mentioned in constraintsAll deps covered
6NFRs measurable against at least one ACNFR has no test hookEvery NFR → testable AC
7Hidden requirements (Step 3) resolved in/outSilent inclusionUser confirmed inclusion or exclusion
0Prior rejection check (Step 1.5) — exact-match resolved with explicit override or session endedSilent re-litigation of rejected conceptUser chose: override (priority bumped) OR accept prior decision (session ends)
Output Format
Logic Consistency Report:
  1. AC → User Story:      🟢 all AC trace to US-1 or US-2
  1b. EARS FR → story+AC:  🟢 FR-1..FR-5 each map to a story and an AC
  2. Business rule → AC:   🟡 "no duplicate emails" cited — exception flow missing
  3. Scope disjoint:       🟢
  4. Terminal states:      🟢
  5. Deps in constraints:  🔴 "PostgreSQL 15" missing from Q5 answer
  6. NFR measurable:       🟢
  7. Hidden reqs resolved: 🟢

Verdict: 1 🔴, 1 🟡, 5 🟢 → BLOCK handoff until 🔴 fixed
Gate Rule
ResultAction
0 🔴Proceed to Step 4 — 🟡 warnings become "Risks" in Requirements Doc
1-2 🔴BLOCK — ask targeted question or re-scope to resolve each 🔴
3+ 🔴Scrap Steps 2-3 and restart — requirements structurally incoherent

Step 4 — Scope Definition

Based on all gathered information, produce:

In-Scope (explicitly included):

  • [list of features/behaviors that WILL be built]

Out-of-Scope (explicitly excluded):

  • [list of things we WON'T build — prevents scope creep]

Assumptions (things we're assuming without proof):

  • [each assumption is a risk if wrong]

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
86
Forks
26
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
ba
Source
github.com/rune-kit/rune