## Why It Matters

Reviews written from memory systematically undercount quiet, consistent shippers and overcount whoever was visible in the last month. The fix isn't surveillance — it's letting the [AI drafter](/docs/performance-ai-drafted-reviews) *cite* real work at draft time: the merge requests someone shipped and the reviews they gave others, as titles and links a human reviewer then weighs.

Kit's signal layer is built on a hard architectural choice: **fetch-on-demand, zero persistence**. Signals are pulled live when a reviewer generates a draft, distilled into that draft's disclosure digest, and discarded. Kit never becomes an activity warehouse — there is no dashboard of commit counts, no leaderboard, and structurally no way to compare people, because the data isn't stored to compare.

> [!WARNING]
> Signals produce narrative evidence, never scores. No volume metrics or diff stats are collected, no cross-person comparison surface exists, and drafting is opt-in per draft with full disclosure to the reviewee. If you want a productivity leaderboard, this feature will actively disappoint you — by design.

## Connecting GitLab

GitLab is the v0 provider (one connection per account). Go to [Performance > Work signals](/performance/signal_source):

| Field | Value |
|-------|-------|
| GitLab URL | `https://gitlab.com`, or your self-hosted instance's URL — self-hosted is fully supported (HTTPS, publicly reachable host) |
| Group access token | A **read_api** Group Access Token with the **Reporter** role — or a service-account PAT on the Free tier |

Press **Connect GitLab**. The token is encrypted at rest and shown only masked afterwards. Kit uses read-only API access; it never writes to your GitLab. If the connection later errors (revoked token, unreachable host), the source trips to **Error** with the failure message shown — re-enter credentials to reconnect. Drafts generated while a source is down simply proceed without signals, noting the source was unavailable.

## Confirming Identities

Signals are fetched per person, so each team member must be mapped to their GitLab username — and the mapping must be **confirmed by an admin** before it's ever used. This is the fence against the obvious failure: a typo'd username must never pull a stranger's activity into someone's review. Unconfirmed mappings are refused at fetch time, full stop.

Under **Identity mapping**, add each member's GitLab username — Kit prefills a suggestion by looking the person up by email on your GitLab where it can — then confirm it. Members without a confirmed mapping are silently skipped when drafting; nothing is fetched for them.

## What Is Gathered

At draft time, with the per-draft opt-in ticked, Kit fetches for the review period (the cycle's period, or the last 6 months if unset):

| Signal | Meaning |
|--------|---------|
| Merged merge requests | Work the person shipped |
| Review activity | MRs the person reviewed for others — glue work most tools ignore |

Each signal is **title, link, date, and repo — nothing else**. No diff sizes, no line counts, no commit frequencies. Two AI-era annotations are derived on the fly: **AI authorship** (commit trailers like `Assisted-by:`/`Co-Authored-By:` naming coding agents — the drafter credits direction and review rigor, never inflated volume) and **AI-enablement work** (changes to skills, agent configs, MCP tools, prompts — multiplier work the drafter is instructed to credit explicitly).

## Opt-in, Disclosure, and Refusal

- **Per-draft opt-in** — signals are used only when the reviewer ticks "Include work signals from GitLab (opt-in for this draft)." Never by default, never covertly.
- **Reviewee disclosure** — every signal used is listed in the review's disclosure panel, visible to the reviewee before finalization: exactly which items, fetched when, with the note that no metrics or activity data were stored.
- **Human gate downstream** — a signal-informed draft still faces the [edit-or-own submission gate](/docs/performance-ai-drafted-reviews); signals inform a human's assessment, they never become one.
- **Tool-invisible work has a channel** — the self-review's **Your own notes** field exists precisely because mentoring, incidents, and unblocking others don't show up in a code host.

> [!NOTE]
> For German tenants: works-council co-determination (BetrVG §87(1) Nr. 6) covers systems *capable* of monitoring performance. Kit's fetch-on-demand, no-warehouse design is the right starting posture, but involve your works council before connecting a source.

## Quick Checklist

- [ ] Create a read_api Group Access Token (Reporter) in GitLab
- [ ] Connect it in [Performance > Work signals](/performance/signal_source) — gitlab.com or self-hosted
- [ ] Map and **confirm** each member's GitLab username
- [ ] Tell the team signals exist and are opt-in per draft — no covert use, ever
- [ ] Remind reviewees to use **Your own notes** for work GitLab can't see

## Next Steps

- [AI-Drafted Reviews](/docs/performance-ai-drafted-reviews) — where signals actually surface
- [Performance Reviews Overview](/docs/performance-reviews-overview) — how the signal layer fits the whole module