Look up who an alias belongs to (people) or what a channel id is (channels) using state/identities.yaml. Use when the operator or a turn-context refers to a platform-prefixed id ("who is discord-100000000000000001?", "what channel is slack-C100?") or you need to resolve aliases the other direction (canonical → display name + aliases). Read-side only — the populator (mimir.identities_populator) maintains the registry.
Scanned 9/1/2026
Install to Claude Code
npx -y skills add jasoncarreira/mimir --skill identity-lookup --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Identity Lookup?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jasoncarreira-identity-lookup)More formats (shields.io, HTML) on the badges page.
---
name: identity-lookup
description: Look up who an alias belongs to (people) or what a channel id is (channels) using state/identities.yaml. Use when the operator or a turn-context refers to a platform-prefixed id ("who is discord-100000000000000001?", "what channel is slack-C100?") or you need to resolve aliases the other direction (canonical → display name + aliases). Read-side only — the populator (mimir.identities_populator) maintains the registry.
success_criteria:
# Lookup happens via Bash + YAML parsing of identities.yaml (the
# portable form documented in the skill body), or the in-tree
# IdentityResolver path. Both pin to identifiable command shapes.
any_of:
- tool_call:
name: Bash
args:
command_glob: "*identities.yaml*"
- tool_call:
name: Bash
args:
command_glob: "*IdentityResolver*"
- tool_call:
name: Read
args:
file_path_glob: "*state/identities.yaml"
---
<!-- desc: Look up who an alias belongs to (people) or what a channel id is (channels) using state/identities.yaml. -->
# Identity Lookup
Read-side query skill against `state/identities.yaml`. The file carries
two parallel registries:
- **`people:`** — operator-managed canonical person ids and their
platform aliases (`discord-<id>`, `slack-<id>`, `bsky:<handle>`,
`email:<addr>`).
- **`channels:`** — operator-managed canonical channel ids with
display names and `kind` (`public` | `dm` | `guild-meta` | other).
The daily populator (chainlink #44 / `mimir.identities_populator`)
auto-fills entries from connected bridges. This skill is for
*reading* — never edit `identities.yaml` from a turn; the file is
operator-managed and the populator handles updates.
## When to use
The operator or a recent-activity rendering surfaces a platform-prefixed
id and you need to know what / who it is:
- "Who is discord-100000000000000001?"
- "What channel is slack-C100 / discord-100000000000000002?"
- "What aliases does jason have?"
- "Is this a known person or just a raw id?"
Especially useful right after Phase C (chainlink #43) cross-channel
surfacing landed — recent-activity now spans all public channels, so
unfamiliar channel ids and author ids appear more often. This skill is
the canonical resolution path.
## How to use
The skill is a thin pattern over reading + parsing the YAML file. Use
Python (or `yq` if available) to query — `grep` works for quick checks
but YAML structure trips up greps for multi-line entries.
The bare-YAML examples below come first because they're portable
(work regardless of how mimir was installed); the typed
`IdentityResolver` path further down is the cleaner alternative when
you're already inside a Python process that has `mimir` importable.
### Resolve an alias to its canonical + record
```bash
python <<'PY'
import yaml, os
from pathlib import Path
home = Path(os.environ.get("MIMIR_HOME", os.environ["HOME"]))
doc = yaml.safe_load((home / "state" / "identities.yaml").read_text())
alias = "discord-100000000000000001"
for person in doc.get("people") or []:
if alias in (person.get("aliases") or []) or person.get("canonical") == alias:
print(f"canonical: {person['canonical']}")
print(f"display: {person.get('display_name', '(none)')}")
print(f"aliases: {', '.join(person.get('aliases') or [])}")
if person.get("notes"):
print(f"notes: {person['notes']}")
break
else:
print(f"not found: {alias}")
PY
```
### Resolve a channel id
```bash
python <<'PY'
import yaml, os
from pathlib import Path
home = Path(os.environ.get("MIMIR_HOME", os.environ["HOME"]))
doc = yaml.safe_load((home / "state" / "identities.yaml").read_text())
channel_id = "slack-C100"
for ch in doc.get("channels") or []:
if ch.get("canonical") == channel_id or channel_id in (ch.get("aliases") or []):
print(f"canonical: {ch['canonical']}")
print(f"display: {ch.get('display_name', '(none)')}")
print(f"kind: {ch.get('kind', '(unset)')}")
if ch.get("notes"):
print(f"notes: {ch['notes']}")
break
else:
print(f"not found: {channel_id}")
PY
```
### List all people / channels
```bash
python <<'PY'
import yaml, os
from pathlib import Path
home = Path(os.environ.get("MIMIR_HOME", os.environ["HOME"]))
doc = yaml.safe_load((home / "state" / "identities.yaml").read_text())
print("=== people ===")
for p in doc.get("people") or []:
name = p.get("display_name") or p["canonical"]
aliases = ", ".join(p.get("aliases") or [])
print(f" {p['canonical']:24} {name:30} aliases: {aliases}")
print("=== channels ===")
for c in doc.get("channels") or []:
name = c.get("display_name") or c["canonical"]
kind = c.get("kind", "(unset)")
print(f" {c['canonical']:32} {name:30} kind: {kind}")
PY
```
### Programmatic resolution via IdentityResolver
The runtime already loads `identities.yaml` into
`mimir.identities.IdentityResolver`. From any Python process that
has `mimir` importable (the agent's own interpreter, or a debug
shell in the same environment):
```bash
python <<'PY'
import os
from pathlib import Path
from mimir.identities import IdentityResolver
home = Path(os.environ.get("MIMIR_HOME", os.environ["HOME"]))
r = IdentityResolver(home=home)
r.reload()
# People side
print(r.resolve("discord-100000000000000001")) # → canonical (e.g. "alice")
print(r.display_name("discord-100000000000000001")) # → "Alice Anderson"
# Channels side
print(r.resolve_channel("slack-C100")) # → canonical
print(r.channel_display_name("discord-100000000000000002"))
PY
```
`IdentityResolver` is also the right entry point for any future
in-process consumer — it normalizes the YAML into typed dataclasses
(`Identity`, `Channel`) and handles malformed-input warnings on read.
## On a cache miss
If the alias / canonical isn't in `identities.yaml`:
1. **Tell the operator the id isn't registered.** Don't pretend to know.
2. **Operator can add the entry manually** if they know the answer.
The agent does NOT edit this file directly.
3. **If a daily populator is running** (chainlink #44 /
`mimir.identities_populator`, opt-in via
`MIMIR_IDENTITIES_POPULATE_CRON`) and the file's mtime is more
than 24h old, suggest the operator re-run it — it scrapes
connected Discord guilds + Slack workspaces and fills missing
entries. Skip this step if the populator isn't wired up in the
current deployment.
Live API fallback (Discord `fetch_member` / Slack `users.info`) is
*not* in the read path today. If a real recurring need surfaces,
chainlink it as a follow-up — the runtime would need to expose
bridge handles to the agent (a meaningful tool-surface expansion).
## What NOT to use this for
- **Don't write to `state/identities.yaml`** — operator-managed.
- **Don't use this for cross-channel author resolution at runtime** —
that already happens automatically via `IdentityResolver` in the
prompt-build path. This skill is for ad-hoc queries, not the hot
path.
- **Don't use this skill for general identity discovery** ("find
everyone who works on the engineering team") — there's no role /
team metadata in the schema. Notes are free-form and not queryable
beyond substring grep.
## See also
- `state/identities.yaml` — the registry itself, with header comments
documenting the schema in full.
- `mimir/identities.py` — the loader (`IdentityResolver`) with
read-side methods including `resolve_channel`,
`channel_display_name`, `channel`, `all_channels`.
- `mimir/identities_populator.py` (chainlink #44) — the daily
populator that fills entries from connected bridges.
- chainlink #40 — parent issue covering cross-channel content +
identities/channels prompt-block expansion.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!