# Mentions
An `@mention` addresses a person from inside an issue. tix records every mention it finds
when an issue is written, and shows a mention to the person it names the next time they
open that issue.
## The token
A mention is an `@` at a **boundary** followed by either a handle or a full email:
```
email := [A-Za-z0-9._-]+ '@' [A-Za-z0-9-]+ ('.' [A-Za-z0-9-]+)+
```
| `@herbert-maschke` | yes — the username slug the `docs/issues/<username>/` folder uses | `docs/mentions/herbert-maschke.toml` |
| `@thyseus@pm.me` | yes — a full email | `docs/mentions/thyseus-pm-me.toml` |
| `contact herbert@example.com` | **no** — no `@` sigil at a boundary | — |
| `foo-@alice` | **no** — `-` is part of the handle grammar, so there is no boundary | — |
| `` `@alice` `` / inside a fenced block | **no** — code is quoting, not addressing | — |
Both the issue's **title** and its **body** (including `## Comments`) are scanned. Every
surface that writes an issue reconciles mentions: `tix create`, `tix edit` (including the
`$EDITOR` round trip), `tix move`, `tix bulk`, the TUI's forms, and MCP's `update_issue` /
`comment_on_issue`.
Reconciliation is deliberately **command-driven**. If another editor or tool writes an
issue file directly, the TUI still notices the file change and refreshes the board, but it
does not write the mention store from that passive observation. A mention added outside
tix becomes pending when the next tix-mediated write persists that issue, or when a later
tool/import routes the content through the same store seam. This avoids granting a
filesystem watcher authority to mutate a second store without a command in flight.
## What is recorded, and where
One TOML file per mentioned target, under `docs/mentions/`, named after the **slug of the
mention body**:
```toml
# Mentions awaiting herbert-maschke. Safe to read and edit by hand.
[[mention]]
id = "MSHGDYS7Z" # addressable from `tix mentions`
key = "a9e15e92f929aa44" # the occurrence's content fingerprint
issue_number = 1
issue_id = "VPHEDVJ4"
issue_file = "herbert-maschke/default/triage/2026-10-10-VPHEDVJ4-fix-login.md"
body = "herbert-maschke" # the mention exactly as written
context = "blocked on @herbert-maschke's review"
created = "2026-10-10T10:56:28Z"
The file is the **live pending set**, not a log: a mention whose text is removed from the
issue stops being listed, and an emptied file is deleted (the `docs/mentions/` directory is
left where it is, so the next mention does not have to recreate it). Unknown keys you add by
hand are preserved when tix rewrites the file.
A **read** record is deliberately kept rather than deleted. The mention text is usually still
in the issue, so a dropped record would be re-created as `unread` by the very next
reconciliation and the mention would notify again — the state is the only thing standing
between "acknowledged" and "new".
### Why the `key`, and not a count
Mentions get inserted before and after one another, so an ordinal position — or the number
of mentions in a file — is the wrong identity. Each occurrence is keyed by a fingerprint of
the issue's id and number, the mention body, and the **normalized line it sits on**. Inserting
a new mention elsewhere in the issue does not disturb the existing keys; editing the sentence
a mention sits in re-anchors it, and a merely cosmetic edit (a typo fix) carries the recorded
state over instead of notifying again.
## You are identified by git
Your mention files are the ones whose names match your git identity: the slug of
`user.name`, the slug of the local part of `user.email`, and the full email. That is why
both `@herbert-maschke` and `@thyseus@pm.me` reach the same person when their git identity
is `Herbert Maschke <thyseus@pm.me>`.
No git identity (no `git`, or no `user.name`) means no mention is attributed to you, and no
command fails. Recording is unaffected: mention files are written whoever runs tix, because
the writer only knows the token, not who it belongs to.
## Answering a mention
Three answers, and only the third writes anything:
| **jump** | opens the issue, scrolls the mention to the top of the pane, and highlights its line |
| **ignore** | changes nothing, so the mention is shown again next time |
| **mark read** | records `state = "read"`, so it is never shown as pending again |
In the **TUI**: an issue you open that has unread mentions for you shows a notice; `Enter`
jumps, `i` ignores, `r` marks read. Jumping scrolls the mention's line to the top of the
pane and highlights it (a yellow background) so it stands out from the body. The issue body
is rendered as markdown — headings, emphasis, lists, code and links — and a ```mermaid
block renders as a diagram rather than literal source. Whenever you have at least one unread mention the board
draws an extra line above the hint bar — `@ N unread mentions — press i to open` — and that
chord opens the view of your pending mentions across every issue. That view is also put up
for you without the chord: starting the TUI with unread mentions opens it first, and a
mention that lands while the session is already open (a `git pull` reconciling one into
`docs/mentions/`) opens it within about a second, because the TUI watches the mention
directory. Both only raise from the board — a form or another modal keeps its place, and an
already-open view is refreshed in place instead of interrupted.
In the **CLI**, without a prompt, so it works from a script and without a TTY:
```console
$ tix mentions list
MSHGDYS7Z #1 blocked on @herbert-maschke's review
$ tix mentions jump MSHGDYS7Z
MSHGDYS7Z #1
herbert-maschke/default/triage/2026-10-10-VPHEDVJ4-fix-login.md:1
blocked on @herbert-maschke's review
$ tix mentions read MSHGDYS7Z
marked read: MSHGDYS7Z
```
`tix view <issue>` also appends a `Mentions for you` block when you have pending mentions on
that issue, naming the ids the three verbs take.
Over **MCP**: `mentions_list` and `mentions_mark_read`.
## Configuration
```toml
[mentions]
enabled = true # default; false stops the scan and every write
dir = "docs/mentions" # default; relative to the project root
```
Omitting the section is the same as `enabled = true` with the default directory, and tix
never writes the section into a `tix.toml` that did not have it. The `docs/mentions/`
directory is created lazily — only once a mention is actually recorded — so a repository
with no mentions gains no directory.