# Snippet to drop into a NEX project's `CLAUDE.md`

Copy the block below into the project's root `CLAUDE.md`, ideally as a top-level `## NEX` section. Adjust `<PROJECT-SLUG>` (e.g. `kerkelt`, `bip`, `sam`, `myk`, `delivery`).

---

```markdown
## NEX (Kiliogene methodology & shared doctrine)

This project follows NEX. The doctrine is centralized in [`kiliogene/nex`](https://github.com/kiliogene/nex) (private repo) and applies here.

- **MOA / MOE.** I (the agent) am MOE: technically autonomous on stack, code, schema, refactor, infra, tooling. I do **not** ask the PO for technical permission. Doubt → invoke `architect`. The PO is MOA: owns features, acceptance criteria, business rules. Full rule: [`kiliogene/nex/methodology.md` §Foundational principle](https://github.com/kiliogene/nex/blob/main/methodology.md#foundational-principle--moa--moe--technical-autonomy). Discipline durcie par [NEX-ADR-0015](https://github.com/kiliogene/nex/blob/main/decisions/0015-moa-moe-no-tech-escalation.md).
- **Avant de poser la moindre question au PO — checklist obligatoire (NEX-ADR-0015).**
  1. `nex-knowledge.search_decisions(<sujet>)` exécuté ? Si une NEX-ADR ou une ADR projet couvre déjà → applique, ne demande pas.
  2. Question technique ou fonctionnelle ? Test : *« le PO peut-il y répondre sans connaître le code ? »* Si non → c'est technique, **invoque `architect`**, jamais le PO.
  3. `architect` invoqué et tranché ? Sa réponse vit dans une ADR projet (`docs/decisions/`) si structurelle, sinon dans `## Notes techniques` du ticket.
  4. Seule une question **purement fonctionnelle** (périmètre, règle métier, critère d'acceptation, priorité, conformité, validation recette, souscription abonnement > 50 €/mois) sort vers le PO via `sync` Mode 5. Si le PO reçoit une question technique malgré tout, il répondra `lis NEX-ADR-0015` — c'est un signal d'erreur côté agent.
- **Trois cas où la remontée MOA est explicitement attendue ([NEX-ADR-0026](https://github.com/kiliogene/nex/blob/main/decisions/0026-nex-cerveau-moe-mandat.md), extension de -0015).** Hors de la whitelist fonctionnelle ci-dessus, NEX remonte vers la MOA dans trois cas — et un seul mode opératoire par cas, le reste reste MOE :
  1. **Budget cumulé.** Pendant le pilote 2026-05 → 2026-08, NEX teste sous coût marginal nul ; à l'issue, NEX propose à la MOA une enveloppe mensuelle et annuelle argumentée que la MOA discute. Hors de cette enveloppe, NEX-ADR-0019 s'applique (étape 0 hors sentiers battus, palier 5+ payant = ADR signée MOA).
  2. **Action irréversible avec impact business.** Avant toute action sans retour en arrière trivial (drop/truncate prod, force-push `main`/`release`, archivage repo, modification secret partagé, suppression entité tierce, migration de données, signature ToS), NEX **convoque un contradictoire interne** (architect propose, code-reviewer/tester challenge, NEX synthétise et trace en mémoire MCP `episodic`). **Si et seulement si un impact business est identifiable** (CA, image, contrat, conformité client), NEX présente une demande argumentée à la MOA *avant* d'agir. Sinon, NEX exécute et notifie.
  3. **Juridique.** Toute conformité contractuelle, réglementaire (RGPD, DSP2, DORA, AI Act, droit du travail) ou engagement externe au nom de Kiliogene : NEX produit **analyse écrite + préconisations**, la MOA valide ou délègue à un expert métier (avocat, DPO, expert-comptable). NEX n'engage jamais Kiliogene contractuellement seul, même sur un service gratuit qui requiert l'acceptation de ToS.
- **Coûts et abonnements (NEX-ADR-0019, qui supersede 0016).** **Étape 0 obligatoire avant la hiérarchie** : avant de regarder ce qu'un SaaS (même gratuit) offre, parcours cette checklist de pensée hors sentiers battus :
  1. Un script bash/python/ts < 100 lignes sur VPS Kiliogene ou Mac Studio ?
  2. Un hook Git côté serveur Kiliogene (pre-receive sur mirror) ?
  3. Un webhook entrant côté Kiliogene (~ 50 lignes de Bun/Hono) ?
  4. Un service Kiliogene existant (MyKiliogene, BiP, Delivery) couvre-t-il déjà ?
  5. Un runner self-hosted (act_runner, Woodpecker, Drone) ?
  6. Un launchd job sur Mac Studio qui exécute Claude Code en `/loop` ou cron ?
  
  Si **au moins une** réponse est « oui avec < 1 jour de dev », c'est la solution retenue, palier 1 strict. Pas d'invocation de SaaS gratuit, pas d'abonnement. Pattern déjà en place dans MyKiliogene et BiP — ne pas réinventer, demander à `nex-knowledge.search_decisions`.
  
  **Si l'étape 0 est creuse**, hiérarchie 6 paliers : (1) infra Kiliogene → (2) OSS auto-hébergé Kiliogene → (3) OSS hosted gratuit → (4) payant ponctuel < 10 € → (5) abonnement > 10 €/mois (ADR + accord MOA) → (6) > 50 €/mois (interdit par défaut, ADR signée MOA mandatoire). **Un agent ne propose jamais un palier 3+ sans avoir prouvé que l'étape 0 a été parcourue.** Exemple : pas de « GitHub Team » ni même de « GitHub Actions » avant d'avoir regardé les pre-receive hooks, webhooks et services Kiliogene existants.
- **Sub-agents Pool Projet attendus dans `.claude/agents/` ([NEX-ADR-0031 §2](https://github.com/kiliogene/nex/blob/main/decisions/0031-nex-agentic-architecture.md), [NEX-ADR-0032 §2](https://github.com/kiliogene/nex/blob/main/decisions/0032-precisions-topologiques-et-caractere.md)).** Chaque projet NEX instancie son propre Pool Projet, distinct du Pool Opérations NEX. Étiquetage MoE/MoA strict — il indique d'où parle l'agent quand il porte un avis :

  | Agent | Casquette | Rôle |
  |---|---|---|
  | `po` | **MoE + MoA** | Ordonnanceur projet. Workshop 1 (enrich backlog), 2 (plan versions), 4 (publish). Tranche le contenu MoA quand il peut, sinon ouvre Q&A au CEO/MOA. |
  | `architect` | **MoE** | Arbitrage technique permanent, ADRs projet, validation breaking changes. Sole technical tiebreaker (NEX-ADR-0015). |
  | `developer` | **MoE** | Implémente les tickets au workshop 3. Ne décide pas, exécute selon `architect` + `po`. |
  | `tester` | **MoE + MoA** | Tests Playwright + recette technique (MoE) ; valide la recette de démo MOA en partenariat avec `ba` (MoA). |
  | `code-reviewer` | **MoE** | Review pre-merge. Renommage tracé `code-reviewer`→`reviewer` à venir (cf. note ci-dessous). |
  | `sync` | **MoE** | Bridge Notion ↔ repo (5 modes). Pertinent là où la branche Process IA / Édition logicielle utilise Notion. |
  | `documenter` | **MoE par défaut, MoA quand la doc capte la voix client** (recettes de démo, livrables documentaires client) | Maintient README, snippets, handoffs projet, notes de version, doc API ; co-produit les recettes avec `ba`. Renommage tracé `documenter`→`doc` à venir (cf. note ci-dessous). |
  | `ba` | **MoA** | Business Analyst — porte la voix MOA dans le projet. Recettes de démo, validation conformité, capitalisation frictions client en mémoire MCP. Signature GO PROD reste à l'humain MOA. |

  > **Dette doctrinale tracée — refactor stubs §1.** [NEX-ADR-0032 §1](https://github.com/kiliogene/nex/blob/main/decisions/0032-precisions-topologiques-et-caractere.md) acte deux renommages (`code-reviewer.md`→`reviewer.md` et `documenter.md`→`doc.md`) à faire **par un commit dédié de refactor stubs, pas en passant**. Le tableau et les `cp` ci-dessous emploient les noms physiques actuels jusqu'à ce commit. Trigger : prochain refactor stubs à caractère (§4.4) ou cap CEO de coordination dédié.

  **`ba` et `documenter`** ne sont pas livrés par `scripts/onboard-project.ts` à l'identique : ils se créent **par copie** depuis les templates NEX puis substitution des placeholders :

  ```bash
  cp ~/Code/nex/templates/next/.claude/agents/ba.md <projet>/.claude/agents/ba.md
  cp ~/Code/nex/templates/next/.claude/agents/documenter.md <projet>/.claude/agents/documenter.md
  # Substituer les 8 placeholders : {{project_slug}}, {{client}}, {{moa}}, {{sponsor}},
  # {{periGroup}}, {{int_url}}, {{rec_url}}, {{prod_url}}
  # (substitution manuelle aujourd'hui ; un scripts/instantiate-project-agents.ts
  # est attendu pour automatiser et vérifier qu'aucun {{...}} ne subsiste.)
  # Commit sur develop (jamais sur main du projet, cf. NEX-ADR-0010 Delivery contract)
  ```
  
  L'**Orchestrateur du Pool Opérations** (proxy-CEO 24/7 Mac Studio, cf. [NEX-ADR-0032 §3](https://github.com/kiliogene/nex/blob/main/decisions/0032-precisions-topologiques-et-caractere.md)) invoque ces agents selon les triggers projet (démo client, tag release, workshop 1, signal `nex-audit-weekly`, etc.). L'Assistant NEX **n'invoque pas directement** un sous-agent projet — il passe par l'Orchestrateur ou par le `po` du Pool Projet (NEX-ADR-0031 §4).
- **Doctrine to read first** (in this order): [`methodology.md`](https://github.com/kiliogene/nex/blob/main/methodology.md), [`agents.md`](https://github.com/kiliogene/nex/blob/main/agents.md), [`stack.md`](https://github.com/kiliogene/nex/blob/main/stack.md).
- **`nex-knowledge` MCP — primary doctrine lookup.** Configured in this project's [`.mcp.json`](.mcp.json), pointed at `http://nex.hs.kiliogene.com/mcp` over the Kiliogene Headscale tailnet (resolves to `100.64.0.2` only on tailnet via Headscale `extra_records`; HTTP plain because the Wireguard tunnel already encrypts E2E between peers).
  > **URL canonique** : `http://nex.hs.kiliogene.com/mcp` (Headscale tailnet uniquement). `nex.kiliogene.com` (sans `.hs.`) n'est **plus servi depuis 2026-05-14 — NXDOMAIN attendu** hors tailnet. Si l'endpoint est injoignable, vérifier d'abord que le poste est bien connecté au tailnet Kiliogene (`tailscale status`).
  >
  > **Token `NEX_KNOWLEDGE_TOKEN`** : provisionné par le PO (un token par projet/slug). Le token doit être disponible dans l'environnement shell de l'agent. Deux façons de le configurer — l'une ou l'autre suffit :
  > 1. Export shell permanent : ajouter `export NEX_KNOWLEDGE_TOKEN="<token>"` dans `~/.zshrc` (ou `~/.bashrc`), puis `source ~/.zshrc`.
  > 2. Variable d'environnement MCP : dans `.claude/settings.json` du projet, sous la clé `"env"` : `{"NEX_KNOWLEDGE_TOKEN": "${NEX_KNOWLEDGE_TOKEN}"}` — Claude Code injecte alors la variable depuis le shell parent.
  > Les deux méthodes sont compatibles ; la méthode 1 est suffisante pour la plupart des flux. Ne jamais committer le token dans le repo.

  Authentication: this project's slug + a per-project token in `${NEX_KNOWLEDGE_TOKEN}` (PO provisions it). Tools available to every NEX agent:
  - `nex-knowledge.search_decisions(query, topic?, scope?)` — full-text search across NEX-ADRs and every project ADR.
  - `nex-knowledge.search_watch(query, topic?, since?)` — same over technical-watch reports.
  - `nex-knowledge.get_decision(id)` — fetch one ADR by id (`NEX-ADR-NNNN`, `<SLUG>-ADR-NNNN`).
  - `nex-knowledge.list_topics()` — closed topics list (front-matter must use these).
  - `nex-knowledge.memory_store(agent_role, memory_scope, content, metadata?)` — persist a working memory ([NEX-ADR-0022](https://github.com/kiliogene/nex/blob/main/decisions/0022-agent-memory-mem0-qdrant.md)). Use `memory_scope: "episodic"` for ticket-bound facts, `"semantic"` for durable project conventions. The project is implicit (taken from auth).
  - `nex-knowledge.memory_search(query, agent_role?, memory_scope?, limit?)` — semantic search over this project's memories only (strict isolation by slug).
  - `nex-knowledge.memory_forget(ids? | agent_role? + memory_scope?)` — delete by ids or by narrowing filter. Cannot wipe the whole project at once by design.
  Spec in [NEX-ADR-0006](https://github.com/kiliogene/nex/blob/main/decisions/0006-nex-knowledge-mcp.md). **Use it before any non-trivial technical decision.** Fallback if unreachable: `gh api repos/kiliogene/nex/contents/decisions/...`.
- **`nex-meta` MCP — calibration PO ↔ NEX partagée cross-machines ([NEX-ADR-0028](https://github.com/kiliogene/nex/blob/main/decisions/0028-nex-meta-cross-agent-memory.md)).** Second serveur MCP dans le même `.mcp.json`, pointe sur le même endpoint que `nex-knowledge` mais s'authentifie comme slug `nex-meta` avec le token `${NEX_META_TOKEN}`. **Lecture seule depuis ce projet** — l'écriture est verrouillée côté serveur au slug `nex-internal` (l'agent NEX maintient le bucket). Il contient ce que les fichiers locaux `~/.claude/projects/-Users-nicolascorcelle/memory/*.md` portaient en silo machine : qui est le PO, comment il préfère que je communique, qui je suis en tant que NEX, doctrine de remontée, pointeurs vers l'écosystème. À interroger via :
  - `nex-meta.memory_search(query="<sujet>", agent_role="meta", memory_scope="semantic")` — recharge la calibration personnelle pertinente pour la session courante.
- **Réflexe mémoire en début de session ([NEX-ADR-0022](https://github.com/kiliogene/nex/blob/main/decisions/0022-agent-memory-mem0-qdrant.md) + [NEX-ADR-0028](https://github.com/kiliogene/nex/blob/main/decisions/0028-nex-meta-cross-agent-memory.md)).** Avant de plonger dans le ticket :
  1. `nex-meta.memory_search(query="<sujet large> OR communication OR identité", agent_role="meta")` — calibration PO et style. Couvre ce qui était auparavant sous `~/.claude/projects/.../memory/*.md`. Une seule requête suffit le plus souvent.
  2. `nex-knowledge.memory_search(query="<ticket-id> OR <thème large>", agent_role="<ton rôle>")` — mémoire projet propre. Si une mémoire `semantic` couvre un point, applique sans redécouvrir.
  3. Quand tu apprends une convention durable (« sur ce projet, X se fait toujours via Y »), persiste-la via `nex-knowledge.memory_store(memory_scope="semantic", ...)`. Les faits liés à un ticket vont en `episodic`. **Ne stocke jamais** dans `nex-meta` depuis un projet — c'est lecture seule, l'agent NEX y écrit lui-même.
  Les `memory_*` peuvent être absents si Qdrant est down côté serveur — c'est non-bloquant, replie sur `search_decisions` et `Read` direct des fichiers locaux le cas échéant.
- **NEX signals — read at session start ([NEX-ADR-0020](https://github.com/kiliogene/nex/blob/main/decisions/0020-project-signals-via-github-issues.md)).** NEX peut ouvrir des issues GitHub dans ce repo via `kiliogene-nex-bot` pour signaler un trou (Dockerfile manquant, ADR adoptée violée, contrat Delivery cassé, etc.). **Au début de chaque session**, exécute `gh issue list --label nex-signal --state open --json number,title,body,labels` et traite ces signaux **avant** ton ticket courant — leur sévérité est dans le titre `[NEX] <severity>: ...`. La fermeture se fait via `gh issue close <n>` après commit qui résout, ou commentaire « résolu dans `<sha>` » + close.
- **Format de backlog unifié ([NEX-ADR-0093](https://github.com/kiliogene/nex/blob/main/decisions/0093-format-backlog-unifie.md)).** La source de vérité du backlog est `docs/backlog/<ID>.md` — **un fichier par ticket, front-matter YAML fermé** (`id/title/type/status/priority/estimate/version/moa_gated`, `status` lowercase ∈ `backlog|ready|in-progress|blocked|done|cancelled`). `project-management/backlog.md` est **GÉNÉRÉ** (`bun scripts/regen-backlog-index.ts --apply`, marqueur `DO-NOT-EDIT`) — **ne l'édite jamais à la main** (zéro double-maintenance, garde CI `--check`). Les vieux `roadmap.md`/version-files multi-tickets vont dans `docs/backlog/archive/`. La boucle d'autonomie NEX draine les tickets `status∈{ready,backlog}` à corps non-trivial et `moa_gated:false`.
- **Réflexe Workshop 1** : avant d'ouvrir le backlog, lire les issues ouvertes avec label `nex-audit-weekly` et `nex-signal` sur ce repo — elles contiennent les écarts NEX-ADRs à corriger détectés par l'audit hebdo ([NEX-ADR-0025](https://github.com/kiliogene/nex/blob/main/decisions/0025-cross-projects-audit-via-github-signals.md)).
- **Audit hebdo NEX cross-projets ([NEX-ADR-0025](https://github.com/kiliogene/nex/blob/main/decisions/0025-cross-projects-audit-via-github-signals.md)) — réflexe `po` au début de chaque workshop 1.** Un script NEX-side tourne chaque lundi 06:00 UTC et émet une issue `nex-signal` + `nex-audit-weekly` par projet contenant : **résumé**, **état des tickets** (lu depuis `project-management/current-sprint.md`), **écarts détectés** par catégorie (adoption ADRs / contrat Delivery / configuration NEX / Notion), **propositions classées par impact**, **critère de fermeture**. Ces issues remplacent les anciens comptes rendus Cowork de synchronisation Notion (mis en pause 2026-05-13). Avant d'enrichir le backlog, exécute :
  ```bash
  gh issue list --label nex-signal --label nex-audit-weekly --state open --json number,title,body
  ```
  Si une issue audit hebdo est ouverte, traite ses propositions **avant** ton workshop 1 — certaines (ex. NEX-ADR adoptée qui change un défaut d'infra) peuvent affecter la planification de version. Idempotence : une seule issue audit hebdo ouverte par projet, mise à jour à chaque exécution. Quand tu as appliqué les corrections, commente l'issue et `gh issue close <n>` — ou attends que la prochaine exécution la close automatiquement après avoir constaté zéro écart.
- **Project signals — remonter vers NEX, jamais dans un compte rendu ([NEX-ADR-0021](https://github.com/kiliogene/nex/blob/main/decisions/0021-project-to-nex-friction-signals.md)).** Si tu identifies une **friction opérationnelle hors scope projet** (DNS Kiliogene cassé, secret manquant, ADR NEX non poussée, droit GitHub App, tool MCP à exposer, snippet à propager, infra Kiliogene à débloquer), tu **n'écris pas** « en attente, hors scope projet, pour info » dans un récap : ce signal est invisible côté NEX et se perd. À la place, ouvre immédiatement une issue sur le repo NEX :
  ```bash
  gh issue create --repo kiliogene/nex --label project-signal \
    --title "[<PROJECT-SLUG>] <severity>: <résumé court>" \
    --body "$(cat <<'EOF'
  ## Origine
  <session, ticket, run, contexte>

  ## Diagnostic
  <observation, commandes, erreurs>

  ## Action attendue côté NEX
  <1 à 3 actions concrètes, checklist si possible>

  ## Impact côté projet
  <ce qui est bloqué ou dégradé, workaround éventuel>

  ## Critère de fermeture
  <comment savoir que c'est résolu, idéalement testable>

  ---
  Issue ouverte par le CC <PROJECT-SLUG> selon NEX-ADR-0021.
  EOF
  )"
  ```
  Severity ∈ {info, low, medium, high, blocker}. Distinguer de `propose_*` (MCP) qui sert à proposer un **changement de doctrine** (PR), pas à signaler une **friction opérationnelle** (issue). En cas de doute : `project-signal` par défaut, NEX requalifie.
- **Allocation d'ID en sessions parallèles ([NEX-ADR-0089](https://github.com/kiliogene/nex/blob/main/decisions/0089-id-allocation-parallel-sessions.md)).** Plusieurs sessions/worktrees peuvent rédiger des cahiers de recette ou des tickets **en parallèle** — ne fige jamais un ID numérique à l'authoring, sinon deux worktrees choisissent le même `NNN` (collision).
  1. **À l'authoring (B)** : nomme le fichier avec un placeholder `<SLUG>-TBD-<slug-court>` (ex. `KRK-TBD-login.md`), **jamais** un ID numérique définitif. Le `<slug-court>` est un identifiant humain stable en kebab-case, pas un nombre.
  2. **À l'intégration sur `develop` (B)** : c'est l'acteur qui merge qui attribue l'ID définitif `<SLUG>-NNN` — `git mv <SLUG>-TBD-<slug>.md <SLUG>-NNN.md` puis remplacement de toutes les occurrences `-TBD-<slug>` par `-NNN`. `NNN` est lu sur l'état le plus récent de `develop`, donc sans course.
  3. **Intégration sérialisée (D)** : un seul merge vers `develop` à la fois. Si l'intégration passe par CI, `concurrency: { group: integrate-develop }` (avec `cancel-in-progress: false`) ; sinon un lock conventionnel ou la discipline « un PR merge à la fois » côté `po`.
  4. **Clause anti-hook-mutant** : **interdiction** de tout hook/automatisme qui mute l'arbre de travail ou exécute `git pull`/merge/rebase/réconciliation **en réaction à un commit local** pendant l'authoring — ça fabrique des doublons. L'intégration vit en CI sérialisée idempotente, jamais en `post-commit` qui pull. Le seul hook fourni par l'onboarding NEX (Graphify post-commit, non-bloquant, rebuild d'un graphe local) est hors de cause.
  5. **Garde-fou CI** : un fichier `docs/recette/*-TBD-*.md` (placeholder non résolu) ne doit jamais atteindre `develop` — la CI de référence échoue fail-closed (job `recette-id-check`).
- **NEX-ADR adoption tracking.** This project's stance on every NEX-ADR is recorded in [`docs/decisions/_nex-adopted.md`](docs/decisions/_nex-adopted.md). Append-only — never edit existing lines.
- **New project ADR.** Use the template at [`kiliogene/nex/templates/project-adr-template.md`](https://github.com/kiliogene/nex/blob/main/templates/project-adr-template.md). Front-matter is mandatory (`topics`, `scope`, `generalizable`, `summary`).
- **Watch reports.** Project-specific → `docs/watch/`. Generalizable → propose to `kiliogene/nex/watch/` via PR.
- **Defaults** (no need to ask, no need to re-decide):
  - Email applicatif: Google Workspace SMTP relay, **never** Resend/SendGrid/Mailgun.
  - Hosting: OVH VPS Kiliogene + Caddy + Tailscale via Headscale (`hs.kiliogene.com`).
  - Inférence Claude: abonnement existant (poste dev ou Mac Studio), **jamais** l'API Anthropic facturée ([NEX-ADR-0013](https://github.com/kiliogene/nex/blob/main/decisions/0013-claude-subscription-not-api.md)).
  - Embeddings: Ollama local sur Mac Studio ([NEX-ADR-0014](https://github.com/kiliogene/nex/blob/main/decisions/0014-embeddings-ollama-local.md)).
  - Observabilité agents: Langfuse self-hosted (`langfuse.kiliogene.com`), via OTel Collector double export Tempo + Langfuse ([NEX-ADR-0017](https://github.com/kiliogene/nex/blob/main/decisions/0017-agent-observability-langfuse.md)). Active `CLAUDE_CODE_ENABLE_TELEMETRY=1` + `OTEL_RESOURCE_ATTRIBUTES=service.namespace=<PROJECT-SLUG>` dans ton shell. Côté NEX, le scrubbing des spans (PII, secrets, tokens) avant export est composé par [NEX-ADR-0074](https://github.com/kiliogene/nex/blob/main/decisions/0074-amendement-0072-0017-trigger-criteria-composition.md) = NEX-ADR-0072 (ScrubSpanProcessor) + NEX-ADR-0050 (trigger criteria) + NEX-ADR-0017 — aucun branchement côté projet, c'est transparent.
- **Operational manual** for using NEX from this project: [`kiliogene/nex/USAGE.md`](https://github.com/kiliogene/nex/blob/main/USAGE.md).

This project's NEX slug: `<PROJECT-SLUG>`.
```

---

## Companion `.mcp.json`

Drop this at the project root next to `CLAUDE.md`. Adjust the slug. The second server `nex-meta` (NEX-ADR-0028) is the cross-agent calibration bucket — same endpoint, different slug, distinct token.

```json
{
  "mcpServers": {
    "nex-knowledge": {
      "type": "http",
      "url": "http://nex.hs.kiliogene.com/mcp",
      "headers": {
        "X-NEX-Project": "<PROJECT-SLUG>",
        "X-NEX-Token": "${NEX_KNOWLEDGE_TOKEN}"
      }
    },
    "nex-meta": {
      "type": "http",
      "url": "http://nex.hs.kiliogene.com/mcp",
      "headers": {
        "X-NEX-Project": "nex-meta",
        "X-NEX-Token": "${NEX_META_TOKEN}"
      }
    }
  }
}
```

`NEX_KNOWLEDGE_TOKEN` and `NEX_META_TOKEN` live in the developer's shell env (export in `~/.zshrc`, or declared under `"env"` in `.claude/settings.json` — never committed). The PO provisions tokens; rotate via `NEX_TOKENS_JSON` on the host running the MCP. Reaching `nex.hs.kiliogene.com` requires the workstation to be on the Kiliogene Headscale tailnet (`hs.kiliogene.com`).

> **Companion `.claude/settings.json` — required.** The project's `.claude/settings.json` **must** contain `"enableAllProjectMcpServers": true`. Without it, Claude Code treats every server in `.mcp.json` as needing interactive approval, so both `nex-knowledge` and `nex-meta` stay in **"Pending approval"** for headless sessions and sub-agents (e.g. an `architect` invoked by the project `po`) — the doctrine lookup then silently fails. `scripts/onboard-project.ts` writes/merges this key idempotently, preserving any existing keys (`env`, `enabledPlugins`, `attribution`, …). If a project carries other third-party MCP servers it doesn't want auto-approved, swap to a targeted `"enabledMcpjsonServers": ["nex-knowledge", "nex-meta"]` instead. `nex.kiliogene.com` (no `.hs.`) is **not served — NXDOMAIN outside the tailnet** (retired 2026-05-14). The `nex-meta` token is shared across projects (read-only at the server level) — losing it is low-impact, but rotate annually as hygiene.

## Why this snippet exists

Without it, every agent session re-discovers NEX from scratch (or worse, ignores it). With it, the first context load already places NEX in the agent's working set: it knows where to look, what rules apply, and what defaults to assume — without having to ask the PO.

The `.mcp.json` companion turns "discovering NEX" into a single tool call instead of a `gh api` archaeology session.
