Analyste: Jacques Gariepy
Date: 2026-04-22
Binaire: C:\Users\jacqu\.local\share\claude\versions\2.1.117 (247,959,712 o)
Git SHA: 5e9d59ce46d5559e3510d71ef3dc12b5ab1e7387
Runs précédents: v2.1.98 (2026-04), v2.1.104 (2026-04-13)
| # | Finding | Sévérité | Renvoi |
|---|---|---|---|
| F1 | Plugin system sans signature crypto — claude-plugins-official tip compromet toute la population sans pin obligatoire |
CRITIQUE | §3.1, §10.1 |
| F2 | Tool approval à distance depuis le mobile (RC) — un attaquant contrôlant le téléphone peut approuver Bash/Edit/Write sans voir le terminal | HAUTE | §3.2, §10.3 |
| F3 | Windows n'a pas de sandbox OS-level — macOS = sandbox-exec, Linux = bwrap + seccomp; Windows = seulement env scrub + trust dialog |
HAUTE | §3.8-sandbox, §10.4 |
| F4 | Datadog telemetry avec token public hardcodé (pubea5604404508cdd34afb69e6f42a05bc) + scrub limité aux _PROTO_* seulement |
MOYENNE | §3.8-datadog, §10.5 |
| F5 | AFK mode — fail-open explicite : si le serveur rejette afk-mode-2026-01-31, le client drope le header et circuit-break silencieusement |
MOYENNE | §3.5, §10.6 |
| F6 | OIDC federation — grant type JWT Bearer + Token Exchange (RFC 7523 + RFC 8693) pleinement implémentés, PRM discovery (RFC 9728) | INFO | §3.3 |
| F7 | Advisor gate (deux fonctions whitelist identiques) — WfH et Z$8 évaluent différents inputs contre le même set {opus-4-7, opus-4-6, sonnet-4-6} — surface pour divergence silencieuse |
INFO | §3.6 |
| F8 | 42 outils vs 29 en v2.1.104 — +13 nouveaux : TaskCreate/Update/Get/List/Output/Stop, EnterWorktree/ExitWorktree, CronCreate/Delete/List, ScheduleWakeup, SendMessage, PushNotification, AskUserQuestion, REPL, Monitor, RemoteTrigger | INFO | §5 |
Résumé exécutif : v2.1.117 est la version la plus architecturalement significative depuis le début de ces RE. En 13 jours depuis 2.1.104, Anthropic a livré : un marketplace de plugins sans signature crypto (F1), un Remote Control pivot-capable (F2), une fédération OIDC conforme aux RFC récents (F6), un task manager complet (F8), et un mode AFK avec circuit-break fail-open (F5). Le sandbox Windows reste l'absence la plus grave (F3).
| Champ | Valeur |
|---|---|
| Chemin | C:\Users\jacqu\.local\share\claude\versions\2.1.117 |
| Taille | 247,959,712 octets (236.5 MB) |
| Build timestamp | 2026-04-21T17:58:52Z |
| Git SHA | 5e9d59ce46d5559e3510d71ef3dc12b5ab1e7387 |
| Format | PE32+ x86-64 (12 sections) |
Section .bun offset |
0x7533600 (122,893,824 d) |
Section .bun taille raw |
125,055,488 o (119.3 MB) |
| Bundle JS dans la section | offset +424 après header Bun (128 o archive + 296 o manifest) |
| Taille JS manifest-bounded | 13,128,629 o (12.52 MB) |
| Bytecode JSC (non décodé) | ~106.8 MB dans la même section |
Source : EXTRACTION_REPORT.md §1-§2.
| Fichier | Chemin | Taille |
|---|---|---|
EXTRACTION_REPORT.md |
E:/tmp/claude_extracted/2.1.117/ |
7,189 o |
baseline_2.1.104.md |
idem | 35,312 o |
raw/claude-code-v2.1.117.clean.js |
idem | 13,128,629 o |
beautified/cli.beautified.js |
idem | 19,339,722 o |
catalogs/apis_catalog.json |
idem | 168,398 o (452 entrées) |
catalogs/tools_catalog.json |
idem | 13,383 o (42 outils) |
catalogs/env_vars_catalog.json |
idem | 188,603 o (540 vars) |
catalogs/beta_headers_catalog.json |
idem | 13,463 o (31 headers) |
internals/plugin_system.md |
idem | 10,647 o |
internals/remote_control.md |
idem | 10,792 o |
internals/oidc_federation.md |
idem | 12,196 o |
internals/agent_teams_swarm.md |
idem | 15,057 o |
internals/afk_mode.md |
idem | 12,317 o |
internals/advisor_tool.md |
idem | 13,702 o |
diff/apis_diff.md |
idem | 13,922 o |
diff/tools_diff.md |
idem | 12,507 o |
diff/env_vars_diff.md |
idem | 20,024 o |
diff/beta_headers_diff.md |
idem | 10,817 o |
diff/structural_diff.md |
idem | 38,698 o |
cfg/plugin_install.md |
idem | 7,534 o |
cfg/plugin_validate.md |
idem | 7,256 o |
cfg/remote_control_bridge.md |
idem | 8,149 o |
cfg/oidc_token_exchange.md |
idem | 9,066 o |
cfg/agent_team_dispatch.md |
idem | 11,092 o |
cfg/advisor_gate.md |
idem | 7,567 o |
cfg/afk_latch.md |
idem | 7,938 o |
cfg/foundry_auth.md |
idem | 10,407 o |
cfg/datadog_telemetry.md |
idem | 9,999 o |
cfg/sandbox_env_check.md |
idem | 14,621 o |
identifier_map_2.1.117.json |
idem | 49,048 o (225 mappings) |
Extraction PE : lecture de l'en-tête DOS → table de sections PE12 → localisation de .bun par nom → lecture des 512 octets d'en-tête de section → magic // @bun à offset +424 → taille JS depuis le manifest Bun (u32LE à offset +420 = 13,128,629) → extraction exacte, sans contamination bytecode. Méthode identique à 2.1.104 (même layout : 128 o Bun archive header + 296 o module manifest = 424 o avant le JS).
Beautification : js-beautify → beautified/cli.beautified.js (19.3 MB, ~545 K lignes).
Extraction de catalogues : regex sur le JS beautifié pour APIs (/v[0-9]+\/), outils (constantes name:, description:), env vars (process.env.CLAUDE_CODE_*, process.env.ANTHROPIC_*), beta headers (pattern "anthropic-beta" + constantes associées).
Internals markdown : lecture ciblée des zones de la beautified autour des strings-clés (plugin, afk-mode, advisor, tengu_ccr_bridge, oidc_federation, etc.) → 6 documents sémantiques.
CFG reconstruction manuelle : identification des blocs basiques, transitions, et pseudo-code reconstitué pour 10 fonctions critiques → 10 documents cfg/.
Identifier map : cross-référence contexte string + voisinage d'appel sur le JS beautifié → 225 mappings mangled→sémantique.
Outils envisagés mais non utilisés :
x64dbgdynamic analysis (breakpoints import addresses, heap JS dump post-init)angr/Tritonsymbolic execution (env var conditional paths)- Décodeur JSC bytecode Bun (106.8 MB de bytecode JSC toujours non parsé — magic changé vs 2.1.98)
mitmproxyharness réseau (bridge_url non extrait, flow OIDC token exchange non capturé)
| Version | Taille binaire | JS extrait | Identifiants | APIs | Outils | Env vars | Beta headers |
|---|---|---|---|---|---|---|---|
| 2.1.98 | ~230 MB | ~12 MB | 34,170 (JSC) | ~16 | ~25 | ~213 | ~15 |
| 2.1.104 | 243,137,184 o (231.9 MB) | 12,800,361 o (12.2 MB) | 141,390 | ~66 | 29 | ~258 | 28 |
| 2.1.117 | 247,959,712 o (236.5 MB) | 13,128,629 o (12.52 MB) | 143,536 | 452 | 42 | 540 | 31 |
Sources : baseline baseline_2.1.104.md §1, §3, §4, §6 ; EXTRACTION_REPORT.md §4, §5.
| Métrique | v2.1.98 | v2.1.104 | v2.1.117 | Δ 104→117 |
|---|---|---|---|---|
| Taille binaire | ~230 MB | 231.9 MB | 236.5 MB | +4.6 MB |
| JS extrait | ~12 MB | 12.2 MB | 12.52 MB | +0.3 MB |
| JS beautifié | — | ~18 MB | 19.3 MB | +1.3 MB |
| Identifiants uniques | 34 170 (JSC) | 141 390 | 143 536 | +2 146 |
| APIs endpoint | ~16 | ~66 | 452 | +386 |
| Outils | ~25 | 29 | 42 | +13 |
| Env vars | ~213 | ~258 | 540 | +282 |
| Beta headers | ~15 | 28 | 31 | +3 |
Note : le bond APIs 66→452 reflète une extraction plus complète (script corrigé sans faux-positif
.rdata), pas un ajout de 386 endpoints entre les deux versions. Les ajouts réels sont documentés dansdiff/apis_diff.md.
Confirmés dans EXTRACTION_REPORT.md §6 :
claude-opus-4-7
claude-opus-4-6 (fast, 1m variants)
claude-haiku-4-5-20251001
claude-sonnet-4-5-20250929
claude-opus-4-1-20250805
claude-opus-4-5-20251101
Absents en 2.1.104, présents en 2.1.117 (source : EXTRACTION_REPORT.md §6 L99-L113) :
| Commande | Description |
|---|---|
plugin install/enable/disable/uninstall/validate |
Gestion plugins |
plugin marketplace add/list/remove/update |
Gestion marketplaces |
auto-mode defaults/config/critique |
Inspection classifier AFK |
agents |
Lister agents configurés |
xaa |
Gestion XAA SEP-990 (OIDC federation MCP) |
setup-token |
Jeton long-lived inference-only |
install [target] |
Installation native build |
doctor |
Health check auto-updater |
remote-control / rc |
Remote Control via claude.ai/code |
Le plugin system 2.1.117 orchestre install / enable / disable / uninstall / marketplace add-remove-update + /plugin validate via slash-command et subcommand CLI (internals/plugin_system.md §1, L433204-L433217). Le manifeste canonique est plugin.json ou .claude-plugin/plugin.json (L198665-L198667), validé par un schéma Zod (L45370-L46005).
Composants déclarables (L199317-L199321) : commands, agents, skills, hooks, outputStyles.
Marketplace officiel : github:anthropics/claude-plugins-official (L194628). URL stats installs : https://raw.githubusercontent.com/anthropics/claude-plugins-official/refs/heads/stats/stats/plugin-installs.json (L427529) — fingerprint en clair.
Plugins officiels référencés (L421173-L421176) :
/plugin install frontend-design@claude-plugins-official
/plugin install playwright@claude-plugins-official
/plugin install skill-creator@claude-plugins-official
Flow install (CFG cfg/plugin_install.md) : fonction C4H = installResolvedPlugin (L198214) → gate policy enterprise Bm8 → closure de dépendances wWK → write settings atomique T$(scope, {enabledPlugins}) → 8 reason codes d'erreur → télémétrie tengu_plugin_installed.
Chemin de cache : <CLAUDE_CODE_PLUGIN_CACHE_DIR>/cache/<marketplace>/<pluginId>/<version>/ (L198336).
Scopes : user (défaut) ou project (.claude/settings.json, partagé avec l'équipe, L429360).
| Élément | Lignes |
|---|---|
Aide /plugin install |
L433898-L433914 |
Localisation plugin.json |
L198665-L198667 |
Schéma Zod gitCommitSha |
L45968, L45991, L45972 |
| Marketplace officiel | L194628 |
Flow install C4H |
L198214-L198270 |
| Path cache derivation | L198336 |
| Path poisoning detection | L378813 |
| Contrainte kebab-case | L432853 |
| Manifest conflict detection | L199317-L199328 |
| Seed dir re-registration | L378644 |
- A08 (Software & Data Integrity) — CRITIQUE : aucune signature crypto.
internals/plugin_system.md§4.3 : 0 match poured25519,sigstore,cosign,gpg,openpgp,detached signature. Seul guard :gitCommitShaoptionnel (L45968) + marketplace allowlistknown_marketplaces.json(L197682) + kebab-case soft-warn (L432853). - A06 (Vulnerable & Outdated Components) : un push malveillant sur la branche
maindeclaude-plugins-officialcompromet toute la population sans pin obligatoire. La branchestats(L427529) expose les noms d'install en clair → fingerprint d'adoption. - Supply-chain — 7 vecteurs (§6.1 internals) : typosquat marketplace (A), dependency injection (B), path traversal mitigé (C, L378813), seed-dir persistence (D, L378644), JSON registry editable à la main (E), manifest conflict si
strict:trueoverridable (F), branchestatspublique (G). - TOCTOU :
validatepeut muterenabledPlugins(L197997-L197998) sans bracketing atomique sur.claude/settings.json.
| Aspect | Claude Code 2.1.117 | poc-inter-cli |
|---|---|---|
| Marketplace | github:anthropics/claude-plugins-official |
N/A |
| Manifeste | plugin.json + Zod schema |
skills/*.md + frontmatter JSON |
| Signature | Aucune | Aucune — même gap |
| Scopes | user / project | global seulement |
| Dep closure | wWK multi-niveau |
N/A |
| Policy codes | 8 reason codes | 4 modes permission-gate |
À reprendre : 8 reason codes granulaires pour nos permission-gates ; pattern transactionnel reserve+rollback (L322929) pour WorkerPool.spawn().
À NE PAS reprendre : re-registration automatique depuis seed_dir (antipattern persistence) ; kebab-case soft-only (rendre hard dans notre skills-registry.js).
Le bridge Remote Control expose claude --remote-control [name] + alias masqué --rc (--hideHelp, L554438). Cible UI : https://claude.ai/code/<session_id> (L438035, L467222). Le bridge permet :
- Observation output terminal à distance
- Envoi de prompts depuis le mobile/web
- Approbation de tool calls depuis un autre device (L438023)
- Push de notifications mobiles via
PushNotification(L187186)
Gate d'éligibilité ve6() — 7 vérifications séquentielles (CFG cfg/remote_control_bridge.md B2-B9) :
B2: Og8() = Dg8() && y8("tengu_ccr_bridge", false) — feature flag GrowthBook
B3: !$IH() — pas déjà dans une remote session (anti-double-hop)
B4: Dg8() — abonnement claude.ai
B5: RBK() — token full-scope (setup-token REFUSÉ, inference-only)
B6: IBK()?.organizationUuid — UUID org présent
B7: await FT("tengu_ccr_bridge") — async feature flag
B8: policy("allow_remote_control") — policy managée org
B9: version check serveur (L260849) — le serveur peut rejeter les clients obsolètes
Beta headers liés : ccr-byoc-2025-07-29 (bridge avec x-organization-uuid L260418), ccr-triggers-2026-01-30 (déclenchement distant, L368645).
État machine (L313103-L313106) : connecting… → active → reconnecting → failed.
Multi-session : tengu_ccr_bridge_multi_session (L484292) — variante ajoutée en 2.1.117.
Source session : source: "remote-control" émis dans les events audit (L438882).
| Élément | Lignes |
|---|---|
CLI --remote-control + --rc |
L554434, L554438 |
Gate feature flag tengu_ccr_bridge |
L260743-L260759 |
| Refus setup-token | L260756 |
| Anti-double-hop guard | L260751 |
| State machine | L313103-L313106 |
Debug dump hSf (11 vars auth) |
L260763 |
Org policy allow_remote_control |
L467591, L491258-L491260 |
Bridge connect log bridge_url |
L9415 |
| PushNotification wiring | L187186-L187187 |
- A04 (Insecure Design) — HAUTE : tool approval à distance sans contexte local (
internals/remote_control.md§6.2). Un attaquant contrôlant le téléphone approuveBash rm -rf /,Write .git/hooks/pre-commit,Edit package.jsonsans voir le terminal. Le mobile UI doit afficher une signature lisible — [À VÉRIFIER] absent des greps. - A07 (Auth Failures) — bien géré : rejet explicite
setup-token(L260756 "inference-only") + anti-double-hop (L260751). Empêche le pivot depuis un token long-lived ou depuis une session compromise. - Info : debug dump
hSf(L260763) inventorie 11+ variables d'auth en clair → surveiller si dump atterrit dans un log partagé/mobile. - [HYPOTHÈSE] : URL bridge (
bridge_urlL9415) non extraite par greps — impossible de confirmer l'endpoint exact sans mitmproxy.
Notre telegram-bridge.js est conceptuellement analogue (état connecting/active), mais n'a pas de gate multi-étapes documentée. À reprendre : formaliser la state machine en enum (4 états) ; pipeline de gates with reason codes ; anti-double-hop guard. À NE PAS reprendre : approval à distance sans contexte — notre Tauri affiche déjà le diff complet, garder cette supériorité UX.
La fédération OIDC permet d'utiliser un jeton d'identité d'un IdP externe (Okta, GitHub Actions, Google Workspace, Azure AD, Kubernetes SA) pour s'authentifier auprès d'Anthropic, sans exposer une API key.
Beta header : oidc-federation-2026-04-01 (L93223). Déclenché par l'env-quad (L37309-L37314) :
["ANTHROPIC_FEDERATION_RULE_ID", "ANTHROPIC_ORGANIZATION_ID",
"ANTHROPIC_IDENTITY_TOKEN", "ANTHROPIC_IDENTITY_TOKEN_FILE"]Deux types d'auth (L93006-L93007) : oidc_federation, user_oauth. Aucun autre accepté.
Schéma config OIDC reconstitué :
{
"organization_id": "<UUID>",
"base_url": "https://api.anthropic.com",
"authentication": {
"type": "oidc_federation",
"federation_rule_id": "<rule>",
"service_account_id": "<sa-id>",
"identity_token": { "source": "file", "path": "/path/to/id-token" },
"scope": "<optional>"
}
}Stockage : %APPDATA%\Anthropic\credentials\<profile>.json (Windows) ou ~/.config/anthropic/credentials/<profile>.json (Unix) — L93046-L93063.
XAA (SEP-990) — mécanisme connexe pour les MCP servers (L46430, L46443) : découverte PRM RFC 9728 → découverte AS metadata RFC 8414 → token exchange RFC 8693 (grant_type: urn:ietf:params:oauth:grant-type:token-exchange) → ou JWT bearer RFC 7523 (grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer).
Chaîne de vérifications XAA (L388974-389028) :
- PRM resource mismatch → rejet
- Issuer mismatch → rejet
- Token endpoint non-HTTPS → rejet obligatoire
issued_token_typevérifié strictement (conformité RFC 8693)
Token caching : y04 = makeCachedOIDCProvider (identifier_map L93460) — access_token + expires_at dans le fichier credentials avec auto-refresh.
| Élément | Lignes |
|---|---|
Beta header oidc-federation-2026-04-01 |
L93223 |
| Env-quad | L37309-L37314 |
| Config OIDC reconstitué | L93006-L93107 |
Masquage rule ID (…<6 chars>) |
L37271-L37273 |
| XAA — PRM discovery (RFC 9728) | L388974-389028 |
| XAA — grant_type token-exchange | L389010 (rD1) |
| XAA — grant_type jwt-bearer | L389038 (w0_) |
| HTTPS obligatoire token endpoint | L389024 |
| Stockage credentials path | L93046-L93063 |
| Profil actif | L37279-L37282 |
- Positif : HTTPS obligatoire sur token endpoint (L389024) ; issuer mismatch rejeté (L389026) ;
issued_token_typevérifié (RFC 8693 strict). - [HYPOTHÈSE] :
service_account_idstocké en clair dans<profile>.json. Lafederation_rule_idest masquée à l'affichage (L37271) mais écrite en clair dans le fichier de config. - [À VÉRIFIER] : le grant type exact (token-exchange vs jwt-bearer) selon l'IdP — la chaîne XAA tente d'abord token-exchange, puis jwt-bearer si le premier échoue.
- Scénario idéal : GitHub Actions OIDC token →
ANTHROPIC_IDENTITY_TOKEN_FILE→ fédération sans API key exposée.
Les Agent Teams imposent une topologie flat star (hub-spoke) centrée sur le process principal. Les teammates sont des workers in-process (pas des subprocess), du type in_process_teammate (L229025, L229044). La topologie est explicitement contrainte : "Teammates cannot spawn other teammates — the team roster is flat" (L333270).
Activation : CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 ou --agent-teams (L131965-L131968). Gate de plan (L333266) — nécessite un abonnement Anthropic supérieur.
Registre : state.teamContext.teammates[id] (L229111). Identifiant swarm : claude-swarm-<pid> (L227779).
Protocole inter-agent : bloc XML <teammate-message teammate_id="...">…</teammate-message> (L37710, L227971), adressable via SendMessage({to: name, content}).
Task system complet (EXTRACTION_REPORT §6) :
_V → TaskCreate bk → TaskUpdate ec → TaskGet
BJ → TaskList JE → TaskOutput Uv → TaskStop
Ownership mutuable : TaskUpdate({owner: teammateId}) pour réassigner des tâches orphelines (L221143).
Spawn primitive pU8 = spawnInProcessTeammate (L229025) retourne {success, agentId, taskId, abortController, teammateContext}. La réservation d'identité est transactionnelle via mCH avec rollback l_$ (L322929).
SwarmPermissionPoller (L229393-L229398) : synchronise les permission requests entre agents du swarm via callbacks per-requestId.
Deux modes Agent tool (L224331, L224346, L224466) :
- Fork : hérite le contexte complet + cache Anthropic
- Fresh subagent : démarrage à froid, prompt self-contained
Deux backends de spawn (L322929, L375004) :
spawnInProcessTeammate(in-process, pour teammates)PaneBackendExecutor(probablement subprocess/tmux pane)
UltraPlan (remote-agent) : CLAUDE_CODE_PLAN_V2_AGENT_COUNT (L365624) ; feature tengu_ultraplan_config.enabled (L447609) ; exécuté côté cloud (vtf = ["remote-agent", "ultraplan", ...] L320890).
| Élément | Lignes |
|---|---|
| Contrainte flat topology | L333270, L224476 |
| Activation env/flag | L131965-L131968 |
Swarm ID claude-swarm-<pid> |
L227779 |
Message XML <teammate-message> |
L37710, L227971 |
Spawn primitive pU8 |
L229025-L229070 |
| Rollback post-reserve | L322929 |
| SwarmPermissionPoller | L229393-L229398 |
| Fork vs fresh | L224331, L224346, L224466 |
TaskCreate minified _V |
L367631 |
| TeammateIdle hook schema | L226768 |
- Race condition :
teamContext.teammatesmuté de manière concurrente (workers in-process, heap V8 partagée). Pas de verrou observable. - Fork mode et cache Anthropic : [HYPOTHÈSE] le fork hérite le cache prompt côté Anthropic — gain de coût significatif si vérifié. Si un agent forke avec un contexte contenant des secrets, ils héritent dans le fork.
- Isolation mémoire : teammates in-process partagent le heap V8 — pas d'isolation de processus comme nos workers subprocess.
| Aspect | Claude Code 2.1.117 | poc-inter-cli |
|---|---|---|
| Workers | In-process teammates | Subprocess via IPC |
| Task queue | TaskCreate/Update/Get/List | Mission planner + task-queue.js |
| Flat topology | Enforced (L333270) |
À vérifier / à enforcer |
| Message protocol | XML <teammate-message teammate_id> |
XML custom + Telegram bridge |
| Idle tracking | isIdle + TeammateIdle hook |
WorkerProfile affinity routing |
| Permission sync | SwarmPermissionPoller |
permission-gate.js 4 modes |
| Fork mode | OUI (2 modes Agent) | NON — opportunité |
À reprendre : fork mode (inherit context + cache) ; task queue first-class (TaskCreate) ; hook TeammateIdle pour re-routing ; flat topology enforcement (anti-fork bomb).
Le mode AFK (Away From Keyboard) est couplé à l'auto-mode : Claude Code continue d'exécuter sans intervention humaine, en approuvant automatiquement les tool calls selon un classifier ML, en pushant les notifications sur mobile via Remote Control.
Beta header : afk-mode-2026-01-31 (L91826). Stocké dans le state session global x8 (L2099) :
x8 = { ..., afkModeHeaderLatched: null, fastModeHeaderLatched: null, cacheEditingHeaderLatched: null, ... }Latching : une fois afkModeHeaderLatched = true (setter fO8 L1837), le header est injecté dans toutes les requêtes subséquentes de la session jusqu'à reset.
Circuit breaker (L481885-L481888) : si le serveur rejette afk-mode-2026-01-31, le client drope le header et circuit-break l'auto-mode pour la session (fail-open, non blocant) — marque retry:afk-beta.
Idle thresholds (L527095-L527097) :
CLAUDE_CODE_IDLE_TOKEN_THRESHOLD (défaut: 100,000 tokens)
CLAUDE_CODE_IDLE_THRESHOLD_MINUTES (défaut: 75 minutes)Anti-spam notifications : idleSec (secondes depuis dernière keystroke, L369182) — notifications supprimées si l'user est actif.
Classifier auto-mode (L231997-L232004, L400292, L400625, L400642) : émet un second appel API séparé (classifierTokensEst, classifierChars — L324094). Fallback : "Classifier unavailable" → fail-open (L400625).
Vérification multi-facteurs (L401156) avant entrée auto-mode :
enabledState— state machinedisabledBySettings— settings usermodelSupported— le modèle actuel supporte-t-il auto-mode ?disableFastModeBreakerFires— interaction circuit-breaker fast-modecarouselAvailable— UI picker disponiblecanEnterAuto— verdict final
Persistance : <config_dir>/auto-mode/ (L323637) ; erreurs classifier dans <log_dir>/auto-mode-classifier-errors/<sessionId>.txt (L323643).
| Élément | Lignes |
|---|---|
Beta header afk-mode-2026-01-31 |
L91826 |
State global afkModeHeaderLatched |
L2099 |
| Circuit-break fail-open | L481885-L481888 |
| Idle thresholds env vars | L527095-L527097 |
Anti-spam idleSec |
L369182-L369213 |
| Classifier second call metrics | L324094-L324096 |
Diagnostic verifyAutoModeGateAccess |
L401156 |
| Logs classifier errors | L323637, L323643 |
- MOYENNE — Fail-open : circuit-break silencieux (L481885). L'user n'est pas averti que
afk-modea été désactivé côté serveur ; le mode auto continue en mode dégradé (les tool calls ne sont plus marqués AFK côté Anthropic mais s'exécutent quand même). - Coût caché : chaque décision auto-mode coûte un appel API supplémentaire (classifierTokensEst). Pour une session longue, cela peut doubler les tokens.
- Fallback
"Classifier unavailable"(L400625) → pas de blocage → approbation implicite si classifier down.
L'Advisor est un server-side tool exécuté par l'infrastructure Anthropic (pas côté client). Il n'a pas de paramètres — l'historique complet de conversation est auto-forwardé côté serveur.
Beta header : advisor-tool-2026-03-01 (L91827).
Protocole stream (L223353, L481970-L481991) :
content_block_starttypeserver_tool_usename"advisor"→ latchm8 = truecontent_block_starttypeadvisor_tool_result→ releasem8 = false- Sous-types result :
advisor_result(succès) /advisor_tool_result_error(retry) - Retry sur 400 spécifique :
IY$strip les messages advisor +tengu_advisor_strip_retry
Gate deux-fonctions (cfg/advisor_gate.md, identifier_map) :
function Uh() {
if (truthy(process.env.CLAUDE_CODE_DISABLE_ADVISOR_TOOL)) return false;
if (provider !== "firstParty" || !isOAuth()) return false;
if (truthy(process.env.CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL)) return true;
return growthbook("tengu_sage_compass2").enabled ?? false;
}
const SUPPORTED = /opus-4-7|opus-4-6|sonnet-4-6/;
function WfH(baseModel) { return SUPPORTED.test(baseModel.toLowerCase()); } // Gate #1
function Z$8(advisorModel) { return SUPPORTED.test(advisorModel.toLowerCase()); } // Gate #2
function tkK(advisorModel, baseModel) { // dispatcher
if (!Uh() || !advisorModel) return undefined;
const canonical = resolveAlias(advisorModel);
if (!WfH(baseModel)) { log.skip("base unsupported"); return; }
if (!Z$8(canonical)) { log.skip("advisor invalid"); return; }
return canonical;
}Modèles supportés (confirmés dans identifier_map L223361, L223369) :
- Base models :
opus-4-7,opus-4-6,sonnet-4-6 - Advisor models : mêmes (whitelist identique en 2.1.117)
Positionnement (L223392-L223407) : appel AVANT travail substantiel + après complétion pour review final. Stratégie "stronger reviewer model" front-load.
Kill switches : CLAUDE_CODE_DISABLE_ADVISOR_TOOL (hard-off) + CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL (force-on).
| Élément | Lignes |
|---|---|
Beta header advisor-tool-2026-03-01 |
L91827 |
| Discriminateur type protocol | L223353 |
Gate Uh() — 4 conditions |
L223355-L223360 |
Gate WfH() base models |
L223361 |
Gate Z$8() advisor models |
L223365-L223369 |
Dispatcher tkK() |
L223369-L223381 |
| System prompt addendum | L223392-L223407 |
Latch m8 start/end |
L481970-L481991 |
| Telemetry events | L481979, L482127, L223866, L481894 |
Config advisorModel settings |
L46701, L464342-L464349 |
- INFO — whitelist identique :
WfHetZ$8testent le même regex sur des inputs différents (base vs advisor model). Si Anthropic diverge les deux fonctions en 2.1.118 sans documentation, un utilisateur avec un advisor non-supporté ne verra aucune erreur visible — justeundefinedsilencieux. - Coût : l'advisor forward l'historique complet côté serveur → coût tokens proportionnel à la longueur du transcript. Pas de slicing client.
- [HYPOTHÈSE] :
advisorModel: Dest stamped sur tous les messages assistant même sans appel advisor dans ce turn (L482090, L482295 unconditional quandDtruthy) → attribution billing scope whole-turn.
Le provider Foundry permet d'utiliser Claude via Azure AI Foundry (Microsoft). Il s'agit du 5ème provider (avec Bedrock, Vertex, Anthropic AWS/mantle, firstParty).
Activation : CLAUDE_CODE_USE_FOUNDRY=1 (L38015, L85982).
Deux modes d'auth :
ANTHROPIC_FOUNDRY_API_KEY(string) → headerx-api-key- Azure AD
DefaultAzureCredentialvia@azure/identity→ headerAuthorization: Bearer <AAD token>
Skip-auth : CLAUDE_CODE_SKIP_FOUNDRY_AUTH=1 → provider () => Promise.resolve("") → Bearer vide (pour test proxy uniquement — [HYPOTHÈSE]).
URL base : ANTHROPIC_FOUNDRY_BASE_URL (explicit) ou dérivée : https://${ANTHROPIC_FOUNDRY_RESOURCE}.services.ai.azure.com/anthropic/ (L97354-L97378).
Contrainte mutex constructeur (L97367) : apiKey && azureADTokenProvider → throw ; aucun des deux → throw ; baseURL && resource → throw.
DefaultAzureCredential chain : env → workload identity → managed identity → shared-token-cache → VS Code → Azure CLI → Azure PowerShell → InteractiveBrowser (dernier recours, inutilisable en CI non-TTY).
Features désactivées sur Foundry (L91874, L406817, L97341) : fast-mode, /feedback, beta.messages.batches.
Telemetry : les Foundry users n'émettent zéro événement Datadog (gate provider !== "firstParty" dans zp6 — cf. cfg/datadog_telemetry.md B2a).
| Élément | Lignes |
|---|---|
Provider dispatcher uO |
L122118 |
| Branche Foundry | L122143-L122156 |
Constructeur AnthropicFoundry |
L97353-L97400 |
authHeaders() — Bearer vs x-api-key |
L97381-L97395 |
| URL derivation depuis resource | L97354-L97378 |
| Mutex checks | L97367 |
| Features désactivées | L91874, L406817, L97341 |
- INFO :
validateHeaders()no-op sur Foundry (L97397-L97399) — contrairement au client firstParty. Les headers custom (ANTHROPIC_CUSTOM_HEADERS) atteignent Foundry sans vérification. - [HYPOTHÈSE] :
CLAUDE_CODE_SKIP_FOUNDRY_AUTH=1against production → Bearer vide → 401 mais la requête part quand même vers le réseau. Ajouter un guard côté client. - Comparaison providers : Foundry = pas de SigV4 (contrairement à Bedrock) ; pas de Google OAuth2 interceptor (contrairement à Vertex). Auth simplifiée mais sans signing request.
Claude Code v2.1.117 embarque un pipeline Datadog en plus du pipeline Amplitude. Nouveau en 2.1.117 (gap documenté de 2.1.104).
Module : _HK (L134129-L134130) — trackDatadogEvent: zp6, shutdownDatadog: ys, initializeDatadog: KHK.
Endpoint : https://http-intake.logs.us5.datadoghq.com/api/v2/logs (L134203 = Lc4).
Token : pubea5604404508cdd34afb69e6f42a05bc (L134204 = Jc4) — hardcodé, publiquement extractable.
Gates d'activation (B1-B2 du CFG) :
- Provider doit être
firstParty— Foundry/Bedrock/Vertex → zéro emission - GrowthBook
tengu_log_datadog_eventsdoit être activé - Détection VPN → désactivation automatique
Allowlist : 55 événements seulement (L134227-L134283). Les autres l(...) vont uniquement vers Amplitude (csH).
Scrubber AO8 (L2934) : supprime uniquement les clés préfixées _PROTO_. PII non-_PROTO_ (URLs, paths, error strings) passent en clair.
Batching : buffer mémoire esH, flush automatique à 100 entrées ou après 15 s (CLAUDE_CODE_DATADOG_FLUSH_INTERVAL_MS configurable). Shutdown flush via KK (L134118).
User bucketing : sha256(installId) % 30 → entier déterministe 0..29 (userBucket) pour staged rollouts.
Fire-and-forget : échec du POST → log seulement, pas de retry, pas de spool disque.
| Élément | Lignes |
|---|---|
Module _HK |
L134129-L134130 |
| Endpoint Datadog | L134203 |
| Token hardcodé | L134204 |
Gate yc4() |
L134319-L134327 |
Enqueue zp6() |
L134154-L134200 |
Scrubber AO8 _PROTO_* |
L2934 |
| Allowlist 55 events | L134227-L134283 |
| Buffer+flush | L134136-L134149 |
CLAUDE_CODE_DATADOG_FLUSH_INTERVAL_MS |
L134144 |
- MOYENNE : scrub très étroit (seulement
_PROTO_*). Les error strings, paths, model names, HTTP status détails passent en JSON payload Datadog. Pas de filtrage PII structuré. - Token public extractable : intentionnel (public ingest tokens write-only), mais documenter comme artefact RE.
- Foundry/Bedrock/Vertex privacy positive : zéro émission DD pour ces providers.
- [HYPOTHÈSE] :
_PROTO_plugin_namescrubbé avant DD mais reste dans Amplitude (csHL134333) — pipeline asymétrique.
Source : catalogs/apis_catalog.json (168,398 o, 452 entrées), diff/apis_diff.md.
| Domaine | Base | Exemples d'endpoints notables |
|---|---|---|
| Anthropic API core | https://api.anthropic.com |
/v1/messages, /v1/models, /v1/files |
| Sessions/environments | idem | /v1/sessions/$ID/events, /v1/environments, /v1/environments/bridge |
| Agents | idem | /v1/agents (non public) |
| OAuth/auth | idem | /v1/oauth/token, /v1/oauth/hello, /api/oauth/claude_cli/* |
| Feedback/metrics | idem | /api/claude_cli_feedback, /api/claude_code/metrics, /api/claude_code/organizations/metrics_enabled |
| Foundry (Azure) | https://<resource>.services.ai.azure.com/anthropic/ |
Standard Anthropic sur base Azure |
| mcp-proxy | https://mcp-proxy.anthropic.com |
Proxy MCP streamable HTTP |
| GitHub Copilot MCP | https://api.githubcopilot.com/mcp/ |
Copilot MCP endpoint |
| Notion MCP | https://mcp.notion.com/mcp |
Notion MCP endpoint |
| Datadog | https://http-intake.logs.us5.datadoghq.com/api/v2/logs |
Telemetry pipeline |
| claude.ai | https://claude.ai/upgrade/max, https://claude.ai/code, https://clau.de/chrome/permissions |
UI/auth |
| Docs | https://code.claude.com/docs/en/microsoft-foundry |
Nouveau en 2.1.117 |
Highlights (diff/apis_diff.md) :
https://api.anthropic.com/v1/sessions/$SESSION_ID/events?page=page_abc123— session event streamhttps://api.anthropic.com/v1/files/$FILE_ID/content— Files APIhttps://api.anthropic.com/v1/files?scope_id=$SESSION_IDhttps://mcp-proxy.anthropic.com— reverse proxy Anthropic pour MCPhttps://api.githubcopilot.com/mcp/— GitHub Copilot MCPhttps://mcp.notion.com/mcp— Notion MCPhttp-intake.logs.us5.datadoghq.com/api/v2/logs— Datadog (nouveau)https://code.claude.com/docs/en/microsoft-foundry— doc Foundry
Source : catalogs/tools_catalog.json (13,383 o), diff/tools_diff.md, EXTRACTION_REPORT.md §6 (identifier_map).
| Tool | Minified | Catégorie | Nouveau vs 2.1.104 |
|---|---|---|---|
| Agent | DK |
subagent | NON |
| Bash | d$ |
shell | NON |
| Read | Cq |
filesystem | NON |
| Edit | jK |
filesystem | NON |
| Write | U_ |
filesystem | NON |
| Glob | xf |
filesystem | NON |
| Grep | $4 |
search | NON |
| WebFetch | TY |
network | NON |
| WebSearch | Ik |
network | NON |
| TodoWrite | Gh |
planning | NON |
| NotebookEdit | cD |
notebook | NON |
| ToolSearch | aO |
meta | NON |
| Skill | qw |
skill | NON |
| EnterPlanMode | H4H |
plan | NON |
| ExitPlanMode | Rk |
plan | NON |
| AskUserQuestion | Gz |
interaction | NON (était gated) |
| REPL | Wz |
repl | NON (était gated) |
| PowerShell | m7 |
shell | OUI |
| ScheduleWakeup | $w |
async | OUI |
| Monitor | wW |
async | OUI |
| PushNotification | sc |
notification | OUI |
| SendMessage | _L |
teams | OUI |
| RemoteTrigger | V2H |
remote | OUI |
| EnterWorktree | Eu8 |
worktree | OUI |
| ExitWorktree | hu8 |
worktree | OUI |
| TaskCreate | _V |
tasks | OUI |
| TaskUpdate | bk |
tasks | OUI |
| TaskGet | ec |
tasks | OUI |
| TaskList | BJ |
tasks | OUI |
| TaskOutput | JE |
tasks | OUI |
| TaskStop | Uv |
tasks | OUI |
| CronCreate | — | cron | OUI |
| CronDelete | — | cron | OUI |
| CronList | — | cron | OUI |
| LSP | — | language | NON (était gated) |
| SendUserMessage | — | user | OUI |
Outils internes (non publics) : TeamCreate, TeamDelete, SyntheticOutput, AdvisorTool, Workflow.
| Catégorie | Count | Description |
|---|---|---|
| Filesystem | 5 | Read, Edit, Write, Glob, Grep |
| Shell | 2 | Bash, PowerShell |
| Task manager | 6 | TaskCreate/Update/Get/List/Output/Stop |
| Async/scheduling | 3 | ScheduleWakeup, Monitor, CronCreate/Delete/List |
| Teams/messaging | 2 | SendMessage, SendUserMessage |
| Worktree | 2 | EnterWorktree, ExitWorktree |
| Planning | 2 | EnterPlanMode, ExitPlanMode |
| Network | 2 | WebFetch, WebSearch |
| Remote | 1 | RemoteTrigger |
| Subagent | 1 | Agent |
| Notification | 1 | PushNotification |
| Meta | 2 | ToolSearch, TodoWrite |
| User | 1 | AskUserQuestion |
| REPL/notebook | 2 | REPL, NotebookEdit |
| Skill | 1 | Skill |
Source : catalogs/env_vars_catalog.json (188,603 o), diff/env_vars_diff.md.
| Namespace | Count | Exemples représentatifs |
|---|---|---|
CLAUDE_CODE_* |
~220 | DISABLE_ADVISOR_TOOL, EXPERIMENTAL_AGENT_TEAMS, IDLE_THRESHOLD_MINUTES, SCRIPT_CAPS, SUBPROCESS_ENV_SCRUB |
ANTHROPIC_* |
~60 | FEDERATION_RULE_ID, ORGANIZATION_ID, FOUNDRY_BASE_URL, FOUNDRY_API_KEY, IDENTITY_TOKEN, IDENTITY_TOKEN_FILE, SERVICE_ACCOUNT_ID |
AWS_* |
~50 | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_BEARER_TOKEN_BEDROCK |
AZURE_* |
~10 | AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH |
GOOGLE_* |
~5 | GOOGLE_APPLICATION_CREDENTIALS |
OTEL_* |
~10 | OpenTelemetry exporter vars |
GITHUB_* / ACTIONS_* |
~15 | ACTIONS_ID_TOKEN_REQUEST_TOKEN, ALL_INPUTS, OVERRIDE_GITHUB_TOKEN, etc. |
| Autres | ~170 | Proxy, paths, debug, misc |
ANTHROPIC_API_KEY CLAUDE_CODE_OAUTH_TOKEN
ANTHROPIC_AUTH_TOKEN ANTHROPIC_FOUNDRY_API_KEY
ANTHROPIC_AWS_API_KEY ANTHROPIC_BEDROCK_MANTLE_API_KEY
ANTHROPIC_CUSTOM_HEADERS OTEL_EXPORTER_OTLP_* (4 vars)
AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
AWS_BEARER_TOKEN_BEDROCK GOOGLE_APPLICATION_CREDENTIALS
AZURE_CLIENT_SECRET AZURE_CLIENT_CERTIFICATE_PATH
ACTIONS_ID_TOKEN_REQUEST_TOKEN ACTIONS_ID_TOKEN_REQUEST_URL
ACTIONS_RUNTIME_TOKEN ACTIONS_RUNTIME_URL
ALL_INPUTS OVERRIDE_GITHUB_TOKEN
DEFAULT_WORKFLOW_TOKEN SSH_SIGNING_KEY
Source : cfg/sandbox_env_check.md §B8.
| Variable | Rôle |
|---|---|
ANTHROPIC_FEDERATION_RULE_ID |
OIDC federation rule |
ANTHROPIC_ORGANIZATION_ID |
Org pour OIDC |
ANTHROPIC_IDENTITY_TOKEN |
JWT inline |
ANTHROPIC_IDENTITY_TOKEN_FILE |
JWT via fichier |
ANTHROPIC_SERVICE_ACCOUNT_ID |
SA OIDC |
ANTHROPIC_FOUNDRY_BASE_URL |
URL Foundry |
ANTHROPIC_FOUNDRY_API_KEY |
Clé Foundry |
ANTHROPIC_FOUNDRY_RESOURCE |
Resource Azure pour URL derivation |
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS |
Activation Teams |
CLAUDE_CODE_IDLE_THRESHOLD_MINUTES |
Seuil idle AFK (défaut 75 min) |
CLAUDE_CODE_IDLE_TOKEN_THRESHOLD |
Seuil tokens idle (défaut 100K) |
CLAUDE_CODE_REMOTE_MEMORY_DIR |
Mémoire remote cross-session |
CLAUDE_CODE_DATADOG_FLUSH_INTERVAL_MS |
Flush telemetry (défaut 15s) |
CLAUDE_CODE_DISABLE_ADVISOR_TOOL |
Kill switch advisor |
CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL |
Force-on advisor |
CLAUDE_CODE_SCRIPT_CAPS |
JSON cap per-substring pour Bash |
Source : catalogs/beta_headers_catalog.json (31 entrées), diff/beta_headers_diff.md.
| Header | Date | Interprétation produit |
|---|---|---|
ccr-byoc-2025-07-29 |
2025-07 | Remote Control BYOC (Bring Your Own Cloud) — bridge multi-tenant |
files-api-2025-04-14 |
2025-04 | Files API (probablement déjà stable en 2.1.104) |
structured-outputs-2025-12-15 |
2025-12 | JSON structured outputs |
advanced-tool-use-2025-11-20 |
2025-11 | Améliorations tool use pipeline |
effort-2025-11-24 |
2025-11 | Contrôle niveau d'effort modèle |
afk-mode-2026-01-31 |
2026-01 | Mode AFK avec classifier auto |
ccr-triggers-2026-01-30 |
2026-01 | RC triggers déclenchement distant |
redact-thinking-2026-02-12 |
2026-02 | Redact thinking blocks |
fast-mode-2026-02-01 |
2026-02 | Fast mode Opus |
compact-2026-01-12 |
2026-01 | Compaction mémoire |
task-budgets-2026-03-13 |
2026-03 | Budgets tokens par task |
advisor-tool-2026-03-01 |
2026-03 | Advisor server-side tool |
context-hint-2026-04-09 |
2026-04 | Context hints pour modèle |
managed-agents-2026-04-01 |
2026-04 | Agents managés (Agent Teams public ?) |
oidc-federation-2026-04-01 |
2026-04 | OIDC Federation enterprise |
mcp-client, mcp-servers, message-batches, token-counting, web-search, interleaved-thinking, context-1m, context-management.
- Q3 2025 → BYOC infrastructure, Files API
- Q4 2025 → Structured outputs, effort control, advanced tool use
- Jan 2026 → AFK mode, RC triggers, compact memory
- Fév 2026 → Fast mode, redact thinking
- Mars 2026 → Task budgets, Advisor tool
- Avr 2026 → Managed agents (Teams GA ?), OIDC enterprise, context hints
La fenêtre managed-agents-2026-04-01 suggère que les Agent Teams passeront en GA courant Q2 2026.
Source : cfg/*.md (10 fichiers, ~90 KB total).
| Fonction | Fichier CFG | Blocs | Points-clés |
|---|---|---|---|
C4H = installResolvedPlugin |
plugin_install.md |
B1-B6 (+ B7 sub-CFG) | 8 policy reason codes ; transactionnel avec rollback l_$ ; telemetry tengu_plugin_installed marker "third-party" |
pluginValidate |
plugin_validate.md |
B1-B10 | Zod schema L45370-L46005 ; gitCommitSha optionnel ; path poisoning check L378813 ; soft-warn kebab-case L432853 |
tryConnectRemoteControl = ve6() |
remote_control_bridge.md |
B1-B14 | 7 gates séquentielles ; state machine 4 états ; multi-session flag ; token setup-token rejeté |
xaaFullFlow = oz$ |
oidc_token_exchange.md |
PRM→AS→exchange | RFC 9728 + 8414 + 8693/7523 ; HTTPS obligatoire ; issuer mismatch rejeté |
spawnInProcessTeammate = pU8 + Task tools |
agent_team_dispatch.md |
B1-B15 | 15 blocs ; flat topology enforced ; transactionnel mCH+rollback ; task queue sextuplet |
tkK (advisor gate) |
advisor_gate.md |
B1-B7 | Gate feature Uh() → gate base WfH() → gate advisor Z$8() → enqueue advisor_20260301 ; retry strip sur 400 |
setAfkModeHeaderLatched + circuit-break |
afk_latch.md |
— | Latch dans x8.afkModeHeaderLatched ; circuit-break fail-open L481885 ; idle thresholds configurable |
createClient branche foundry |
foundry_auth.md |
B1-B9 | Azure DAC chain ; mutex apiKey/azureADTokenProvider ; baseURL derivation depuis resource ; features désactivées |
zp6 (Datadog enqueue) + Ap6 (flush) |
datadog_telemetry.md |
B1-B10 | Provider firstParty guard ; allowlist 55 events ; scrub _PROTO_* narrow ; fire-and-forget ; token public hardcodé |
zc4/U5 (sandbox trust) + Tk (subprocess env) |
sandbox_env_check.md |
B1-B12 | 23-var scrub list ; macOS sandbox-exec -p ; Linux bwrap + seccomp ; Windows = env scrub seulement ; sd6 script-caps anti-exfil |
- Latch + session state : même pattern pour
afkModeHeaderLatched,fastModeHeaderLatched,cacheEditingHeaderLatched,thinkingClearLatcheddansx8(L2099) — on peut prédire de nouveaux latches pour les prochaines features beta. - Gate feature flag GrowthBook :
y8("tengu_XXX", false)sync ouFT("tengu_YYY")async — tous les blocs critiques passent par cette abstraction. - Transactionnel reserve+rollback :
mCH(team file update) +l_$(rollback L322929) — pattern réutilisable dans notreWorkerPool. - Fail-open sur circuit-break : AFK, advisor strip retry, classifier unavailable → tous continuent sans bloquer.
Source : identifier_map_2.1.117.json (49,048 o).
| Métrique | Valeur |
|---|---|
| Total identifiants 2.1.117 | 143,536 |
| Identifiants mappés (ce run) | 225 |
| Nouveaux vs 2.1.104 (estimé) | ~2,500 |
| Méthode | Cross-ref contexte + string neighbors + callsite grouping |
| Domaine | Count | Exemples remarquables |
|---|---|---|
| Advisor | 12 | tkK=resolveAdvisorModel, WfH=baseModelSupportsAdvisor, Z$8=isValidAdvisorModel |
| OIDC/Federation | 18 | oz$=xaaFullFlow, rD1=GRANT_TYPE_TOKEN_EXCHANGE, w0_=GRANT_TYPE_JWT_BEARER |
| Remote Control | 14 | ve6=checkRemoteControlEligibility, Og8=isRemoteControlAvailable, $IH=isInsideRemoteSession |
| Agent Teams | 22 | pU8=spawnInProcessTeammate, qq8=killTeammate, JV8=buildTeammateContext |
| AFK/Auto-mode | 8 | fO8=setAfkModeHeaderLatched, lA6=getAfkModeHeaderLatched, x8=globalSessionState |
| Feature flags | 6 | y8=getSyncFeatureFlag, FT=getAsyncFeatureFlag |
| Session/runtime | 8 | E8=getCurrentSessionId, W16=rotateSessionId |
| XAA | 15 | eD1=xaaDiscoverPRM, Hw1=xaaDiscoverAuthorizationServer, PA8=redactTokenInJson |
| Divers core | 122 | ej=getTrimmedEnvVar, Yp$=getAnthropicConfigDirSync, etc. |
// Feature flags (universels)
y8 = getSyncFeatureFlag // y8("tengu_ccr_bridge", false)
FT = getAsyncFeatureFlag // await FT("tengu_ccr_bridge")
// Session state global
x8 = globalSessionState // { afkModeHeaderLatched, fastModeHeaderLatched, sessionId, ... }
E8 = getCurrentSessionId // return x8.sessionId
W16 = rotateSessionId // x8.sessionId = randomUUID()
// XAA grant types (constantes)
rD1 = GRANT_TYPE_TOKEN_EXCHANGE // "urn:ietf:params:oauth:grant-type:token-exchange"
w0_ = GRANT_TYPE_JWT_BEARER // "urn:ietf:params:oauth:grant-type:jwt-bearer"
oD1 = SUBJECT_TOKEN_TYPE_JWT // "urn:ietf:params:oauth:token-type:jwt"
// Advisor whitelist
WfH = baseModelSupportsAdvisor // /opus-4-7|opus-4-6|sonnet-4-6/.test(model)
Z$8 = isValidAdvisorModel // même regexVecteur principal (OWASP A08) : le marketplace officiel github:anthropics/claude-plugins-official est le point de défaillance central. Aucune signature cryptographique vérifiée côté client. Un push sur la branche main compromise tous les utilisateurs sans pin gitCommitSha.
7 vecteurs documentés (internals/plugin_system.md §6.1) :
| # | Vecteur | Mitigation actuelle | Gap |
|---|---|---|---|
| A | Typosquat marketplace | Kebab-case soft-warn (L432853) | Unicode confusables non bloqués |
| B | Dependency injection | Root-only trust (L197899) | Transitive trust du marketplace racine uniquement |
| C | Path traversal | Check isInside(Y) (L378813) |
Couvert |
| D | Seed-dir re-registration | Message warning (L378644) | Persistence silencieuse au démarrage |
| E | JSON registry editable | Détection corrupted installLocation (L378813) |
Lecture-écriture sans intégrité |
| F | Manifest conflict | Erreur explicite (L199321) | strict:true peut être overridé |
| G | Branche stats GitHub |
N/A | Fingerprint d'adoption en clair |
Recommandations pour poc-inter-cli : si on ajoute un marketplace de skills, signature ed25519 obligatoire dès la conception ; pin de hash par défaut ; seed_dir = read-ACK-only.
23 variables scrubbées dans les subprocess (M4f) — liste exhaustive au §6.2.
Variables "skip-auth" à risque : CLAUDE_CODE_SKIP_FOUNDRY_AUTH, CLAUDE_CODE_SKIP_BEDROCK_AUTH, CLAUDE_CODE_SKIP_VERTEX_AUTH, CLAUDE_CODE_SKIP_ANTHROPIC_AWS_AUTH — toutes permettent un bypass auth pour tests mais envoient quand même la requête réseau.
Secrets en clair dans config : service_account_id dans <profile>.json ; federation_rule_id masqué à l'affichage mais pas dans le fichier.
Token Datadog hardcodé : pubea5604404508cdd34afb69e6f42a05bc (L134204) — public ingest token write-only, extractable par quiconque dispose du binaire.
Protections effectives : rejet setup-token (L260756), anti-double-hop (L260751), policy managée allow_remote_control (L467591), version check serveur (L260849).
Risques résiduels :
- Tool approval depuis mobile sans contexte local complet (§F2, OWASP A04)
- Debug dump
hSf(L260763) inventorie 11+ vars d'auth — surveiller les logs bridge_urlexact non extrait — impossible de confirmer l'isolation réseau sans mitmproxy- Alias
--rcavechideHelp(L554438) — obscurité d'une feature de sécurité
macOS (B11) : sandbox-exec -p <profile> avec deny réseau, règles filesystem ed6, mach lookups restreints. Couvert.
Linux (B12) : bwrap --unshare-net --unshare-pid [--unshare-user] --dev /dev --proc /proc + seccomp BPF via apply-seccomp (L174255) + socat bridge UNIX socket pour proxy HTTP. Couvert.
Windows : aucun JobObject, AssignProcessToJobObject, CreateJobObject détecté (cfg/sandbox_env_check.md §notes F12). La protection Windows repose uniquement sur :
- Env scrub (
M4f23 vars) - Trust dialog +
hasTrustDialogAccepted x-anthropic-additional-protection: true(header serveur, L122105)
Absence de CLAUDE_CODE_BASH_SANDBOX_SHOW_INDICATOR efficace sur Windows — l'user Windows ne voit pas la différence sandboxed/non-sandboxed.
Script-caps CLAUDE_CODE_SCRIPT_CAPS (L174630) : protection anti-exfiltration par répétition (ex: {"curl": 5}). Disponible sur tous les OS.
AO8 (L2934) scrub uniquement les clés _PROTO_*. Tout le reste (URLs, paths, error messages, model names) passe en JSON payload Datadog.
Les _PROTO_plugin_name et _PROTO_marketplace_name sont scrubbés avant Datadog mais restent dans Amplitude (pipeline csH L134333 parallèle non filtré).
| Feature | Pattern fail-open | Impact |
|---|---|---|
| AFK circuit-break | Serveur rejette beta → header droppé, auto-mode continue (L481885) | Silent fallback |
| Advisor strip retry | 400 spécifique → strip + un retry, pas de blocage (L481894) | Résultat potentiellement dégradé |
| Auto-mode classifier unavailable | Fallback "Classifier unavailable" → décision implicite permissive (L400625) |
Tool calls approuvés sans classifier |
| Datadog flush failure | Log seulement, pas de retry (L134139) | Perte d'événements silencieuse |
| Foundry skip-auth | () => Promise.resolve("") → Bearer vide envoyé quand même (L122147) |
Requête part vers prod avec token vide |
Task Manager (TaskCreate/Update/Get/List/Output/Stop) : notre src/orchestrator.js gère les missions comme des entités monolithiques. La séparation task queue (TaskCreate) + assignment (TaskUpdate owner) + output stream (TaskOutput) est plus composable. Alignement avec nos mission.enqueue + plan.phase concepts.
Flat topology enforcement : notre orchestrateur supporte déjà le modèle hub-spoke (workers non récursifs), mais rien ne l'enforce côté protocole. Ajouter une guard if (msg.params.parentWorker) throw dans handleWorkerMessage.
TransactionalReserve+Rollback (pattern mCH + l_$, CFG agent_team_dispatch B5) : notre WorkerPool.spawn() devrait écrire l'identité dans un registre avant init, puis rollback atomiquement si l'init échoue. Actuellement, un spawn raté peut laisser un worker "fantôme" dans le registre.
Hook TeammateIdle : notre WorkerProfile.affinity routing peut bénéficier d'un hook workerIdle émis quand un worker n'a plus de tâche. Cela permettrait un re-routing dynamique sans polling.
State machine formelle pour Telegram bridge : états connecting → active → reconnecting → failed (L313103-L313106) pour notre telegram-bridge.js. Actuellement les états sont implicites.
AFK latching pattern : notre /loop (ScheduleWakeup + CronCreate dans Claude Code) pourrait bénéficier d'un latch de mode session. Quand l'user lance /loop, latcher un flag "autonomous" dans le session state global, et le reset proprement sur interruption ou complétion.
Advisor two-gate : le pattern "vérifier base model + vérifier advisor model séparément" est adaptatif pour notre routage de workers. WorkerProfile.affinity + canHandleTask(taskType) = deux gates similaires. Précaution : ne pas utiliser des whitelists identiques pour les deux gates — maintenir une asymétrie explicite.
Batching telemetry Datadog (buffer 100, timer 15s) : notre events.jsonl est append-only et synchrone. Le pattern async batch + flush sur shutdown est plus performant pour des flux d'événements denses.
Plugin scopes (user vs project) : notre système de skills n'a qu'un scope global. Ajouter scope: "project" (stocké dans .claude/settings.json partageable via git) pour les skills d'équipe.
8 reason codes granulaires : nos permission-gate.js 4 modes pourraient être enrichis avec des reason codes (blocked-by-policy, dependency-blocked, marketplace-blocked, etc.) pour un meilleur diagnostic auditeur.
Plugin system sans signature crypto : si on ajoute un marketplace de skills, ed25519 détaché obligatoire. Le gap de Claude Code ici est documenté comme F1.
Re-registration automatique depuis seed_dir : antipattern pour persistence malveillante. Read-ACK-only uniquement.
Approbation de tool calls à distance sans contexte (RC) : notre Tauri affiche déjà le diff complet dans la ConfirmDialog — conserver cette supériorité UX vs le mobile RC de Claude Code.
hideHelp sur une feature de sécurité : l'alias --rc en mode caché (L554438) est un antipattern. Tout ce qui touche à la sécurité doit être dans /help.
Datadog avec token hardcodé : si on ajoute de la telemetry, token via config ou env var, jamais embarqué dans le binaire.
| Zone | Outil requis | Gain attendu |
|---|---|---|
| Bytecode JSC (106.8 MB) | Décodeur JSC Bun actualisé (magic changé vs 2.1.98) | Logique compilée non accessible en statique |
Transport bridge RC (bridge_url) |
mitmproxy + claude remote-control |
URL exacte, format messages, chiffrement |
| Token exchange OIDC endpoint exact | mitmproxy + session fédérée | Confirmer URL, payload, refresh cycle |
| Schémas Zod complets des 42 tools | Grep input_schema + webcrack |
Validation stricte côté client vs serveur |
Native bindings (.node) |
pefile + lief sur les bindings embarqués |
Surface d'attaque native (conpty, pty, audio) |
| Windows Job Object | x64dbg dynamique + QueryInformationJobObject |
Confirmer absence de sandbox Windows |
| Sandbox seccomp BPF profile | Extraction binary apply-seccomp (L174255) |
Liste exacte des syscalls autorisés |
L'analyse dynamique aurait permis :
- Breakpoints sur
LoadLibrarypour observer le boot loader Bun - Dump heap JS post-init → closures résolues au lieu de minifiées
- Capture des appels
child_process.spawnavec args réels (sandbox params)
Raison du non-usage : complexité du setup Bun self-contained (pas de DLL séparée, heap JS dans le process unique), et valeur suffisante de l'analyse statique pour ce run.
- [P0] Audit mitmproxy du RC bridge — capturer
bridge_url+ format messages + handshake - [P0] Windows sandbox gap — confirmer absence Job Object via instrumentation dynamique
- [P1] Schema extraction Zod des 42 tools — grep
input_schemasur beautified - [P1] 906 telemetry events
tengu_*complets —grep tengu_ catalogs/strings_extracted_report.txt - [P2] OIDC token exchange endpoint exact — mitmproxy sur session fédérée
- [P2]
SyntheticOutputtool (internal) — comprendre le mécanisme de consensus multi-agent - [P3] Bytecode JSC décodage — si un décodeur compatible devient disponible
| Sujet | Fichier artefact | Lignes clés |
|---|---|---|
Plugin manifeste plugin.json |
internals/plugin_system.md |
L198665-L198667, L45370 |
| Plugin supply-chain 7 vecteurs | internals/plugin_system.md §6.1 |
L194628, L197682, L378813, L432853 |
| Plugin install CFG complet | cfg/plugin_install.md |
L198214-L198270, L198336 |
RC gate ve6() 7 étapes |
cfg/remote_control_bridge.md |
L260749-L260759, L467591 |
RC rejet setup-token |
internals/remote_control.md §3.1 |
L260756 |
| RC state machine | internals/remote_control.md §4.1 |
L313103-L313106 |
| OIDC env-quad | internals/oidc_federation.md §2.1 |
L37309-L37314 |
| XAA PRM discovery (RFC 9728) | internals/oidc_federation.md §6.2 |
L388974-389028 |
| XAA grant types RFC 8693/7523 | identifier_map_2.1.117.json |
mappings rD1, w0_, oD1 |
| Teams flat topology | internals/agent_teams_swarm.md §2.1 |
L333270, L224476 |
| Teams spawn transactionnel | cfg/agent_team_dispatch.md B5-B6 |
L322920, L229025, L322929 |
AFK latch state global x8 |
internals/afk_mode.md §2.1 |
L2099, L481885 |
| AFK idle thresholds | internals/afk_mode.md §4.3 |
L527095-L527097 |
| Advisor gate deux-fonctions | cfg/advisor_gate.md B4-B5 |
L223361, L223365 |
| Advisor whitelist models | identifier_map_2.1.117.json |
WfH, Z$8 L223361-L223369 |
| Foundry Azure auth | cfg/foundry_auth.md B5-B8 |
L122143-L122156, L97353-L97400 |
| Foundry mutex constructor | cfg/foundry_auth.md |
L97367 |
| Datadog token hardcodé | cfg/datadog_telemetry.md |
L134203-L134204 |
Datadog scrub _PROTO_* |
cfg/datadog_telemetry.md |
L2934 |
Sandbox macOS sandbox-exec |
cfg/sandbox_env_check.md B11 |
L173536 |
Sandbox Linux bwrap |
cfg/sandbox_env_check.md B12 |
L173144, L174255 |
| Sandbox Windows gap | cfg/sandbox_env_check.md §notes F12 |
— |
Scrub subprocess 23 vars M4f |
cfg/sandbox_env_check.md B8 |
L174684 |
| Script-caps anti-exfil | cfg/sandbox_env_check.md B10 |
L174628-L174668 |
E:/tmp/claude_extracted/2.1.117/
├── EXTRACTION_REPORT.md (7,189 o)
├── baseline_2.1.104.md (35,312 o)
├── identifier_map_2.1.117.json (49,048 o — 225 mappings)
│
├── raw/
│ ├── claude-code-v2.1.117.js (39,472,885 o — avec bytecode)
│ └── claude-code-v2.1.117.clean.js (13,128,629 o — JS pur)
│
├── beautified/
│ └── cli.beautified.js (19,339,722 o — ~545K lignes)
│
├── deobfuscated/ (vide ce run — webcrack non lancé)
│
├── catalogs/
│ ├── apis_catalog.json (168,398 o — 452 entrées)
│ ├── tools_catalog.json (13,383 o — 42 outils)
│ ├── env_vars_catalog.json (188,603 o — 540 vars)
│ ├── beta_headers_catalog.json (13,463 o — 31 headers)
│ ├── strings_extracted.json (5,303,477 o)
│ └── strings_extracted_report.txt (76,231 o)
│
├── internals/
│ ├── plugin_system.md (10,647 o)
│ ├── remote_control.md (10,792 o)
│ ├── oidc_federation.md (12,196 o)
│ ├── agent_teams_swarm.md (15,057 o)
│ ├── afk_mode.md (12,317 o)
│ ├── advisor_tool.md (13,702 o)
│ ├── identifiers-raw.txt (1,436,431 o — 143,536 identifiants)
│ └── identifier-extraction-summary.md (448 o)
│
├── diff/
│ ├── apis_diff.md (13,922 o)
│ ├── tools_diff.md (12,507 o)
│ ├── env_vars_diff.md (20,024 o)
│ ├── beta_headers_diff.md (10,817 o)
│ └── structural_diff.md (38,698 o)
│
└── cfg/
├── plugin_install.md (7,534 o)
├── plugin_validate.md (7,256 o)
├── remote_control_bridge.md (8,149 o)
├── oidc_token_exchange.md (9,066 o)
├── agent_team_dispatch.md (11,092 o)
├── advisor_gate.md (7,567 o)
├── afk_latch.md (7,938 o)
├── foundry_auth.md (10,407 o)
├── datadog_telemetry.md (9,999 o)
└── sandbox_env_check.md (14,621 o)
E:/sources/poc-inter-cli/reverse/2.1.117/
└── README.md (ce fichier)
| Script | Emplacement |
|---|---|
01_extract_strings.cjs |
E:/sources/poc-inter-cli/reverse/2.1.117/ |
02_extract_identifiers.cjs |
idem |
Analyse produite le 2026-04-22. Version Claude Code analysée : 2.1.117 (build 2026-04-21). Analyste : Jacques Gariepy via poc-inter-cli RE toolkit. Tous les numéros de ligne référencent E:/tmp/claude_extracted/2.1.117/beautified/cli.beautified.js.