sales-wiki-architecture.md46.9 KBView on GitHub # Sales Knowledge Wiki: Document-Based Architecture
**Date:** May 3, 2026
## The Shift: Compiled Knowledge > Embedding Retrieval
The trend you're pointing to is real and well-documented. Key evidence:
### Why Embeddings Are Problematic
**Fundamental failure modes** (2025-2026 research):
- **Entity/role swapping**: Cosine similarity of 0.987 between "Alice sold to Bob" and "Bob sold to Alice" — catastrophic retrieval failure
- **Negation blindness**: "Deal closed" and "Deal did not close" have 0.896 similarity
- **Fine-grained matching failures**: Embeddings can't distinguish subtle but important differences
- **Drowning in documents**: As corpus grows, relevant docs get overshadowed by noise in similarity distributions
**Architectural issues**:
- Similarity search ignores *structure* — "What's the status of deal X?" requires traversing relationships, not finding similar text
- Pruning breaks evidence chains — removing context loses the connections between sequential facts
- Re-derivation on every query — no compounding, no learning
### What's Replacing It
**Karpathy's LLM Wiki pattern** (April 2026):
- The LLM *maintains* a persistent wiki, not just retrieves from raw sources
- When new data arrives, it updates entity pages, revises summaries, flags contradictions
- Cross-references are *already there* — not discovered at query time
- "Knowledge as compiled code" — synthesize once, query many times
**ByteRover** (2026):
- Hierarchical Context Tree: Domain → Topic → Subtopic → Entry
- Just markdown files on the filesystem — no vector database
- 5-tier retrieval: cache → BM25 → LLM prefetch → agentic reasoning
- Most queries resolve without LLM calls using text relevance + importance + recency
**Structured Linked Data** (arXiv 2603.10700):
- Entity pages with explicit navigational links
- +29.6% accuracy improvement over flat document retrieval
- Multi-hop link traversal beats semantic similarity
---
## Applied to Cedar: Sales Knowledge Wiki
Instead of:
- Vectorizing field values into Turbopuffer
- Doing similarity search at query time
- Re-discovering patterns on every agent execution
We build:
- A persistent wiki of sales knowledge maintained by the agent
- Entity pages for techniques, objections, deals, reps, process variants
- Explicit wikilinks between related entities
- Summaries that compound as deals close and patterns emerge
### The Three Layers (Karpathy Pattern)
**Layer 1: Raw Sources (immutable)**
- Meeting transcripts (S3/`MEETINGS_BUCKET`)
- Email threads (S3/`THREADS_BUCKET`)
- CRM events (`crm_events`)
- Deal data (`crm_conversations`)
These are never modified by the agent. They're source of truth.
**Layer 2: The Wiki (agent-maintained)**
- Markdown documents in the Cedar Docs system
- Entity pages, technique pages, pattern pages, summary pages
- Cross-referenced with `[[wikilinks]]` (Cedar already has `[[type: id]]` syntax)
- Updated when: new deals close, new techniques extracted, periodic consolidation
**Layer 3: The Schema (governance)**
- AOP-level configuration: what pages should exist, what conventions to follow
- Extraction rules: what qualifies as a "technique" worth a page
- Update triggers: when to revise, when to flag contradictions
### Page Types in the Sales Wiki
| Page Type | Scope | Purpose | Example |
|-----------|-------|---------|---------|
| **Technique** | Org | A specific reusable sales technique with examples | `techniques/pricing-anchoring-via-tco.md` |
| **Objection** | Org | An objection type with handling approaches | `objections/security-compliance.md` |
| **Process Variant** | Org | A discovered sales motion with characteristics | `variants/enterprise-inbound.md` |
| **Stage Guide** | Org | What success looks like at each stage | `stages/discovery.md` |
| **Rep Profile** | Org | A rep's patterns and strengths | `reps/sarah-chen.md` |
| **Deal Case Study** | Org | A closed deal with lessons learned | `deals/acme-corp-2026-q1.md` |
| **Methodology** | Org | MEDDPICC/BANT/SAYA reference with org examples | `methodology/meddpicc.md` |
| **Pattern Summary** | Org | Aggregate pattern (what wins at stage X) | `patterns/discovery-winners.md` |
| **Competitive Intel** | Org | Competitor-specific knowledge | `competitors/competitor-x.md` |
### Wiki Structure
```
org_{orgId}/
├── _index.md # Catalog of all pages with summaries
├── _log.md # Chronological record of updates
├── _schema.md # Wiki conventions and update rules
│
├── techniques/
│ ├── pricing-anchoring-via-tco.md
│ ├── multi-threading-executive-sponsor.md
│ └── ...
│
├── objections/
│ ├── security-compliance.md
│ ├── budget-timing.md
│ └── ...
│
├── variants/
│ ├── enterprise-inbound.md
│ ├── smb-plg-conversion.md
│ └── ...
│
├── stages/
│ ├── discovery.md
│ ├── demo.md
│ ├── proposal.md
│ └── ...
│
├── patterns/
│ ├── discovery-winners.md
│ ├── sell-between-tactics.md
│ └── ...
│
├── deals/ # Case studies of notable deals
│ ├── acme-corp-2026-q1.md
│ └── ...
│
├── reps/
│ └── ...
│
└── competitors/
└── ...
```
### Grep-able Formatting Convention (Karpathy Pattern)
**Principle:** Consistent prefixes make files parseable with simple unix tools — no full-text parsing required.
**Section headers use SCREAMING_CASE:**
```markdown
## SUMMARY
## WHEN_TO_USE
## EXAMPLES
## PATTERNS
## RELATED
```
**Example entries use structured prefixes:**
```markdown
### [2026-03-15] Sarah Chen | Acme Corp | Won
### [2026-04-02] Mike Torres | Globex | Won
### [2026-04-18] Jennifer Wu | Initech | Lost
```
**Log entries use consistent format:**
```markdown
## [2026-05-01] update | techniques/pricing-anchoring-via-tco.md | Added example from Acme deal
## [2026-05-01] create | objections/implementation-timeline.md | New objection type detected
## [2026-04-30] lint | Found 3 orphan pages, 1 contradiction
```
**This enables fast queries without LLM:**
```bash
# Find all technique summaries
grep "^## SUMMARY" techniques/*.md -A 1
# Find all examples from won deals
grep "^### \[.*\] .* | Won$" techniques/*.md
# Find all examples from a specific rep
grep "^### \[.*\] Sarah Chen" */**.md
# Find all lost deal examples
grep "^### \[.*\] .* | Lost$" */**.md
# Get last 10 wiki updates
grep "^## \[" _log.md | tail -10
# Find all pages updated today
grep "^## \[2026-05-03\]" _log.md
# Count examples per technique
for f in techniques/*.md; do echo "$f: $(grep -c '^### \[' $f)"; done
```
### Example Page: `techniques/pricing-anchoring-via-tco.md`
```markdown
---
type: technique
title: Pricing Anchoring via TCO
summary: Anchor pricing by referencing competitor TCO before revealing your price
keywords: [pricing, anchoring, tco, competitor, discovery]
created: 2026-03-15
updated: 2026-05-01
importance: 72
maturity: validated
outcome_stats:
used_in: 12
won: 8
lost: 4
win_rate: 0.67
stages_used: [discovery, demo]
variants: [enterprise-inbound]
related:
- [[objections/budget-timing]]
- [[stages/discovery]]
- [[patterns/discovery-winners]]
---
# Pricing Anchoring via TCO Comparison
## SUMMARY
Anchor the pricing conversation by referencing competitor total cost of ownership
before revealing your price. Frames your price as reasonable vs. market, not
as an abstract number.
## WHEN_TO_USE
- Early in discovery when prospect has competitor exposure
- When you're more expensive than competitor headline price but better on TCO
- Best deployed BEFORE they ask about pricing
## EXAMPLES
### [2026-03-15] Sarah Chen | Acme Corp | Won
**Stage:** Discovery | **Call:** [[event:evt-abc123]] at 08:45
> "Most teams evaluating [competitor] don't realize the implementation typically
> runs 6-9 months with $200K in services. When you factor that in, the 3-year
> TCO is actually 40% higher than our all-in number."
**Prospect response:** "That's helpful context. We hadn't factored in services."
**Outcome:** Deal closed at $180K, 47-day cycle
### [2026-04-02] Mike Torres | Globex Inc | Won
**Stage:** Demo | **Call:** [[event:evt-def456]] at 12:30
...
### [2026-04-18] Jennifer Wu | Initech | Lost
**Stage:** Discovery | **Call:** [[event:evt-ghi789]] at 04:15
> [Quote]
**Why it didn't work:** Prospect had already gotten competitor quote locked in.
Technique was deployed too late — needs to happen before competitor pricing lands.
## PATTERNS
- **Win rate by stage:** Discovery (75%), Demo (60%), Proposal (40%)
- **Works best when:** Prospect hasn't received competitor quote yet
- **Counter-indicators:** Prospect already has competitor proposal; small deal (<$50K)
## RELATED
- Counters: [[objections/budget-timing]]
- Used in: [[variants/enterprise-inbound]]
- See also: [[techniques/roi-calculator-walkthrough]]
```
### Example Page: `variants/enterprise-inbound.md`
```markdown
---
type: process_variant
created: 2026-02-01
updated: 2026-05-01
deals_analyzed: 47
win_rate: 0.32
avg_cycle_days: 52
discriminators:
segment: enterprise
source: inbound
deal_size_min: 100000
---
# Enterprise Inbound Process Variant
## Characteristics
| Attribute | Value |
|-----------|-------|
| Segment | Enterprise (500+ employees) |
| Source | Inbound (demo request, content download) |
| Deal size | $100K–$500K |
| Avg cycle | 52 days |
| Win rate | 32% |
| Deals analyzed | 47 |
## Stage Progression
| Stage | Median days | P25–P75 | Exit criteria |
|-------|-------------|---------|---------------|
| Discovery | 8 | 5–14 | Pain confirmed, 2+ stakeholders identified |
| Demo | 12 | 8–18 | Technical validation, champion confirmed |
| Proposal | 10 | 6–16 | Pricing accepted, procurement engaged |
| Negotiation | 14 | 8–22 | Legal/security complete |
| Close | 8 | 4–12 | Contract signed |
## What Wins Look Like
### Discovery
- Multi-threading by end of stage (avg 2.4 contacts in won deals vs 1.1 in lost)
- ROI discussion happens before pricing (see [[techniques/roi-calculator-walkthrough]])
- Champion test passed: [[patterns/champion-indicators]]
### Between Stages
- Sell-between activity: 2+ touchpoints between every stage transition
- Content that works: ROI summaries, technical deep-dives, customer references
- See [[patterns/sell-between-tactics]]
### Key Techniques
- [[techniques/pricing-anchoring-via-tco]] — 67% win rate when used in discovery
- [[techniques/multi-threading-executive-sponsor]] — 3.2x close rate when exec involved by Stage 3
- [[techniques/security-review-parallel-track]] — reduces cycle by 8 days
## Red Flags
- Single-threaded past discovery → 18% win rate
- No activity for 10+ days → 28% of stalled deals don't recover
- Competitor mentioned without battlecard response → win rate drops to 22%
## Comparison to Other Variants
- vs [[variants/smb-plg-conversion]]: 3x cycle time, 2x deal size, 0.5x volume
- vs [[variants/enterprise-outbound]]: Similar cycle, but inbound has 1.4x win rate
```
---
## How Updates Flow
### On Meeting Completion
1. **Extraction agent** processes transcript (already exists)
2. **Wiki update agent** (new):
- Checks if any extracted techniques match existing pages → update with new example
- If new technique pattern detected → create new page or flag for review
- Updates rep profile page with technique usage
- Updates stage guide with any new signals
- Appends to `_log.md`
### On Deal Close
1. **Outcome propagation** (partially exists in `backfillFieldValueOutcomes`):
- Updates all technique pages used in this deal with outcome data
- Recalculates win rates on technique, objection, variant pages
- If deal is notable (large, fast, unusual) → create case study page
- Updates variant page aggregate stats
- Pattern detection: if this deal followed unusual path, flag for variant review
### Periodic Consolidation ("Lint")
Weekly background job:
- Find orphan pages (no inbound links) → flag or merge
- Find contradictions (technique claims one thing, stats show another) → flag
- Regenerate pattern summaries from updated data
- Identify gaps: objections mentioned but no handling page exists
---
## Metadata Linking: Wiki ↔ Events ↔ Turbopuffer
### The Full Chain
Each wiki example links back to source data:
```
Wiki Example (compiled knowledge)
│
├── [[conversation: conv_abc123]] → crm_conversations row
│ (deal, stage, outcome, company)
│
└── [[event: evt_meeting_456]] → crm_events row
(meeting, transcript, timestamp)
│
└── Turbopuffer field value
(vector embedding, metadata filters)
```
### What's Stored Where
| Layer | Data | Access Pattern | Use Case |
|-------|------|----------------|----------|
| **Wiki page** | Compiled pattern + examples | Grep/read | "What works in discovery?" |
| **`crm_conversations`** | Deal metadata, stage, outcome | SQL lookup | Link context, outcome stats |
| **`crm_events`** | Full transcript, timestamp | ID lookup via `[[event:]]` | Deep-dive into source |
| **Turbopuffer** | Vector embeddings + filters | Semantic search | "Find similar moments" |
### Turbopuffer's Role
Turbopuffer field values are the **extraction layer** — raw moments captured from transcripts. Each row stores:
```typescript
{
fieldId: '_ii_competitive', // extraction type
content: 'Rep anchored on TCO...', // extracted moment
sourceEventId: 'evt_meeting_456', // → full transcript
conversationId: 'conv_abc123', // → deal context
sourceUserId: 'user_sarah', // → rep
stageAtEventTime: 'discovery', // when it happened
outcomeStage: 'closed_won', // deal result
metadata: { callType: 'Demo', timestampMmSs: '08:45' }
}
```
**How it fits with the wiki:**
1. **Wiki page cites the example** — formatted prose with `[[event: evt_meeting_456]]`
2. **Agent wants to go deeper** — follows link to read full transcript section
3. **Agent wants to find similar** — queries Turbopuffer for `fieldId: '_ii_competitive'` + `outcomeStage: 'closed_won'`
4. **New extraction happens** — gets written to Turbopuffer AND triggers wiki update agent
### Example: Agent Flow
```
User: "How should I handle budget objections?"
1. Agent reads wiki: objections/budget-timing.md
- Sees pattern summary, win rate, examples
- Example links: [[conversation: conv_abc123]] [[event: evt_meeting_456]]
2. Agent wants more examples not yet in wiki:
- Queries Turbopuffer: fieldId contains 'objection', content ~ 'budget'
- Gets raw extractions from recent meetings
3. Agent wants full context on one example:
- Follows [[event: evt_meeting_456]]
- Reads transcript section around timestamp 08:45
4. Agent synthesizes:
- Wiki provided the pattern ("reframe to ROI timeline")
- Turbopuffer provided fresh examples
- Transcript provided exact wording that worked
```
### Two-Way Sync
| Direction | Trigger | Action |
|-----------|---------|--------|
| **Turbopuffer → Wiki** | New extraction | Wiki update agent checks if pattern exists, adds example |
| **Wiki → Turbopuffer** | Manual page edit | N/A (Turbopuffer is source of truth for raw extractions) |
| **Deal close** | Status change | Backfill `outcomeStage` in Turbopuffer; recalc wiki `outcome_stats` |
---
## How Agent Reads Wiki
### At Execution Time
Instead of `searchIntelligenceTool` doing vector similarity search, agent:
1. **Reads `_index.md`** — sees what pages exist, one-line summaries
2. **Navigates via links** — "User asking about discovery" → read `stages/discovery.md`
3. **Follows cross-references** — discovery page links to relevant techniques → read those
4. **Gets specific examples** — technique pages have verbatim quotes with event IDs
This is Cedar Docs infrastructure that already exists — `listDocuments`, `readDocument`, `grepDocuments`. Just need:
- New `DOCUMENT_TYPE` values for wiki pages
- `DOCUMENT_SCOPE_TYPE.ORG` scoping
- Convention for wikilink syntax (already have `[[type: id]]`)
### Query Flow Example: "I'm losing momentum between meetings"
1. Agent reads `_index.md` → finds `patterns/sell-between-tactics.md`
2. Reads that page → sees:
- Expected cadence: 2+ touchpoints between stages
- Techniques that work: ROI follow-ups, technical deep-dives
- Links to: `[[techniques/roi-follow-up-email]]`, `[[techniques/technical-deep-dive-async]]`
3. Reads technique pages → gets specific examples with [[event: id]] links
4. Agent fetches this deal's recent activity via `fetchConversation`
5. Compares: expected cadence vs actual → generates gap analysis
6. Uses technique examples to draft sell-between content
**No vector search involved.** Just document reads and link traversal.
---
## 5-Tier Progressive Retrieval (ByteRover Pattern)
The key insight from ByteRover: **most queries don't need an LLM to find the answer — they need the LLM to have written a good answer ahead of time.** Their 5-tier strategy resolves most queries in <200ms with zero LLM cost.
### The Tiers
| Tier | Name | Speed | How It Works |
|------|------|-------|--------------|
| **0** | Exact cache | ~0ms | MD5 fingerprint match on query string. 60s TTL. |
| **1** | Fuzzy cache | ~50ms | ≥60% token similarity (Jaccard) to a cached query. Return cached if wiki unchanged. |
| **2** | BM25 direct | ~100–200ms | Full-text search. If top result scores ≥0.85 with clear gap over #2, return directly — **no LLM call**. |
| **3** | LLM pre-fetch | <5s | Top BM25 results injected as context for single LLM call to synthesize. |
| **4** | Agentic loop | 8–15s | Full multi-step reasoning: reads files, follows relations, iterates. |
**Tiers 0–2 bypass the LLM entirely.** This is the key efficiency gain.
### Compound Scoring Formula
Results ranked by:
```
score = (0.6 × BM25 + 0.2 × importance + 0.2 × recency) × tierBoost
```
| Component | Weight | What It Measures |
|-----------|--------|------------------|
| **BM25 relevance** | 60% | Text match quality (title, summary, keywords, content) |
| **Importance** | 20% | Accumulated value: +3 per search hit, +5 per update, decays 0.995^days |
| **Recency** | 20% | Exponential decay since last update (e^(-days/30)) |
**Maturity tier boosts:**
- `core` (importance ≥85): ×1.15 — well-established, frequently-used knowledge
- `validated` (≥65): ×1.0 — actively used
- `draft` (<65): ×0.85 — new or infrequently accessed
A `core` technique page with moderate text match beats a `draft` page with higher text match.
### File Artifacts That Enable Fast Retrieval
ByteRover auto-generates companion files:
| Artifact | Size | Purpose |
|----------|------|---------|
| `_index.md` | ~1-2K tokens | Catalog with one-line summaries per page |
| `_manifest.json` | structured | Token-budgeted registry, pre-computed |
| `.abstract.md` | ~80 tokens | One-liner capturing core topic + key insight |
| `.overview.md` | ~1500 tokens | Structured summary with 3-7 key points |
| `context.md` | ~200 tokens | Scope and boundaries at each hierarchy level |
The manifest is read lazily — fresh if unchanged, rebuilt on the fly if stale. This gives the agent a structural overview without scanning every file.
### Applied to Cedar Sales Wiki
| ByteRover Artifact | Cedar Equivalent |
|--------------------|------------------|
| `_index.md` | `WIKI_INDEX` doc with technique/pattern summaries |
| `.abstract.md` | YAML frontmatter `summary` field (~80 tokens) |
| `.overview.md` | "Overview" section at top of each page |
| `_manifest.json` | Could use Cedar Docs `listDocuments` metadata |
| Importance scoring | `outcome_stats.used_in` + `win_rate` + update recency |
| Maturity tiers | `core` (high win rate, many uses), `validated`, `draft` |
### Cache Strategy for Cedar
**Tier 0 — Exact cache:**
- Key=[redacted]
- TTL: 60s (or until wiki update)
- Storage: Redis or in-memory LRU
**Tier 1 — Fuzzy cache:**
- Jaccard similarity on query tokens
- If ≥60% match and wiki unchanged since cached query, return cached result
**Tier 2 — BM25 direct:**
- Use `grepDocuments` with scoring on frontmatter fields: `title`, `summary`, `keywords`, `tags`
- If top result scores ≥0.85 with clear gap, return page content directly
- **No LLM call needed**
**Tier 3 — LLM pre-fetch:**
- Top 3 BM25 results injected as context
- Single LLM call to synthesize answer with citations
**Tier 4 — Agentic loop:**
- Full agent execution with `readDocument`, `listDocuments`, link traversal
- Used for complex multi-hop questions
### Out-of-Domain Detection
When top search result scores below relevance threshold, or query terms have no matches:
- Return "This topic isn't covered in the sales wiki"
- Suggest: "Consider curating knowledge about [topic] after your next [relevant call type]"
- Don't return low-quality guesses
### Score-Gap Filter
After scoring, drop results below 70% of top score:
```
minimum = topScore × 0.7
```
If best result scores 0.90, anything below 0.63 is excluded. Prevents long-tail noise.
### Example: "pricing anchoring" Query
1. **Tier 0**: No exact cache hit
2. **Tier 1**: No fuzzy match
3. **Tier 2**: BM25 search returns:
- `techniques/pricing-anchoring-via-tco.md` — score 0.92 (title exact match + keywords)
- `techniques/roi-calculator-walkthrough.md` — score 0.45 (mentions pricing)
- Gap: 0.92 vs 0.45 = clear winner
4. **Result**: Return `pricing-anchoring-via-tco.md` content directly. **No LLM call.**
### Example: "how do I handle security objections in enterprise deals" Query
1. **Tier 0-1**: No cache hit
2. **Tier 2**: BM25 returns multiple relevant results with close scores (0.71, 0.68, 0.65)
3. **Tier 3**: Escalate to LLM pre-fetch
- Inject top 3 results: `objections/security-compliance.md`, `variants/enterprise-inbound.md`, `patterns/discovery-winners.md`
- LLM synthesizes: "In enterprise deals, security objections typically arise in [stage]. Effective approaches include [technique 1] (67% win rate) and [technique 2]..."
4. **Result**: Synthesized answer with citations to wiki pages
---
## Advantages Over Embedding Approach
| Factor | Embedding/Turbopuffer | Wiki/Docs |
|--------|----------------------|-----------|
| **Query accuracy** | Similarity misses structure, roles, negation | Explicit links capture exact relationships |
| **Cost** | Embedding generation + vector DB ops on every event | Write once, read many |
| **Transparency** | Black-box similarity scores | Human-readable markdown, version controlled |
| **Maintenance** | Vectors drift, need re-embedding | Wiki is self-documenting, contradictions flagged |
| **Compounding** | Same patterns rediscovered each query | Knowledge accumulates, cross-references build |
| **Context window** | Retrieved chunks may miss critical context | Pages designed for coherent reading |
---
## Implementation Path
### Phase 1: Wiki Schema + Seeding (1 week)
- [ ] Add new `DOCUMENT_TYPE` values: `WIKI_TECHNIQUE`, `WIKI_OBJECTION`, `WIKI_VARIANT`, `WIKI_STAGE`, `WIKI_PATTERN`, `WIKI_INDEX`, `WIKI_LOG`
- [ ] Define frontmatter schema: `title`, `summary`, `keywords`, `tags`, `related`, `outcome_stats`, `importance`, `maturity`
- [ ] Define grep-able formatting conventions:
- Section headers: `## SUMMARY`, `## WHEN_TO_USE`, `## EXAMPLES`, `## PATTERNS`, `## RELATED`
- Example entries: `### [YYYY-MM-DD] Rep Name | Company | Outcome`
- Log entries: `## [YYYY-MM-DD] action | path | description`
- [ ] Create `_index.md`, `_schema.md`, and `_log.md` templates
- [ ] Seed initial pages from existing KB articles + AOP methodology
### Phase 2: Extraction → Wiki Update Pipeline (2 weeks)
- [ ] Modify extraction output to include wiki update instructions
- [ ] Create wiki update agent that:
- Parses extraction output
- Decides: update existing page vs create new page vs skip
- Maintains cross-references
- Updates `_index.md` and `_log.md`
- [ ] Auto-generate `.abstract.md` summaries (~80 tokens) on page create/update
- [ ] Run on historical meeting transcripts to backfill
### Phase 3: Outcome Propagation + Scoring (1 week)
- [ ] On deal close: update outcome stats on all related pages
- [ ] Recalculate win rates on technique/variant pages
- [ ] Implement importance scoring: +3 per search hit, +5 per update, decay 0.995^days
- [ ] Implement maturity tiers: draft (<65) → validated (≥65) → core (≥85)
- [ ] Flag contradictions (technique claims high win rate, recent data says otherwise)
### Phase 4: 5-Tier Retrieval Infrastructure (1.5 weeks)
- [ ] **Tier 0**: Exact cache — Redis/in-memory LRU keyed by `{orgId}:{query_md5}`, 60s TTL
- [ ] **Tier 1**: Fuzzy cache — Jaccard similarity on query tokens, ≥60% match returns cached
- [ ] **Tier 2**: BM25 direct — extend `grepDocuments` to score on frontmatter fields
- Implement compound scoring: `0.6×BM25 + 0.2×importance + 0.2×recency`
- Apply maturity tier boosts (core ×1.15, draft ×0.85)
- Score-gap filter: drop results below 70% of top score
- If top result ≥0.85 with clear gap, return directly (no LLM)
- [ ] **Tier 3**: LLM pre-fetch — inject top 3 results as context, single LLM call
- [ ] **Tier 4**: Agentic loop — full agent with `readDocument`, link traversal
- [ ] Out-of-domain detection: if no results above threshold, return "not covered"
### Phase 5: Agent Wiki Access (1 week)
- [ ] Create `queryWikiTool` that implements 5-tier strategy
- [ ] Add wiki navigation to agent context (include `_index.md` in preamble)
- [ ] Teach agent to follow `[[wikilinks]]` via `readDocument` calls
- [ ] Replace `searchIntelligenceTool` calls with `queryWikiTool` in sales-intelligence skill
### Phase 6: Wiki Analytics Layer (1 week)
- [ ] Implement `queryWikiTool` with grep-based aggregation:
- `win_rate_ranking` — sort pages by frontmatter `win_rate`
- `rep_usage` — count rep names in example prefixes
- `outcome_by_stage` — parse stage from examples, group by outcome
- `example_count` — count `^### \[` lines
- `custom_grep` — flexible pattern for ad-hoc queries
- [ ] Compute-on-write: update `outcome_stats` when examples added
- [ ] Outcome propagation: when deal closes, update all referencing examples
- [ ] Frontmatter index: cache parsed frontmatter for fast ranking queries
### Phase 7: DB Fallback for Raw Data (0.5 weeks)
- [ ] Identify queries wiki can't answer:
- Stage timing (needs `crm_conversation_updates`)
- Activity cadence (needs `crm_events`)
- Deal size distribution (needs `crm_conversations`)
- [ ] Build constrained query templates for these specific cases
- [ ] Route detection: wiki-answerable vs DB-fallback
### Phase 8: Process Variant Discovery (2 weeks)
- [ ] Cluster deal trajectories to discover variants (same as before)
- [ ] But output is wiki pages, not database rows
- [ ] Variant pages link to techniques/patterns that characterize them
### Phase 9: Periodic Consolidation (ongoing)
- [ ] Weekly lint job: find orphans, contradictions, gaps
- [ ] Regenerate pattern summaries from updated technique pages
- [ ] Archive low-importance drafts (importance <35 after decay)
- [ ] Surface suggestions: "New objection type detected, needs page"
- [ ] Update wiki pages with fresh analytics stats
---
## Analytics: The Wiki IS the Queryable Data
### Key Insight: No Separate Extraction Needed
If the wiki is formatted consistently, **the wiki itself IS the structured data**. The grep-able formatting convention means analytics queries can run directly on wiki content.
Example entries in `objections/budget-timing.md`:
```markdown
### [2026-03-15] Sarah Chen | Acme Corp | Won
### [2026-04-02] Mike Torres | Globex | Won
### [2026-04-18] Jennifer Wu | Initech | Lost
### [2026-04-22] Alex Kim | Megacorp | Lost
### [2026-04-25] Sarah Chen | TechStart | Lost
```
To answer "Which objections lead to closed-lost?":
```bash
# Count won vs lost examples in each objection file
for f in objections/*.md; do
name=$(basename "$f" .md)
won=$(grep -c '| Won$' "$f")
lost=$(grep -c '| Lost$' "$f")
total=$((won + lost))
loss_rate=$(echo "scale=2; $lost / $total" | bc)
echo "$name: Won=$won Lost=$lost LossRate=$loss_rate"
done
```
Output:
```
budget-timing: Won=2 Lost=3 LossRate=0.60
security-compliance: Won=8 Lost=6 LossRate=0.43
implementation-timeline: Won=5 Lost=2 LossRate=0.29
```
**No pre-extraction. No separate database. The wiki format IS the analytics layer.**
### Three Analytics Modes
| Mode | Speed | How It Works |
|------|-------|--------------|
| **Frontmatter read** | ~50ms | Parse YAML `outcome_stats` from page headers |
| **Grep aggregation** | ~100-500ms | Count patterns across wiki files |
| **Computed on write** | 0ms at query | Stats updated when examples added |
### Mode 1: Frontmatter Stats (Fastest)
Every page has pre-computed stats in frontmatter:
```yaml
outcome_stats:
used_in: 12
won: 8
lost: 4
win_rate: 0.67
stages_used: [discovery, demo]
variants: [enterprise-inbound]
```
Query "Which techniques have best win rate?":
```bash
# Extract win_rate from all technique frontmatters
for f in techniques/*.md; do
name=$(basename "$f" .md)
win_rate=$(grep "win_rate:" "$f" | head -1 | awk '{print $2}')
echo "$name: $win_rate"
done | sort -t: -k2 -rn | head -10
```
**These stats are updated every time an example is added** — computed on write, not on read.
### Mode 2: Grep Aggregation (Flexible)
For questions not covered by frontmatter stats, grep the content:
**"Which reps use pricing anchoring most?"**
```bash
grep "^### \[" techniques/pricing-anchoring-via-tco.md |
cut -d'|' -f1 |
sed 's/.*\] //' |
sort | uniq -c | sort -rn
```
Output:
```
4 Sarah Chen
3 Mike Torres
2 Jennifer Wu
```
**"What objections appear in lost enterprise deals?"**
```bash
grep -l "enterprise" objections/*.md |
xargs grep "| Lost$" |
cut -d: -f1 |
sort | uniq -c | sort -rn
```
**"Average deal cycle in won deals using this technique?"**
```bash
grep "| Won$" techniques/pricing-anchoring-via-tco.md |
grep -oP '\d+ days' |
awk '{sum+=$1; n++} END {print sum/n}'
```
### Mode 3: Cross-Wiki Aggregation
For questions spanning multiple page types:
**"Do deals with multi-threading win more often?"**
1. Find all examples in `techniques/multi-threading-*.md`
2. Extract deal names (Company column)
3. Cross-reference with deal outcomes in `deals/*.md` or frontmatter
This is where it gets more complex — but still doable with shell or a simple script.
### What the Wiki Can't Answer (Fallback to DB)
Some questions genuinely need the raw database:
| Question | Why Wiki Can't Answer | Fallback |
|----------|----------------------|----------|
| "Avg days in discovery stage" | Stage timing not in wiki | Query `crm_conversation_updates` |
| "Deal size distribution" | Not tracked per-example | Query `crm_conversations` |
| "Email response times" | Activity-level data | Query `crm_events` |
For these, we still need a constrained query layer against the CRM tables. But the scope is much narrower — most "which patterns work?" questions are answerable from the wiki.
### The `queryWiki` Tool
```typescript
const queryWikiTool = createTool({
id: 'query-wiki',
description: `Query statistics from the sales wiki. Use for questions about
technique effectiveness, objection patterns, rep comparisons, etc.
This queries the wiki directly — no separate database needed.`,
inputSchema: z.object({
query_type: z.enum([
'win_rate_ranking', // Which techniques/objections have best/worst win rate?
'rep_usage', // Which reps use a technique/handle an objection?
'outcome_by_stage', // Win rate by stage for a technique
'example_count', // How many examples in a page?
'cross_reference', // Which deals appear in multiple pages?
'custom_grep' // Flexible grep pattern
]),
target: z.string().describe('Page path or pattern, e.g. "techniques/*.md"'),
filter: z.object({
outcome: z.enum(['Won', 'Lost', 'any']).optional(),
rep: z.string().optional(),
date_from: z.string().optional(),
date_to: z.string().optional()
}).optional()
}),
execute: async ({ query_type, target, filter }, context) => {
// Executes grep/awk patterns against wiki files
// Returns structured results
}
});
```
### Compute on Write, Not on Read
**When adding an example to a page:**
1. Append the example with grep-able prefix
2. Re-count `| Won$` and `| Lost$` patterns
3. Update frontmatter `outcome_stats`
4. Update `_index.md` summary if win_rate changed significantly
**When a deal closes:**
1. Find all pages that reference this deal
2. Update each example's outcome (if it was `| Open` → `| Won` or `| Lost`)
3. Recalculate frontmatter stats
4. Log the propagation in `_log.md`
This means **most analytics queries hit pre-computed data** — the expensive computation happened at write time.
### When to Use Which
| User Question | Mode | Why |
|---------------|------|-----|
| "Which objections kill deals?" | Frontmatter | Read `win_rate` from each `objections/*.md` |
| "Which reps are best at discovery?" | Grep | Count rep names in `stages/discovery.md` examples |
| "How should I handle budget objections?" | Wiki retrieval | Read the page content |
| "Avg days in discovery stage?" | DB fallback | Stage timing not in wiki |
| "Does Sarah close faster than Mike?" | Grep + compute | Extract cycle times from examples by rep |
### The "Infinite Queries" Problem — Resolved
Your concern: "there are infinite things we could track that we can't think of upfront."
The wiki format solves this:
- **Structured prefixes** = queryable without pre-defining fields
- **Frontmatter stats** = common aggregations pre-computed
- **Grep flexibility** = any pattern you can express is queryable
- **DB fallback** = for truly raw data (timing, activity counts)
You don't pre-extract "objection type" as a database field. You just create pages in `objections/`. The directory structure IS the categorization. The example prefixes ARE the queryable records.
---
## What About Existing Turbopuffer Data?
**Keep it for now.** The wiki is the primary interface, but vector search can be a fallback:
- If agent can't find relevant wiki page via navigation → fall back to similarity search
- Vector search becomes "I don't know where this is" exploration mode, not primary retrieval
- Over time, as wiki coverage grows, vector search usage should decline
The key shift: **vector search is exploration, wiki is knowledge, analytics is computation**.
---
## Agent Operating Rules (Research-Based)
Based on implementations of Karpathy's LLM Wiki pattern:
- [balukosuri/llm-wiki-karpathy](https://github.com/balukosuri/llm-wiki-karpathy)
- [arturseo-geo/llm-knowledge-base](https://github.com/arturseo-geo/llm-knowledge-base)
- [gayawellness/anamnesis](https://github.com/gayawellness/anamnesis)
### `_schema.md` — Agent Operating Manual
This file is read at the start of every wiki operation. Full template:
```markdown
# Sales Wiki — Agent Operating Rules
> Version: 1.0.0 | Org: {orgId}
## Purpose
Org-level sales knowledge base maintained by Cedar's AI agent.
Contains patterns extracted from conversations, curated reference content,
and agent-generated playbooks.
## Session Startup
Before any wiki operation, agent:
1. Reads _schema.md (this file)
2. Reads _index.md (catalog of all pages)
3. Notes any pages marked needs_review: true
4. Confirms ready state
## Directory Structure
wiki/
├── _index.md # Master catalog
├── _schema.md # This file
├── _log.md # Chronological activity log
├── _proposals/ # Proposed new categories (human approval required)
├── techniques/ # Sales techniques
│ └── playbooks/ # Generated guides
├── objections/ # Objection handling
│ └── playbooks/
├── competitors/ # Competitive intel
│ └── playbooks/
├── stages/ # Stage-specific patterns (seeded from org AOP)
│ └── playbooks/
├── product/ # Product knowledge (curated + enriched)
│ └── playbooks/
└── customers/ # Customer knowledge
└── playbooks/
## Page Types and Frontmatter
### Pattern Pages (techniques/, objections/, competitors/, stages/)
---
type: technique | objection | competitor | stage
title: "Page Title"
summary: "One-line description"
keywords: [keyword1, keyword2]
source: extracted | curated | hybrid
maturity: draft | validated | core
outcome_stats:
used_in: 12
won: 8
lost: 4
win_rate: 0.67
related:
- path/to/related-page.md
created: 2026-05-04
updated: 2026-05-04
---
### Reference Pages (product/, customers/)
---
type: feature | value_prop | testimonial | use_case | case_study
title: "Page Title"
summary: "One-line description"
source: curated | hybrid
last_verified: 2026-05-04
owner: marketing | sales | product
related:
- path/to/related-page.md
---
### Playbook Pages (*/playbooks/)
---
type: playbook
title: "Discovery Call Guide"
created_by: agent | user
derived_from:
- stages/discovery.md
- techniques/question-layering.md
last_generated: 2026-05-04
needs_review: false
---
## Example Format (Grep-able)
All examples follow this format for analytics:
### [YYYY-MM-DD] Rep Name | Company Name | Outcome
[[conversation: conv_id]] [[event: evt_id]]
**Stage:** Stage Name | **Call type:** Type
> "Verbatim quote from transcript..."
**Outcome:** Description of result
## When to Create vs Update
### Add example to EXISTING page when:
- New extraction matches an existing technique/objection/competitor
- Grouping key (competitorName, objectionTheme, skillArea) matches existing page
- Content adds another instance of a documented pattern
### Create NEW page when:
- Grouping key doesn't match any existing page
- Pattern is distinct enough to warrant its own page
- At least 2 examples of the pattern exist (avoid single-instance pages)
### Propose NEW CATEGORY when:
- Multiple extractions don't fit any existing category
- Pattern is significant and recurring
- Write to _proposals/{category-name}.md and await human approval
## Autonomous vs Approval-Required
### Autonomous (background events — emails, meetings):
- Add examples to existing pages
- Update outcome_stats
- Create new pages within existing categories
- Update _index.md
- Append to _log.md
- Update related links
### Requires Approval (live chat additions):
- Create new top-level categories
- Delete pages
- Major restructuring
- Generate playbooks (unless explicitly requested)
## Maturity Progression
| Level | Criteria | Agent Action |
|-------|----------|--------------|
| draft | <3 examples OR single source | Default for new pages |
| validated | 3+ examples with consistent outcomes | Auto-promote when criteria met |
| core | Foundational pattern, high confidence | Human designation only |
## Playbook Management
Playbooks are derived from pattern pages.
### When to flag needs_review: true
- Source patterns (derived_from pages) have significant new examples
- Win rate changed by >10% since generation
- New related patterns emerged
### Auto-regeneration rules
- If created_by: agent → can auto-regenerate and flag for review
- If created_by: user → never auto-modify, flag only
## Index Maintenance
Update _index.md after EVERY write operation.
## Log Format
_log.md is append-only, newest first:
## 2026-05-04
### Meeting: Acme Corp Discovery Call
- Added example to techniques/question-layering.md
- Added example to objections/budget-timing.md
- Updated outcome_stats on 2 pages
### Ingest: competitor-x mentioned
- Created new page: competitors/competitor-x.md
- Added to _index.md
## Lint Checklist
Periodic health check:
- [ ] Every page in wiki/ appears in _index.md
- [ ] Every [[wikilink]] resolves to a real file
- [ ] No two pages cover the same pattern
- [ ] outcome_stats match actual example counts
- [ ] Playbooks with stale sources marked needs_review: true
- [ ] Orphan pages (no inbound links) flagged
## Naming Conventions
- Filenames: lowercase, hyphens, no spaces
- Example: `pricing-anchoring-tco.md` not `Pricing Anchoring TCO.md`
- Playbooks: `{topic}-guide.md`, `{topic}-checklist.md`
## Conflict Resolution
When sources conflict:
1. Note the conflict explicitly in the page
2. Cite both sources with their outcomes
3. Mark page as maturity: draft until resolved
4. Flag for human review if significant
```
### `_index.md` — Master Catalog
```markdown
# Sales Wiki Index
> Last updated: 2026-05-04 | Total pages: 47
## Quick Stats
- Techniques: 12 pages, 89 examples
- Objections: 8 pages, 56 examples
- Competitors: 4 pages, 23 examples
- Stages: 5 pages, 67 examples
- Product: 15 pages
- Customers: 3 case studies, 12 testimonials
---
## Techniques
| Page | Maturity | Win Rate | Examples | Updated |
|------|----------|----------|----------|---------|
| [Pricing Anchoring via TCO](techniques/pricing-anchoring-tco.md) | validated | 67% | 12 | 2026-05-04 |
| [Multi-threading](techniques/multi-threading.md) | validated | 72% | 8 | 2026-05-03 |
| [Question Layering](techniques/question-layering.md) | draft | -- | 3 | 2026-05-02 |
### Playbooks
- [Pricing Conversation Guide](techniques/playbooks/pricing-guide.md)
---
## Objections
| Page | Maturity | Overcome Rate | Examples | Updated |
|------|----------|---------------|----------|---------|
| [Budget Timing](objections/budget-timing.md) | validated | 45% | 11 | 2026-05-04 |
| [Security Compliance](objections/security-compliance.md) | validated | 78% | 9 | 2026-05-03 |
### Playbooks
- [Common Objections Cheatsheet](objections/playbooks/common-objections.md)
---
## Competitors
| Page | Maturity | Win Rate vs | Examples | Updated |
|------|----------|-------------|----------|---------|
| [Competitor X](competitors/competitor-x.md) | draft | 55% | 7 | 2026-05-04 |
| [Status Quo](competitors/status-quo.md) | validated | 62% | 16 | 2026-05-03 |
### Playbooks
- [Competitor X Talk Track](competitors/playbooks/competitor-x-talk-track.md)
---
## Stages
| Page | Maturity | Examples | Updated |
|------|----------|----------|---------|
| [Discovery](stages/discovery.md) | validated | 23 | 2026-05-04 |
| [Demo](stages/demo.md) | validated | 18 | 2026-05-03 |
| [Technical Review](stages/technical-review.md) | draft | 5 | 2026-05-02 |
| [Proposal](stages/proposal.md) | validated | 12 | 2026-05-01 |
| [Negotiation](stages/negotiation.md) | draft | 9 | 2026-05-01 |
### Playbooks
- [Discovery Call Guide](stages/playbooks/discovery-call-guide.md)
- [Demo Prep Checklist](stages/playbooks/demo-prep-checklist.md)
---
## Product
| Page | Type | Last Verified | Updated |
|------|------|---------------|---------|
| [Workflow Automation](product/features/automation.md) | feature | 2026-05-01 | 2026-05-04 |
| [Integrations](product/features/integrations.md) | feature | 2026-04-15 | 2026-05-02 |
| [Value Props](product/value-props.md) | value_prop | 2026-05-01 | 2026-05-03 |
| [ROI Examples](product/roi-examples.md) | testimonial | -- | 2026-05-04 |
---
## Customers
### Case Studies
| Page | Outcome | Deal Size | Updated |
|------|---------|-----------|---------|
| [Acme Corp Q1 2026](customers/case-studies/acme-corp-2026-q1.md) | Won | $180K | 2026-04-15 |
### Testimonials
- [Customer Testimonials](customers/testimonials.md) — 12 examples
### Use Cases
| Page | Updated |
|------|---------|
| [Enterprise Sales](customers/use-cases/enterprise-sales.md) | 2026-05-01 |
---
## Pending Review
| Page | Reason | Flagged |
|------|--------|---------|
| [Discovery Call Guide](stages/playbooks/discovery-call-guide.md) | Source patterns updated | 2026-05-04 |
---
## Recent Activity
See [_log.md](_log.md) for full history.
```
### Key Decision Rules (From Research)
| Scenario | Rule |
|----------|------|
| Background event (email/meeting) | Autonomous write allowed |
| Live chat addition | Requires user approval |
| New page in existing category | Autonomous if 2+ examples exist |
| New top-level category | Write proposal, await approval |
| Playbook generation | Autonomous only if user requested topic |
| Playbook update | Agent-created: auto-update + flag; User-created: flag only |
| Conflicting info | Note both sources, mark draft, flag for review |
| Orphan page detected | Flag in lint, don't auto-delete |
| Page < 3 examples | maturity: draft, auto-promote when 3+ |
### Authority Hierarchy (From Anamnesis Pattern)
| Authority | Who Sets It | Initial Trust |
|-----------|-------------|---------------|
| explicit | User stated directly (curated content) | Highest |
| hybrid | Curated + enriched with extractions | Medium-high |
| extracted | Agent-derived from conversations | Lowest initially |
Extracted content starts low-trust but earns weight via:
- Multiple occurrences (3+ examples → validated)
- Positive outcome correlation (high win rate → validated)
- Human confirmation (explicit maturity upgrade → core)
---
## Open Questions
1. **Page creation authority**: Does agent auto-create pages, or flag for human review? Probably: auto-create for updates to existing pages, flag for net-new pages.
2. **Version control**: Should wiki pages be in git? Cedar Docs already has versioning via `version` field. Git adds diff visibility but complicates deployment.
3. **Multi-org patterns**: Can we have a "template wiki" that seeds new orgs, then diverges? Or is each org wiki fully independent?
4. **Threshold for page creation**: What qualifies as a "technique" worth its own page? Probably: 3+ occurrences across different deals, or explicit user designation.
5. **Wiki size limits**: How big can the wiki get before `_index.md` is too large? ByteRover claims their approach works at ~100 sources / hundreds of pages. May need hierarchical index at scale.
6. **Hybrid navigation**: Should `_index.md` include embeddings for fallback semantic search within the wiki? Or pure BM25?
7. **Cache invalidation**: When wiki page updates, how do we invalidate affected cache entries? Options: TTL-only (simple), page-version tracking (precise), full cache clear on any write (conservative).
8. **BM25 implementation**: Use Postgres full-text search (`tsvector`/`tsquery`)? Or external like Meilisearch/Typesense? Cedar already has `grepDocuments` with regex — may need proper FTS for scoring.
9. **Importance tracking**: Where to store hit counts and importance scores? Options: in frontmatter (simple, versioned), in sidecar table (faster updates, not versioned), in Redis (fastest, ephemeral).
10. **Abstract generation timing**: Generate `.abstract.md` synchronously on page write (simpler, slower writes) or async in background queue (faster writes, eventual consistency)?
11. **Grep performance at scale**: How many wiki files before grep becomes slow? Probably fine up to 1000s of files. May need indexed search (like ripgrep) for larger wikis.
12. **Frontmatter parsing**: Parse YAML on every query, or maintain a separate frontmatter index/cache? Cache is faster but needs invalidation on write.
13. **Example format flexibility**: What if someone wants to track more fields per example (deal size, cycle time)? Extend the prefix format? Add structured YAML per example?
14. **DB fallback scope**: Which raw-data queries are common enough to pre-build? Stage timing is obvious. What else?