# Design: Enhanced Context People Section

**Date:** 2026-02-24
**Status:** Approved

## Problem

`kbx context` treats all people identically — one compressed line with role snippet and mention count. Pinned people (explicitly marked important) and key people (with rich metadata) get the same treatment as random low-mention names. The brief-deck UI already groups people into pinned/key/all tiers; the CLI context should follow suit.

## Design

### Two-tier model, no "others" tail

Replace the single `[People:N by mentions]` section with two sub-sections:

**Pinned people** — full metadata inline:
```
[People:pinned]
Jeremy★(CTO|team:Leadership|→Eric Thomé,5719m)
Eric★(CEO/Founder,1265m)
Pierre★(Eng Director|team:Engine|→Jeremy,1184m)
```

Format: `Name★(Role|team:Team|→ReportsTo,Nm)`
- Role truncated at 20 chars (as today)
- `team:X` shown if present
- `→ReportsTo` shown if present
- Mention count always shown

**Key people** — role + reports_to:
```
[People:key]
Henri(Eng Director|→Jeremy,1066m)|Guillaume(VP EMEA Sales|→Eric,984m)
Gregory(VP People|→Eric,886m)|Philippe(EM|→Pierre,821m)
```

Format: `Name(Role|→ReportsTo,Nm)`
- Role truncated at 20 chars
- `→ReportsTo` shown if present
- No team (saves tokens vs pinned)
- Mention count always shown

**No "others" tail** — people who are neither pinned nor key do not appear. The `→kb entity find "name" --json` hint remains for discovery.

### Key person definition

Mirrors brief-deck's `_has_person_detail()`:
- Unpinned person with 2+ metadata fields from {role, team, company, reports_to}, OR
- 1+ facts in the `facts` table

### Human format (`--human`)

Same two-tier split with markdown headers:
```
## Pinned People (3)
|Jeremy★(CTO, Leadership, →Eric Thomé) ...
## Key People (8)
|Henri(Eng Director, →Jeremy) |Guillaume(VP EMEA Sales, →Eric) ...
```

### Topic mode

Unchanged — shows all relevant entities without tier filtering.

## Implementation

### New helpers in `context.py`

1. `_get_fact_counts(conn)` — `SELECT entity_id, COUNT(*) FROM facts GROUP BY entity_id`
2. `_is_key_person(entity, fact_counts)` — True if 2+ detail keys or facts > 0
3. `_format_person_pinned(entity)` — full metadata format
4. `_format_person_key(entity)` — role + reports_to format

### Changes to existing code

1. `generate_context()` — split people into `pinned_people` and `key_people` lists (drop others)
2. `_render_compact()` — accept `pinned_people` and `key_people` separately, render two sub-sections
3. `_render_human()` — same, with `## Pinned People` and `## Key People` headers
4. Existing `_format_person_compact()` and `_format_person()` can be removed or kept for topic mode

### Test plan

- Pinned people show full metadata (team, reports_to) in output
- Key people show reports_to in output
- "Others" (not pinned, not key) do not appear
- Fact-based key person detection works
- Topic mode unchanged
- Human format renders two sections
- Zero-mention pinned person still appears
- Person with only 1 metadata field and no facts excluded (not key)

## Token impact

Roughly neutral. Fewer people (~8-12 vs 15), but pinned entries are ~50% wider. Net depends on key person count.
