Strategic meeting prep with coaching frameworks, table-format cards, and outcome-driven game plan — rendered as self-contained HTML. Use when user says "meeting prep", "battle plan", "prep me for my meeting", "prep for my call", or wants a coached game plan for an upcoming meeting. Do NOT use for account reference documents — use /octave-research instead.
Strategic meeting prep with coaching frameworks, table-format cards, and outcome-driven game plan — rendered as self-contained HTML. Use when user says "meeting prep", "battle plan", "prep me for my meeting", "prep for my call", or wants a coached game plan for an upcoming meeting. Do NOT use for account reference documents — use /octave-research instead.
/octave-meeting-prep - Strategic Meeting Prep
Build a coached, strategic meeting prep rendered as a self-contained HTML document. Unlike /octave-research (a reference dossier), this skill produces a prep document — combining intelligence with coaching frameworks to generate table-format cards for pains, beliefs, objections, and themes, each with adaptive action guidance, discovery questions, and response points tied to deal-specific status.
Read references/output-rules.md and the shared rules it points to (../shared/editorial-rules.md, ../shared/information-principles.md, ../shared/presentation-principles.md) before generating any output. Every rule is mandatory.
If a user replaces the coaching files with their own frameworks, the skill adapts automatically.
Key differentiators:
vs — brief is a reference dossier; meeting-prep is a coached prep with table-cards and outcome-driven goals
/octave-research
vs /octave-research — research outputs plain text; meeting-prep renders a styled HTML document with coaching intelligence
vs /octave-deck — deck is a slide presentation for the audience; meeting-prep is internal prep for the seller
Principles
Follow these standards during generation. Read each before producing output.
Content and language:
Editorial rules — no AI-isms, banned vocabulary, honest analyst tone
Octave value — prioritize grounded workspace data over generic AI content
Apply these rules during generation, not just at review. After generating, the review pipeline is a mandatory gate (see Step 5) — the prep is not opened or delivered until the scorecard is produced.
Email address -> Person-targeted prep (enrich person + company)
Domain -> Company-targeted prep (enrich company + find key contacts)
LinkedIn URL -> Person-targeted prep
Meeting description -> Extract company/people from context
1.2 Detect or ask meeting type:
If --type not specified, infer from context or ask:
What type of meeting are you prepping for?
1. Discovery — First conversation, qualifying the opportunity
2. Demo — Showing the product, proving value
3. Follow-up — Continuing a conversation, advancing the deal
4. Executive — High-level strategic conversation
5. QBR — Quarterly business review with existing customer
6. General — Balanced prep (default)
Your choice:
1.3 Ask meeting duration:
The duration is displayed as context in the header — it does NOT drive a minute-by-minute timeline.
How long is this meeting?
1. 30 minutes
2. 45 minutes
3. 60 minutes
4. 90 minutes
Your choice:
1.4 Collect user context:
Ask if the user has any prior context to incorporate:
Do you have any prior context to fold in?
1. Call transcript or recording notes
2. Email thread or meeting notes
3. My own notes / talking points
4. No prior context — use available intel + coaching frameworks
Your choice (or press Enter to skip):
If the user provides a transcript, notes, or email thread, synthesize that context alongside enrichment data. If they skip, proceed with available intelligence and coaching frameworks only.
1.5 Identify attendees:
Who's attending? (names, titles, emails — or "I don't know yet")
If attendees are unknown, build a general stakeholder map from available contacts.
Every name volunteered here (typed by the user, pulled from a CRM field, or mentioned in a transcript) is a claim, not a fact. It gets verified in Step 2 before it can be named in the output; see "Verify every external person before naming them" below. Names that survive that check are stated as fact, names that don't are marked .unconfirmed. The deal owner / your own AE is the one exception (see the same section for why).
1.6 Read reference files:
Read the three reference files from the skill directory:
references/positioning-coach.md — Extract: positioned sales pitch (5 steps), feature->value->emotion, competitive alternatives, category framing, language mining, heads on pillows test
references/output-rules.md (plus the shared editorial/information/presentation rules it points to) — Extract: all output formatting rules. These are mandatory for the generation step.
If the coaching files are not found, fall back to general sales coaching best practices. If the presentation principles file is not found, apply the rules from memory — they are embedded in these instructions as well.
Step 2: Context Gathering
Based on the target and meeting type, use Octave MCP tools to build a complete intelligence picture. Tell the user what you're researching and why.
Call as many tools as needed to build a thorough prep. The best meeting preps layer multiple sources — company enrichment + person enrichment + playbook messaging + proof points + conversation intel + coaching frameworks all combine to create a document grounded in real data. Don't stop at one tool when several would give you a stronger prep.
Not every tool applies to every meeting. Use your judgment about which are relevant to this specific situation. The tables below show what's available — pick the combination that gives you the richest context for the meeting type and target.
List vs Search — when to use which:
Tool
Purpose
Use when...
list_entities({ entityType })
Fetch all entities of a type (minimal fields)
You want a quick inventory — "show me all our competitors"
list_entities({ entityType })
Fetch entities with full data (paginated)
You need the actual content — "get full proof point details"
get_entity({ oId })
Deep dive on one specific entity
You found something relevant and need the complete picture
search_knowledge_base({ query })
Semantic search across library + resources
You have a concept or question — "how do we position for healthcare?"
list_resources() / search_resources({ query })
Uploaded docs, URLs, Google Drive files
You need reference material, uploaded assets, or source docs
Rule of thumb: Use list_* when you know what type of thing you want. Use search_* when you know what topic you're looking for.
Findings and events — always attempt, gracefully skip:
ALWAYS try to pull findings and events if you have a company domain or contact emails. Use a 90-day window. If data exists, it feeds into the Situation section (deal context) and informs context card statuses. If not, silently omit — no error message.
list_findings({ query: "<company or contact>", startDate: "<90 days ago>" }) — surfaces what was actually said in calls: objections raised, features requested, pain points confirmed, competitor mentions
get_event_detail({ eventOId }) — deep dive on specific past interactions
Verify every external person before naming them. This skill names people in the header, the Deal Snapshot Bar, and the People card group: that's exactly the surface where a fabricated contact can slip into a live meeting doc. Before any attendee or stakeholder appears in the output as a real person, confirm them against an actual tool result:
Have an email? Call resolve_profile_from_email({ email }) first.
Have a name and company but no email? Call find_person({ searchMode: "people", companyDomain, fuzzyTitles }) to locate them, then enrich_person({ person: { ... } }) to confirm the profile and pull the correct title.
A name that only came from the user's prompt, a CRM field, or a transcript is a lead, not a confirmed person. Run it through one of the above before it can be stated as fact. If the tool returns no match, or the match is ambiguous (wrong company, stale title, multiple candidates), the person stays unconfirmed: do not guess and do not silently keep the unverified version.
Once confirmed, use the tool's data for the name and title, not whatever version was originally supplied. If a title changed, use the confirmed one.
For internal docs (this skill is seller-facing, never customer-facing), you may link a confirmed person's real profile. See the entity-linking note near the People section below.
Any person who fails verification is not dropped from the doc. Mark them explicitly with the .unconfirmed tag (defined in the People section and the CSS below) instead of stating them as settled fact. This verification requirement applies only to external stakeholders and attendees at the target company. The deal owner / your own AE is handled differently; see "Internal vs. external" under the People section.
For Person-Targeted Preps
Start with person and company enrichment, then pull positioning context:
What you need
Tool
When to use
Person verify + deep-dive
resolve_profile_from_email({ email }) if you have an email, else enrich_person({ person: { email, firstName, lastName, companyDomain } })
Always for person-targeted preps: this IS the verification step for the named target, and gives background, role, priorities
S2 Positioning Directive, S3 Persona message shifts
ICP narrative value props
find_motion_icp({ motionIcpOId, includeElements: true }) — use benefitsAndImpacts + strategicNarrative
S3 Persona use case hooks
Objection entities
list_entities({ entityType: "objection" })
S4 Objection cards with theme grouping + persona tags
Conditional richness: These pulls enrich the prep when data exists. When data is thin:
Persona message shifts: show only personas with strong data, omit thin ones
Competitive position: if no competitor entities, keep single Competition row in Deal Context and note "No confirmed competitors"
Objection entities: if none in library, synthesize from deal context and coaching frameworks
Output of this step: Present a content outline to the user for approval before generating:
MEETING PREP OUTLINE: [Company/Person] — [Meeting Type]
========================================================
Target: [Company name / Person name at Company]
Meeting Type: [Discovery / Demo / Follow-up / Executive / QBR / General]
Duration: [30 / 45 / 60 / 90] minutes
Attendees: [Names and roles, or "Roles to find"]
Style: [Will be selected in Step 3]
---
SECTIONS
--------
Header — "Meeting Prep: [Company]", meeting type badge, duration badge, expand/collapse toggle, one-sentence context
Deal Snapshot Bar — Deal Value | Stage | Target Close | Primary Contact
1. Context
- Company context (card group: logo, grid with what they do, scale, fit reasoning, signals, angle)
- People (card group: persona groups with pressure + why [product], 2-3 rows per card)
- Deal context (card group: grid with stage, activity, competition, champion, compelling event, buying triggers)
2. Goals
- Positioning directive (structured: position us as / mitigate / advance)
- What we need them to recognize (card group: [N] table-cards with context, status, planting guidance, "watch out" row, discovery questions)
3. What to Say & Ask
- How our message lands by persona (tabbed: pressure, story shift, hook line, use case, "don't lead with")
- Competitive position (card group: [N] table-cards with their positioning, our counter, trap question)
- Pains we know they have (card group: [N] table-cards with context, status, probe guidance, "watch out" row, discovery questions)
- Themes to steer (card group: [N] table-cards with relevance, status, steering guidance)
4. Objections
- Theme tabs (Status Quo & Inertia, Technical & Integration, Competitive, etc.)
- [N] objection table-cards with persona tags, "you'll hear", response, "watch out"
5. The Takeaway
- One sentence
Intelligence Sources:
- Company: [key insights]
- Person: [persona match]
- Playbook: [strategic angle]
- Proof points: [N] pulled
- Recent signals: [N] found (or "none — skipped")
- Competitive: [if applicable]
- User context: [transcript / notes / none]
---
Does this look good? I can:
1. Proceed to style selection and generation
2. Add or remove sub-sections
3. Go deeper on any area
4. Change the meeting type or emphasis
Wait for user approval before proceeding.
Step 3: Style Selection
Resolve the brand before generating (do not skip this step). The document brand should be the workspace company's brand — that is, the Octave customer whose workspace you are operating in. The target company's logo (the prospect) should appear in content sections (1-2 places) but does not control the document's design system.
Step 1: Identify the workspace company. Call get_workspace_company to get the company name, domain/URL, and positioning. This is the company whose brand the document should use (whatever get_workspace_company returns is the brand, not the target account).
Step 2: Resolve the workspace company's brand kit. Slugify the workspace company name and check for a cached brand kit at ~/.octave/brands/<slug>/manifest.json. If a complete kit exists (has manifest.json and tokens.css), use it automatically for the document's design system (header, footer, colors, fonts, :root variables).
If no complete kit exists → build one. Run the get-brand-components skill (read ../../skills/get-brand-components/SKILL.md and follow it) for the workspace company's domain. If the first attempt returns incomplete results (no logo, no colors, partial data) → retry up to 3 times with different approaches (root domain, www. prefix, /about subpage). Only fall back to a generic preset after 3 genuine failures.
Step 3: Fetch the target company's logo. Use get_external_brand_logo or get_external_brand_assets to get the target company's logo. Place it in the company context section (and optionally one other location like a deal context card). Do not use it for the document header/footer — those use the workspace company's brand.
If the first attempt returns no logo → retry up to 3 times.
⚠️ STRONG DEFAULT: The document is always branded as the workspace company (the Octave customer). The prospect's logo appears in content to personalize the document, but the overall look and feel — fonts, colors, header, footer — is the workspace company's brand.
Read your brand kit's tokens.css and manifest.json to populate the :root variables using the token mapping table below.
MANDATORY: Add the brand header and brand footer. Read the workspace company's brand kit logo SVG file, inline it into the <header class="brand-header"> and <footer class="brand-footer"> templates documented in the "Brand Header & Footer" section below. This is NOT optional — every meeting prep MUST have the branded header and footer using the workspace company's logo.
Skip the style preset menu when a brand kit is applied.
Only use a generic preset if your brand kit is unavailable (e.g., no kit cached and generation fails). The prep uses the same CSS variable / style preset system as /octave-deck as a fallback. Full preset definitions are in the shared style-presets.md.
Preps default to readability-optimized presets. If --style was not provided, ask:
Pick a style for your meeting prep:
1. midnight-pro — Dark navy, white text, blue accents (default)
2. paper-minimal — Off-white, black type, editorial simplicity
3. executive-dark — Charcoal + gold, premium boardroom aesthetic
4. soft-light — Warm white + sage green, calm and approachable
5. swiss-modern — White + red accent, Bauhaus minimal
6. Use my brand — Extract from website or provide colors
7. Match my deck — Use the same style as an existing /octave-deck
Your choice (or press Enter for default):
Meeting Type
Recommended Default
Discovery
midnight-pro
Demo
midnight-pro
Follow-up
midnight-pro
Executive
executive-dark
QBR
executive-dark
General
midnight-pro
If the user selects "Use my brand," check for an existing brand kit first (~/.octave/brands/<slug>/). If none exists, offer to run /octave-get-brand-components <domain> to build one, or fall back to the brand discovery flow from the deck skill. If they select "Match my deck," ask for the deck file path and extract its CSS variables.
Step 4: Generate HTML
Before generating, re-read references/output-rules.md and the shared rules it points to, and apply every rule.
Build a single self-contained HTML file. The prep is a scrollable reference document — not a slide deck. Natural page scroll, sticky sidebar navigation, collapsible sections, and a print-friendly layout.
The document uses a three-level collapsible hierarchy with smart defaults:
Sections (details.prep-section): open by default — user sees all five sections expanded on load
Card groups (details.card-group): open by default — user sees all group headers and their card titles
Individual cards (details.table-card): CLOSED by default — user sees card titles as a scannable list, one click to expand any card
This means on page load, the user gets a scannable overview of every pain, belief, objection, theme, and risk by title alone, without being overwhelmed by detail. Heavy content (context grids, discovery questions, response lists) is one click away on any individual card.
Sub-sections in Section 1 (Company Context, People, Deal Context) are also details.card-group elements, open by default.
Design System: Table-Format Cards
Every individual card (pain, belief, objection, theme, risk) uses the same table-card pattern:
<detailsclass="table-card"><summary>Card title here</summary><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">Label</div><divclass="cg-value">Value content</div></div><!-- more rows --></div></details>
The card is a collapsible <details class="table-card"> element. The title sits in the <summary>. The body is a .context-grid with .cg-row elements (label | value pairs). Row labels vary by card type:
Card Type
Row Labels
Pain
Context, Status, How to probe, Watch out
Belief / Recognition
Context, Status, How to plant, Watch out
Persona Message (Sec 3 tabs)
Pressure, Our story shifts to, Say this, Use case, Don't lead with
Competitive
Their positioning, Our counter, Trap question
Objection
You'll hear, Response (with .response-list), Watch out
Theme
Why it matters, Status, How to steer
There are NO color-coded left borders, NO data-type attributes, NO .context-card class. The card type is communicated by the card group header it sits under.
Design System: Card Groups
Cards are organized under collapsible <details class="card-group" open> headers. Each card group has a .card-group-intro paragraph explaining the group's purpose. The group header communicates the card type — no legends needed.
Section 3: "How Our Message Lands by Persona", "Competitive Position", "Pains We Know They Have", "Themes to Steer"
Section 4: Objection table-cards organized under theme tabs
There are NO .cc-legend, NO .legend-swatch, NO .legend-divider, NO .legend-types, NO .legend-statuses elements anywhere.
<detailsclass="card-group"open><summary>Pains We Know They Have</summary><pclass="card-group-intro">Based on [scale / ICP match / signal], they're experiencing these problems. Our posture is confident — these are structural, not hypothetical.</p><detailsclass="table-card"><summary>Pain title here</summary><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">Context</div><divclass="cg-value">Why we know this pain exists — grounded in their scale, product complexity, org structure</div></div><divclass="cg-row"><divclass="cg-label">Status</div><divclass="cg-value"><spanclass="cc-status unexplored">Unexplored</span></div></div><divclass="cg-row"><divclass="cg-label">How to probe</div><divclass="cg-value">How to surface this pain without naming it for them</div></div><divclass="cg-row"><divclass="cg-label">Watch out</div><divclass="cg-value cg-watchout">What NOT to say when probing this pain</div></div></div><detailsclass="cc-questions"><summary>2 discovery questions</summary><divclass="cc-q-grid"><divclass="cc-q-header">Ask about</div><divclass="cc-q-header">Driving toward</div><divclass="cc-q-row"><divclass="cc-q-cell">Topic to probe</div><divclass="cc-q-cell">What the answer reveals</div></div></div></details></details><!-- more table-cards --></details>
Design System: Expand/Collapse All Toggle
A button in the header badge row allows expanding or collapsing all <details> elements:
<buttonclass="expand-toggle"id="expand-toggle"onclick="toggleAll()"><spanclass="toggle-icon">▼</span> Expand all
</button>
JavaScript toggles all <details> elements open/closed and flips the label between "Expand all" and "Collapse all".
Design System: Company Identity with Logo
Inside the Company Context card group (after the <summary> and before the .context-grid), include a company identity block:
Use the get_external_brand_logo MCP tool to fetch the logo URL at generation time. If no logo is found, omit the <img> tag and just show the company name in the <span>.
Design System: Status Tags
Status tags appear inside table-card rows as .cc-status pills. Available statuses:
Status
Used for
Style
Unexplored
Pains/beliefs not yet raised
Warning (amber)
Raised
Pains/beliefs mentioned but unconfirmed
Brand primary (blue)
Validated
Confirmed from prior calls/data
Success (green)
Needs Reinforcement
Was validated but may be fading
Secondary (purple)
Expected
Objections/themes anticipated
Warning (amber)
Status grounding rule — evidence required.
Status must reflect what you actually know about this specific prospect, not generic product confidence. Apply these defaults:
No prior conversation data, no deal history, no confirmed signals → everything is Unexplored (for pains/beliefs not yet discussed) or Expected (for anticipated objections/themes). Nothing is Validated or Raised.
Findings or deal events exist but don't confirm this specific belief → still Unexplored. Don't upgrade a status just because the prospect is in-pipeline.
Raised requires evidence that this pain or belief was explicitly mentioned by the prospect (from findings, call notes, or user-provided context).
Validated requires confirmed evidence — the prospect agreed, data backs it up, or prior calls explicitly confirmed the point.
Needs Reinforcement requires that something was once validated but signals suggest it's fading (e.g., champion went quiet, deal stalled).
Note:.cc-status tags above track evidence for pains, beliefs, objections, and themes. People get a separate tag, .unconfirmed, for when a stakeholder's identity or title couldn't be verified against a real tool result; see the People card group and its CSS definition further down.
The belief stack is a coaching tool — its value comes from showing the seller where the gaps are. Marking everything "Validated" with no evidence defeats the purpose. When in doubt, default to Unexplored and flag it as a meeting priority.
Status tags sit inside a .cg-value cell within the Status row of a table-card. They do NOT float as standalone badges.
Design System: Discovery Questions Position
Quality bar — every discovery question must clear this:
L2 or L3 only. L1 diagnostic questions ("Walk me through how you handle X") are table stakes. L2 forces a binary choice that advances the deal regardless of answer. L3 surfaces the business cost of the status quo.
Octave-grounded. The question must be built from specific intelligence only available through Octave (deal pipeline data, enrichment signals, competitive intel, prior findings). If someone could write the question after Googling the company for 5 minutes, cut it.
3-4 questions maximum across the entire document. Distribute across pain and recognition cards. Fewer and sharper beats many and generic.
Discovery questions are placed OUTSIDE the .context-grid, as a direct child of the <details class="table-card">:
This positions the expand trigger on the left side of the card, not buried inside a grid cell.
Design System: Response Lists for Objections
Objection cards use a .response-list inside the "Response" row value cell:
<divclass="cg-row"><divclass="cg-label">Response</div><divclass="cg-value"><ulclass="response-list"><li>First response point</li><li>Second response point with <strong>emphasis</strong></li><li>Third response point</li></ul></div></div>
Each <li> gets an arrow marker (->) via CSS ::before pseudo-element. Use <strong> for key phrases within response points.
Design System: No Hardcoded Brand
The :root CSS variables are populated from the style preset selected in Step 3 OR from a brand kit. The HTML template uses generic variable references (var(--bg), var(--brand-primary), etc.), never specific hex values. Do not hardcode any specific brand or color scheme into the template.
When using a brand kit (~/.octave/brands/<slug>/tokens.css), map the kit tokens to the meeting prep's :root variables:
Meeting Prep Var
Brand Kit Source
--bg
--brand-bg-primary
--bg-elevated
--brand-bg-tint
--bg-card
--brand-bg-secondary
--bg-panel
--brand-bg-panel
--text-primary
--brand-fg-primary
--text-secondary
--brand-gray-60 or mid-tone gray
--text-muted
--brand-fg-muted
--brand-primary
--brand-accent
--brand-primary-soft
--brand-state-info-weak or 12% alpha of accent
--secondary
--brand-accent-hover
--border
--brand-border-primary
--border-strong
--brand-border-secondary
--font-display / --font-body
--brand-font-sans
--font-mono
--brand-font-mono
Also use the kit's @font-face declaration (pointing to the CDN or local font file), heading weight (often 600, not 700), and letter-spacing for headings.
⚠️ REQUIRED: When using a brand kit, you MUST include the brand header and brand footer. See the "Brand Header & Footer" section below for the templates. Read the logo SVG from the kit directory and inline it. When using a generic style preset, omit the brand header/footer.
Header (not a numbered section — the document frame)
The header answers three questions: What is this? Who is it about? What's the context?
<headerclass="prep-header"><divclass="header-badges"><spanclass="meeting-badge">[Meeting Type]</span><spanclass="duration-badge">[Duration] min</span><buttonclass="expand-toggle"id="expand-toggle"onclick="toggleAll()"><spanclass="toggle-icon">▼</span> Expand all
</button></div><h1>Meeting Prep: [Company Name]</h1><pclass="header-subtitle">[One sentence describing the meeting context]</p><pclass="header-meta">[Date] · Prepared for/by [Your name, title] · [Attendee names or "Attendees TBD"]</p></header>
Rules:
Title format: "Meeting Prep: [Company]" — not just the company name, not "Battle Plan"
Meeting type badge: "Discovery Call", "Demo", "Executive Meeting" — plain language, not "Discovery Battle Plan"
Duration badge: just the number + "min"
Expand/collapse toggle button sits in the badge row
Subtitle: one sentence describing the meeting and its purpose — NO deal stats, NO tool names
No branding, no "powered by" text, no "Stream B", no "Octave intelligence"
Prepared for/by: the deal owner (your own AE, the person this doc is prepared for/by) resolves to the workspace company's own domain. Get it from get_workspace_company or the CRM record's owner field, and state it as fact in the header. It is never run through the external-stakeholder verification step and never gets an .unconfirmed tag, since it isn't a prospect claim, it's the seller's own identity. External attendees go in the "Attendee names" portion of the same line and in the People card group, and are subject to verification.
Brand Header & Footer (REQUIRED when a brand kit is active)
⚠️ This is mandatory, not optional. When the meeting prep is styled from a brand kit, you MUST add a sticky brand header at the top and a brand footer at the bottom. These frame the document in the brand's identity. Read the logo SVG from ~/.octave/brands/<slug>/ (e.g. <slug>-logo.svg) and inline it into both the header and footer. Omit these only when using a generic style preset.
<!-- Brand Header — sticky, frosted glass blur --><headerclass="brand-header"><divclass="brand-header-inner"><aclass="brand-header-logo"href="https://[domain]"target="_blank"><!-- Inline the brand's real SVG logo from the kit --><svg>...</svg><span>[Company Name]</span></a><divclass="brand-header-right"><spanclass="brand-header-tag">Meeting Prep</span></div></div></header>
<!-- Brand Footer — at the very end, before </body> --><footerclass="brand-footer"><divclass="brand-footer-inner"><divclass="brand-footer-logo"><!-- Same logo, smaller --><svg>...</svg><span>[Company Name]</span></div><divclass="brand-footer-meta">Prepared [Date]</div></div></footer>
Rules:
Logo: inline the real SVG from the brand kit (<slug>-logo.svg), never hotlink. Use fill="currentColor" so it inherits the text color.
Header is sticky with backdrop-filter: blur(12px) for the frosted glass effect on scroll.
Footer shows the date the prep was generated.
Both hidden in @media print.
The header tag says "Meeting Prep" — not the company name again, not "Powered by Octave."
Deal Snapshot Bar (directly under header)
A labeled key-value grid showing CRM fields at a glance. Every value has a label.
If a field is unknown, display "Unknown" or "TBD" — never omit the label
These are the ONE canonical location for deal stats — do not repeat them elsewhere
If no deal exists yet (net-new prospect), show what's known and label unknowns
Primary Contact is a named person and follows the same verification rule as everyone in the People section: confirm via resolve_profile_from_email / enrich_person / find_person before stating a name and title here. If the CRM's listed contact can't be confirmed, show the name with (unconfirmed) in the snapshot value rather than presenting it as settled fact
Section 1: Context
What the seller needs to know about the account, the people, and the deal before the call.
One-line intro at the top of the section: "Everything you need to know about the account, the people, and the deal going into this call."
Sub-components are organized as card groups (details.card-group open by default):
Company Context — a card group containing a company identity block and a .context-grid with .cg-row elements.
<detailsclass="card-group"open><summary>Company Context</summary><divclass="company-identity"><imgsrc="[logo_url]"alt="[Company]"class="company-logo"><spanclass="company-name">[Company]</span></div><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">What they do</div><divclass="cg-value">[1 sentence description]</div></div><divclass="cg-row"><divclass="cg-label">Scale</div><divclass="cg-value">[Employee count, revenue, funding — whatever's known]</div></div><divclass="cg-row"><divclass="cg-label">Why they're a fit</div><divclass="cg-value">[Fit reasoning with persona/segment match]</div></div><divclass="cg-row"><divclass="cg-label">Key signal</div><divclass="cg-value">[Funding, hiring, tech stack changes, trigger events]</div></div><divclass="cg-row"><divclass="cg-label">Angle</div><divclass="cg-value">[The strategic angle for this conversation]</div></div></div></details>
5-7 grid rows maximum. Add rows as needed (e.g., "Industry", "Tech stack") but keep it tight.
What's Happening Now(conditional — include only when deep research was run) — a card group placed immediately after Company Context. It surfaces the macro themes and recent signals that a rep would otherwise Google for themselves.
This section has two components:
Macro Themes — 1-2 big-picture strategic themes for the company this year (e.g., "Preparing for IPO", "First international expansion", "Pivoting to platform model"). These come from deep web research and should be company-level strategic narratives, not product news.
Signal Feed — 3-5 recent, concrete signals: news, hires, launches, funding, partnerships, regulatory moves. Each signal gets a date (or approximate timeframe) and a one-line "why it matters" tied to the deal angle.
<detailsclass="card-group"open><summary>What's Happening Now</summary><pclass="card-group-intro">Macro themes and recent signals from deep research — what a rep would find googling [Company] right now.</p><divclass="macro-themes"><divclass="macro-theme"><divclass="mt-title">[Theme title — e.g., "Path to IPO"]</div><divclass="mt-body">[2-3 sentences: what's happening, why it matters for this deal, how to reference it naturally]</div></div><divclass="macro-theme"><divclass="mt-title">[Second theme]</div><divclass="mt-body">[2-3 sentences]</div></div></div><divclass="signal-feed"><divclass="signal-item"><divclass="signal-date">[Month YYYY or "Q1 2026"]</div><divclass="signal-body"><divclass="signal-headline">[What happened — one line]</div><divclass="signal-relevance">[Why it matters for this deal — one line]</div></div></div><!-- more signal-items --></div></details>
Rules:
Only include this section when deep_web_research was called during context gathering. If deep research was not run, omit silently.
Macro themes should be strategic narratives, not product feature announcements. Think "what would a board member care about."
Signal feed items must have dates. Undated signals are useless.
The "why it matters" line must connect to the deal angle — don't just restate the news.
People — a card group containing a .people-grid with .persona-group elements. The structure is persona-first: group by the function/role that matters, explain why that persona is relevant, then list the actual people who fit underneath.
Persona groups: Each .persona-group has a header (persona title + "Potential fits" tag), a .persona-why paragraph explaining why this function matters for this specific deal, and a .persona-people list of matching individuals.
When you have real people from research: Default to showing them. Don't fall back to generic role descriptions when named candidates exist. Include LinkedIn links for every named person. Always use find_person({ searchMode: "people", companyDomain, fuzzyTitles }) to find contacts — this returns LinkedIn profile URLs along with name, title, and location. Use the returned LinkedIn URLs directly in the .pp-link elements. Do not guess or construct LinkedIn URLs manually.
When no people are found: Still show the persona group with the "why" context, but replace the people list with a single line: "No candidates identified yet — search [title keywords] on LinkedIn."
Confirmed attendees: If someone is confirmed for the meeting, add a .slot-tag.confirmed-tag next to their name instead of "Potential fits" on the group header.
Verify before naming: the unconfirmed convention. Every named person in this card group must trace to a real result from resolve_profile_from_email, enrich_person, or find_person (see the verification step in Step 2). Two outcomes:
Confirmed. The tool returned a match. Use its name and title (not whatever version was originally supplied), and for internal docs you may link the person's real profile via the app.octavehq.com/entity/{oId} convention (see the entity-linking note in shared/information-principles.md #12c; this skill is internal/seller-facing, so it applies).
Unconfirmed. The person was named by the user, a CRM field, or a transcript, but no tool call confirmed them (no match, ambiguous match, or wrong company). Keep them in the doc, but mark them with a ⚠ Unconfirmed chip using the .unconfirmed tag (same slot as .slot-tag.confirmed-tag / .potential-fit, styled distinctly, see CSS below) and hedge the title if it wasn't verified either, e.g. "VP Engineering (unconfirmed)". Never state an unconfirmed name or title as settled fact.
Internal vs. external: who gets checked. This verification only applies to external stakeholders and attendees at the target company. The deal owner / your own AE resolves to the workspace company's own domain (from get_workspace_company or the CRM owner field) and belongs in the header's "Prepared for/by" line, stated as fact, never flagged .unconfirmed, never treated as a prospect claim.
<detailsclass="card-group"open><summary>People</summary><pclass="card-group-intro">No confirmed attendees yet. These are personas most likely to feel the pain, with potential fits at [Company].</p><divclass="people-grid"><divclass="persona-group"><divclass="persona-header"><spanclass="persona-title">Sales Strategy & Operations</span><spanclass="slot-tag potential-fit">Potential fits</span></div><divclass="persona-why">[2-3 sentences on what this persona owns and why it matters for THIS company. Be specific — reference their product lines, team scale, geo spread, or recent changes that make this role feel the pain.]</div><divclass="persona-people"><divclass="persona-person"><divclass="pp-avatar">DR</div><divclass="pp-info"><divclass="pp-name">Dana Reyes</div><divclass="pp-title">Head of Sales Strategy & Operations · San Francisco</div></div><aclass="pp-link"href="https://linkedin.com/in/[profile]"target="_blank">LinkedIn →</a></div></div></div><divclass="persona-group"><divclass="persona-header"><spanclass="persona-title">Product Marketing</span><spanclass="slot-tag potential-fit">Potential fits</span></div><divclass="persona-why">[Why PMM matters here — e.g., owns battle cards and competitive positioning across N competitors, sees content decay daily as product story evolves.]</div><divclass="persona-people"><divclass="persona-person"><divclass="pp-avatar">HT</div><divclass="pp-info"><divclass="pp-name">Harper Tanaka</div><divclass="pp-title">Enterprise PMM · New York</div></div><aclass="pp-link"href="https://linkedin.com/in/[profile]"target="_blank">LinkedIn →</a></div><divclass="persona-person"><divclass="pp-avatar">MK</div><divclass="pp-info"><divclass="pp-name">Morgan Kade</div><divclass="pp-title">Senior PMM, Platform · San Francisco</div></div><aclass="pp-link"href="https://linkedin.com/in/[profile]"target="_blank">LinkedIn →</a></div><!-- Named in the CRM field but find_person/enrich_person returned no match — keep, don't drop, tag it --><divclass="persona-person"><divclass="pp-avatar">JT</div><divclass="pp-info"><divclass="pp-name">Jordan Tran <spanclass="unconfirmed">⚠ Unconfirmed</span></div><divclass="pp-title">Title from CRM field, not yet verified</div></div></div></div></div></div></details>
Persona cards are briefings, not dossiers. Each group gets 2-3 rows maximum:
Pressure — the structural pressure this persona is under at THIS company (1-2 sentences, grounded in specific company context)
Why [Product] — why our product matters to them specifically (1-2 sentences)
Do NOT add sub-sections for "How we make them the hero," "Top use cases," "Don't lead with," or other messaging content inside persona cards. That content belongs in Section 3 (persona message shifts). The persona card's job is to brief the seller on who this person is and what they care about, nothing more.
Existing Connections — If research surfaces relationships, surface them here. If no connections found, omit this sub-section silently.
Deal Context — a card group containing a .context-grid with .cg-row elements (same pattern as Company Context).
<detailsclass="card-group"open><summary>Deal Context</summary><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">Stage</div><divclass="cg-value">Net-New — Discovery</div></div><divclass="cg-row"><divclass="cg-label">Activity</div><divclass="cg-value">4 meetings, 12 emails in last 30 days</div></div><divclass="cg-row"><divclass="cg-label">Competition</div><divclass="cg-value">[See competition language rules below]</div></div><divclass="cg-row"><divclass="cg-label">Champion</div><divclass="cg-value">Not yet identified</div></div><divclass="cg-row"><divclass="cg-label">Compelling Event</div><divclass="cg-value">Unknown — probe for reorgs or product launches</div></div><divclass="cg-row"><divclass="cg-label">Buying Triggers</div><divclass="cg-value">Fiscal year planning, new product launch, competitor move, reorg — what would trigger action now</div></div></div></details>
Competition language rules for the Competition field in Deal Context:
If we KNOW who's competing: state it directly (e.g., "Datadog, internal build")
If we're speculating: "Unknown — Potential: internal build, Glean"
NEVER use "Likely:" as a prefix when we have no confirmed intel
General principle: always distinguish confirmed facts from speculation
Deal Timeline(conditional — include when event/finding data exists) — a visual timeline placed inside or immediately after the Deal Context card group. It shows the engagement arc: when the deal started, key milestones, gaps in activity, and current momentum.
The timeline uses a horizontal dot-and-line pattern. Each milestone gets a dot, a date, and a one-line label. Gaps in engagement are shown as dashed segments with a label (e.g., "6 months — no activity").
Only include when you have actual event/finding data to populate it. If no deal history exists, omit silently.
Use list_events and list_findings data to reconstruct the timeline. Cluster nearby events into single milestones (don't show every individual email).
Highlight gaps explicitly — a 6-month silence is critical context a rep needs to see.
The most recent / current item gets a .current class and an .active dot (brand-colored).
Keep it to 3-6 milestones. This is a scannable arc, not a CRM activity log.
On mobile, the timeline stacks vertically.
IMPORTANT: "Their Pains" is NOT a sub-section of Section 1. Pains are recognition cards in Section 2 — they ARE the "What We Need Them to Recognize" cards. There are no separate "Pains We Know They Have" cards. "ICP Indicator" is NOT a separate sub-section — persona/segment match is folded into the "Why they're a fit" row of Company Context.
Section 2: Goals
What we need to accomplish in this meeting — our positioning frame, what they need to recognize, and how we advance.
One-line intro: "What we need to accomplish in this meeting — our positioning frame, what they need to recognize, and how we advance."
Sub-components:
Positioning Directive — A concise, structured block that replaces exit criteria. Not a paragraph — a clear three-part frame:
<h3class="sub-section-title">Positioning Directive</h3><divclass="positioning-directive"><divclass="pd-row"><divclass="pd-label">Position us as</div><divclass="pd-value">[One line — the frame we want in their head]</div></div><divclass="pd-row"><divclass="pd-label">Mitigate</div><divclass="pd-value">[The specific risk/objection/competitor angle to neutralize]</div></div><divclass="pd-row"><divclass="pd-label">Advance</div><divclass="pd-value">[The deal motion — next step, commitment, or validation we need]</div></div></div>
CSS: .positioning-directive (grid container), .pd-row (2-column grid like .cg-row), .pd-label (brand-primary color, uppercase), .pd-value. The label column uses var(--brand-primary) color to visually distinguish from context grid labels.
This is the messaging/positioning intelligence showing its value. Grounded in Octave's positioning entities + deal context.
What We Need Them to Recognize — a card group of recognition table-cards. Reframed from passive "beliefs" to active voice:
<detailsclass="card-group"open><summary>What We Need Them to Recognize</summary><pclass="card-group-intro">Conclusions we need them to reach. Active voice, opinionated — we know these are true, we need them to see it too.</p><detailsclass="table-card"><summary>GTM context is infrastructure, not content</summary><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">Context</div><divclass="cg-value">Why this recognition matters for this specific deal</div></div><divclass="cg-row"><divclass="cg-label">Status</div><divclass="cg-value"><spanclass="cc-status unexplored">Unexplored</span></div></div><divclass="cg-row"><divclass="cg-label">How to plant</div><divclass="cg-value">Specific approach to get them to this conclusion</div></div><divclass="cg-row"><divclass="cg-label">Watch out</div><divclass="cg-value cg-watchout">What NOT to say that would undermine this recognition</div></div></div><detailsclass="cc-questions"><summary>1 discovery question</summary><!-- cc-q-grid --></details></details></details>
The "Watch out" row uses .cg-watchout styling (muted, italic) and provides a specific anti-pattern — what to avoid saying when trying to plant this recognition.
3-4 recognition cards maximum. Order by importance to this meeting.
Recognition cards are the canonical location for pains. A recognition like "broker flow masks coverage gaps at portfolio scale" IS the pain. Do not create separate "Pains We Know They Have" or "Themes to Steer" card groups — those always duplicate the recognition cards. If a pain is worth surfacing, it belongs as a recognition card with Context, Status, How to plant, Watch out, and an optional discovery question. One location per insight.
Section 3: Competitive
Where we stand relative to alternatives and the status quo.
One-line intro: "How to position against each competitive angle in this deal. Competitive pushback belongs here, not in Objections."
This section owns all competitive positioning AND competitive objections. When someone says "we already have [Competitor]," the response lives in this section's card for that competitor. The Objections section (Section 5) handles non-competitive resistance only: data trust, pricing, adoption, technical.
<detailsclass="prep-section"openid="competitive"><summary>3. Competitive</summary><pclass="section-intro">How to position against each competitive angle in this deal. Competitive pushback belongs here, not in Objections.</p><detailsclass="table-card"><summary>Competitor Name (positioning angle)</summary><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">Their positioning</div><divclass="cg-value">What the competitor claims / what the prospect believes about them</div></div><divclass="cg-row"><divclass="cg-label">You'll hear</div><divclass="cg-value">The sentence a prospect says when this competitor comes up</div></div><divclass="cg-row"><divclass="cg-label">Our counter</div><divclass="cg-value">How we differentiate. Use response-list format for multiple points.</div></div><divclass="cg-row"><divclass="cg-label">Trap question</div><divclass="cg-value">A question that exposes the competitor's weakness without naming them</div></div><divclass="cg-row"><divclass="cg-label">Watch out</div><divclass="cg-value cg-watchout">What NOT to say that would backfire with this audience</div></div></div></details></details>
2-3 competitive cards maximum. Include "Status quo / internal process" as a card when relevant — this is often the biggest competitor.
Sources: Octave competitor entities, battlecard data. Conditional richness — if competitor entities exist in the library, build the full cards. If not, keep the honest single row in Deal Context and note "No confirmed competitors — competitive section omitted."
Competitive cards absorb competitive objections. The "You'll hear" row is where the prospect's words go. The "Our counter" row is the response. This means the Objections section does NOT need separate cards for competitive pushback. If "we already have CoStar" is a likely objection, the CoStar competitive card handles it completely.
Section 4: What to Say & Ask
How our message shifts by persona in the room.
One-line intro: "Each person in the room hears our story differently. Here's how to shift the message."
This section contains ONLY persona message tabs. Pains are recognition cards in Section 2. Competitive positioning is in Section 3. Objections are in Section 5. This section's job is narrow: how the narrative shifts depending on who you're talking to.
How Our Message Lands by Persona — A tabbed card group. Each tab represents a persona in the room.
<detailsclass="prep-section"openid="what-to-say"><summary>4. What to Say & Ask</summary><pclass="section-intro">Each person in the room hears our story differently. Here's how to shift the message.</p><divclass="tab-bar"><buttonclass="tab-btn active"onclick="switchTab(this, 'persona-tabs')">Sales Ops</button><buttonclass="tab-btn"onclick="switchTab(this, 'persona-tabs')">PMM</button></div><divid="persona-tabs"><divclass="tab-panel active"><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">Our story shifts to</div><divclass="cg-value">How our narrative changes for this persona — the specific angle that matters to their role</div></div><divclass="cg-row"><divclass="cg-label">Say this</div><divclass="cg-value">One concrete hook line for this persona — a sentence they can actually say in the room</div></div><divclass="cg-row"><divclass="cg-label">Don't lead with</div><divclass="cg-value cg-watchout">What to avoid with this persona and why</div></div></div></div><!-- More tab-panels --></div></details>
3 rows per persona tab, not 5. The "Pressure" row is already in the persona card in Section 1 — repeating it here is data duplication. The "Use case" row tends toward bloat and belongs in positioning or recognition cards. Keep it tight:
Our story shifts to — how the narrative changes
Say this — one concrete sentence
Don't lead with — what to avoid
Tab labels should be short persona names (e.g., "Sales Ops", "PMM", "CRO") — not full titles.
Sources: Octave messaging entities, Motion ICP narrative (benefitsAndImpacts, strategicNarrative, painsAndConsequences), ICP cells. Conditional — show when we have strong Octave data, degrade gracefully when thin. If we only have 1-2 personas with strong data, show those and omit thin ones.
Objection framing rules (apply to both competitive cards in Section 3 and objection cards in Section 5): Objection titles must be high-level descriptions of the risk, NOT quotes in the prospect's voice:
BAD: "We already use Glean for this"
GOOD: They position this as overlap with existing enterprise search
BAD: "We could build this ourselves"
GOOD: Their engineering team defaults to building internally
The objection should describe the situation or risk, not put words in the prospect's mouth.
Section 5: Objections
Non-competitive pushback we expect. Have your responses sharp — and know what NOT to say.
One-line intro: "Pushback we expect, organized by theme. Have your responses sharp — and know what NOT to say."
This section handles non-competitive resistance only. Competitive pushback ("we already have X", "our brokers handle this") belongs in Section 3 (Competitive). This section covers: data trust, pricing & value, technical & integration, adoption risk, and status quo inertia that isn't competitor-specific.
Structure: Theme tabs at the top, objection cards underneath each tab.
Theme tabs organize objections by category:
Data Trust
Pricing & Value
Technical & Integration
Status Quo & Inertia (non-competitive — e.g., "we don't have budget for another tool")
(additional themes as relevant to the deal)
Each theme tab has a one-line intro explaining why this theme matters in this specific deal.
<detailsclass="prep-section"openid="objections"><summary>5. Objections</summary><pclass="section-intro">Pushback we expect, organized by theme. Have your responses sharp — and know what NOT to say.</p><divclass="tab-bar"><buttonclass="tab-btn active"onclick="switchTab(this, 'objection-tabs')">Status Quo & Inertia</button><buttonclass="tab-btn"onclick="switchTab(this, 'objection-tabs')">Technical & Integration</button><buttonclass="tab-btn"onclick="switchTab(this, 'objection-tabs')">Competitive</button></div><divid="objection-tabs"><divclass="tab-panel active"><pclass="card-group-intro">Why this theme matters in this specific deal.</p><detailsclass="table-card"><summary><span>Objection title (descriptive, not quoted)</span><spanclass="persona-tag">Sales Ops</span><spanclass="persona-tag">Engineering</span></summary><divclass="context-grid"><divclass="cg-row"><divclass="cg-label">You'll hear</div><divclass="cg-value">The actual sentence they'll say — in their voice</div></div><divclass="cg-row"><divclass="cg-label">Response</div><divclass="cg-value"><ulclass="response-list"><li>First response point</li><li>Second response point with <strong>emphasis</strong></li></ul></div></div><divclass="cg-row"><divclass="cg-label">Watch out</div><divclass="cg-value cg-watchout">What NOT to say in response — the thing that would make this objection worse</div></div></div></details></div><!-- More tab-panels for other themes --></div></details>
Objection card structure:
Summary: Descriptive title (same framing rule as before — not quotes in prospect's voice) + .persona-tag pill badges indicating who typically raises it
"You'll hear" row: The actual sentence the prospect will say, in their voice. This is where the prospect's words go — not the title.
Response row: Response points using .response-list format (same as before)
"Watch out" row: What NOT to say in response, using .cg-watchout styling
Persona tags are pill badges (.persona-tag) that sit inside the <summary> element after the title <span>. They indicate which personas typically raise this objection.
Content limits: Cap at 3-5 objection cards across all themes. Competitive pushback is in Section 3, so this section only needs the non-competitive resistance. Quality over comprehensiveness.
Theme selection: Choose themes relevant to the deal. Not every deal needs all four standard themes. A startup deal might only have "Status Quo & Inertia" and "Competitive." An enterprise deal might have all four plus a custom theme.
Section 6: The Takeaway
The one thing to remember walking into the call.
One-line intro: "If you remember nothing else, remember this."
One sentence. The thing you'd write on a sticky note and put on your monitor before the call. It should distill the entire prep into a single actionable insight.
Section 5 uses a <section> element (not <details>) since it's always visible:
<sectionclass="prep-section"id="the-takeaway"><h2style="font-family:var(--font-display);font-size:clamp(1.1rem,2vw,1.35rem);font-weight:600;padding:0.75rem 0;">6. The Takeaway</h2><pclass="section-intro">If you remember nothing else, remember this.</p><divclass="the-takeaway"><blockquote>[One memorable sentence]</blockquote></div></section>