| name | request-discovery |
| description | Find untracked feature requests or latent product gaps in Intercom, validate against codebase and PostHog, produce a full Shortcut card |
| disable-model-invocation | true |
Request Discovery
Find a recurring feature request or latent product gap in Intercom that isn't
already tracked in Shortcut, validate it against the codebase and PostHog, and
produce a full card in Backlog.
Two discovery modes share the same validation and card-building phases:
- Explicit requests (Play 4): users asking for something by name. Topic
noun keyword search. "RSS", "carousel", "hashtag", "undo."
- Latent gaps (Play 4a): users bumping into friction they don't name as a
request. Complaints, confusion, cancellation reasons, expectation mismatches.
The SC-531 investigation (Turbo pin selection) is the reference run.
Arguments
$ARGUMENTS determines the mode:
{topic keyword} (default): Explicit request mode. Search Intercom for
the named topic. Run the full protocol below.
--latent {product-area}: Latent gap mode. Scope to the named product
area and run a multi-angle friction scan via subagent. Product area is
required — broad scans across the whole product are too noisy.
Also Read
Before starting, read these shared sections from box/shortcut-ops.md:
- Pre-flight Steps: index refresh, token checks, DB connectivity
- Story Template: card format for drafting
- Card Quality Gate: the four criteria checked before presenting
- Verification Bar: factual accuracy checks
- Intercom Search Patterns: search syntax and patterns
- General Constraints: mutation cap, rate limiting
Constraints
- Mutation gate: A PreToolUse hook blocks all Slack and Shortcut mutations
through Bash. Route through
agenterminal.execute_approved or present the
command for the user to run.
- Human-in-the-loop: Present one card at a time with full content rendered.
Wait for Paul's decision. Don't batch-execute without review.
- Context protection: Delegate codebase exploration and high-volume Intercom
filtering to subagents. Primary context is for targeted verification and
synthesis, not broad exploration.
- Before Shortcut API calls: check
reference/tooling-logistics.md for
tested recipes. Don't re-derive payload shapes or endpoint paths.
Validity Criteria
A candidate must meet all three before proceeding to validation:
- 3+ distinct users clearly asking for / experiencing the same thing
- Recency: at least one conversation in the past 30 days (explicit mode)
or 60 days (latent mode — friction signals accumulate slower than explicit
requests). Use the Intercom API for recency verification, not the local DB
(import lag means the DB may be stale)
- Not already tracked in Shortcut (search by topic keyword)
Steps
1. Find the signal
Explicit request mode ({topic keyword})
- Refresh the Intercom search index (pre-flight step 6).
- Search the local index for the topic keyword:
python3 box/intercom-search.py "topic keyword"
This searches all conversation parts including admin replies, not just
opening messages. Fall back to the Intercom API source.body search for
opening-message-only queries when needed.
For core product topics (scheduling, publishing, boards): bare keywords
return support noise. Lead with DB queries for unmet-need language instead
(full_text ILIKE '%don''t currently%', '%not possible%',
'%not available%feature%' scoped to the topic). These surface conversations
where support confirmed a gap.
- Check hit counts to gauge volume. Filter out spam-heavy topics.
Keyword fitness check after first results. If the top results are
overwhelmingly complaints/bugs rather than feature requests, the keyword
is a symptom word ("slow", "broken"), not a feature noun ("RSS",
"carousel"). Symptom keywords map to many root causes, most of which are
bugs. Surface this to the user: "This keyword maps to complaints, not
requests. Options: try a different noun, switch to latent mode, or keep
going knowing the signal will be indirect." Don't run 20+ keyword
permutations trying to force a feature request out of a symptom keyword.
Proved 2026-04-02: "slow" -> 7,413 hits, all performance complaints.
- Search Shortcut to confirm not already tracked:
python3 box/shortcut-cards.py --query 'title:"topic keyword"' --summary
A title match is a candidate, not confirmation. If the search returns
results, read the matched card (shortcut-cards.py --id) and verify the
card's scope actually covers the discovered request. Title keyword overlap
between different-scope features ("language filter" in Keywords vs
Extension) silently kills valid discoveries. Proved 2026-04-23 in
sweep-channels (SC-245 keyword match) and 2026-04-29 (mechanism
assumption without card read).
- DB can validate volume (
GROUP BY issue_signature, COUNT DISTINCT contact_email) but is bad for discovery. Most themes are bugs, not
feature requests.
Latent gap mode (--latent {product-area})
- Refresh the Intercom search index (pre-flight step 6).
- Delegate a multi-angle Intercom scan to a subagent. Search angles should
include:
- Disappointment / unmet expectations
- "doesn't / can't / won't" language
- Cancellation / downgrade reasons
- Frustration / confusion
- Quality complaints
The subagent reads conversations and returns theme groups with conversation
IDs and one-line summaries.
- Filter subagent themes against the Shortcut backlog. For each theme,
search by title keyword; if a match comes back, read the card and verify
scope alignment before dropping. A title match is a candidate for
"already tracked," not confirmation. Drop themes that are pure bugs
(Play 5 /
/bug-discovery territory) unless the bug reveals a product
gap.
- Present untracked themes to the user and wait for selection.
Clustering is analysis; choosing which cluster to pursue is a product
judgment call. Show each theme with conversation count, recency, and a
one-line summary. Do not proceed to Step 2 until the user picks a theme.
Proved 2026-03-30: agent selected Resonance theme autonomously, ran 13
turns of validation, human collapsed the framing in one sentence.
2. Validate
Same protocol for both modes:
- Read 8-12 actual Intercom conversations to confirm users are asking for /
experiencing the same thing. Record conversation IDs and verbatim quotes:
python3 box/intercom-search.py --read ID1,ID2,ID3
Search snippets are not evidence. Read the actual conversation text
before citing it.
- Verify at least one conversation meets the recency threshold (30 days for
explicit, 60 days for latent).
- Delegate a codebase exploration using
agenterminal.delegate with the
verified explore prompt (box/verified-explore-prompt.md). The subagent
returns a structured file manifest. Read the listed files yourself.
- Query PostHog for usage context: how many people use the adjacent feature
surface, country breakdown if relevant, comparison benchmarks. Check
box/posthog-events.md for known event names before querying.
- Before writing the card, ask: "Is this a new feature or an extension of an
existing one?" Frame as extension when possible. Identify the closest
existing feature surface and build from there.
3. Build the card
- Use the Story Template. All sections required for feature cards.
Architecture Context is included when there are meaningful findings.
- Run the Card Quality Gate and Verification Bar before presenting.
Every code path, file name, property name, and number on the card must be
verified against primary sources. This is the step that gets skipped under
completion momentum.
- Present the completed checklist inline, then present the card description
via
approve_content with content_type: "card-draft",
filename: "scNNN".
4. Ship (after approval)
- Submit via
agenterminal.execute_approved:
python3 box/shortcut-ship.py SC-NNN <saved_path>
The script executes the PUT (update description, move to Backlog,
unassign owners), re-fetches the card, and verifies inline (state, owners,
section headers, description length). Exit 0 = verified, 1 = verification
failed, 2 = mutation failed.
- If any new PostHog event names were discovered during investigation, add
them to the appropriate section in
box/posthog-events.md.