Aller au contenu

Configuration

Tout se règle dans deux fichiers TOML, et un profil en Markdown.

Fichier Rôle Versionné ?
config/workspace.toml Défauts partagés, livrés avec le projet oui
config/workspace.user.toml Vos réglages — ils priment, clé par clé non (gitignoré)
planning/Runner_Profile.md Votre profil : physiologie, blessures, matériel, préférences non

La façon normale de les remplir est /coach-setup. Rien n'interdit de les éditer à la main ensuite.

Annuler un héritage

Une clé présente mais vide dans workspace.user.toml gagne sur la valeur partagée. C'est ainsi qu'on efface une valeur au lieu de la remplacer.

Le staff — [agents]

[agents]
enabled = ["coach", "medical", "nutritionist", "course-strategist"]

Seuls les agents listés sont installés, et le coach ne délègue qu'à eux. coach est indispensable : c'est lui qui planifie et pousse vers le calendrier Garmin.

./install.sh --no-medical                  # tout sauf le médecin
./install.sh --agents coach,nutritionist   # staff explicite

L'option écrit [agents].enabled, si bien qu'une réinstallation sans option respecte votre choix. Réactiver un agent le réinstalle ; le désactiver le retire pour de bon des dossiers .claude/agents, .opencode/agents et .github/agents.

Ce que vous perdez en retirant un agent :

Retiré Conséquence
medical Plus de gatekeeper ni de protocole blessure. Le coach applique lui-même [health].morning_check et vous renvoie vers un vrai médecin pour tout ce qui est clinique.
nutritionist Plus de plan de macros ni de poids de forme. Le coach garde des conseils de ravitaillement génériques dans les notes de séance.
course-strategist Plus de plan de course détaillé. Le coach analyse quand même un GPX avec le skill gpx-analysis.

Le bilan matinal — [health]

[health]
morning_check = "full"   # full | minimal | off
Valeur Ce que fait le coach
full HRV + FC de repos + readiness avant toute décision de séance. Défaut, recommandé.
minimal Readiness seule, en une ligne. Aucune annulation sur les seules données de santé.
off Aucune donnée de santé récupérée. Planification sur la charge d'entraînement et votre ressenti.

Ce n'est pas la même chose que retirer l'agent medical

Le bilan matinal est un mandat porté par le coach, pas par le médecin. Retirer l'agent medical ne le désactive pas — il faut morning_check. Inversement, off n'empêche pas le médecin de répondre à une question de santé que vous posez.

Passez à minimal ou off si votre montre ne mesure pas la HRV, ou si vous ne souhaitez pas que votre entraînement dépende de ces données.

Le seuil de chaleur — [health].heat_threshold_c

[health]
heat_threshold_c = 25.0   # °C, borne INCLUSE

Une séance outdoor compte comme « chaude » (KPI d'acclimatation à la chaleur,

38) quand la température maximale du jour au lieu de la séance est ≥ ce

seuil. Défaut 25 °C. Indépendant de morning_check ci-dessus : le calcul joint les activités et la météo, il ne dépend pas du bilan matinal — il tourne même avec morning_check = "off".

Une valeur invalide ne casse jamais l'index

heat_threshold_c = "chaud" (ou tout autre texte non numérique, ou un booléen) ne fait planter ni scripts/arc_index.py, ni le tableau de bord : un avertissement est affiché et le défaut (25 °C) s'applique à la place.

La source de données — [data].source (#68)

[data]
source = "garmin"   # garmin (défaut) | intervals

Écrite automatiquement par ./install.sh --source garmin|intervals — voir Configuration Garmin et Configuration Intervals.icu. Change les outils MCP appelés par coach/medical/garmin-daily-sync pour les activités, la santé et le calendrier planifié (table de correspondance complète dans AGENTS.md). Sans montre Garmin, intervals ouvre le projet aux données COROS/Suunto/Polar/Apple synchronisées sur Intervals.icu.

Fonctionnalités indisponibles avec intervals

Le score de readiness algorithmique de Garmin, le téléchargement FIT (et les KPI qui en dépendent) et l'upload de parcours n'ont pas d'équivalent câblé dans ce projet côté Intervals.icu — l'agent le dit explicitement plutôt que d'inventer une valeur. Détail dans Configuration Intervals.icu.

Le style de coaching — [coaching]

[coaching]
style     = "bienveillant"   # bienveillant | exigeant | factuel | pedagogue
intensity = "balanced"       # gentle | balanced | strong
verbosity = "standard"       # brief | standard | detailed

Styles de coaching

Style Ce que ça change
bienveillant Chaleureux, valorise la régularité, explique le pourquoi.
exigeant Direct, vous tient à vos engagements, nomme les séances manquées, ne console pas.
factuel Verdict d'abord, chiffres, zéro remplissage motivationnel.
pedagogue Développe la physiologie derrière chaque décision.

intensity règle la fermeté (proposer / recommander / trancher), verbosity la longueur. Le catalogue complet, avec les règles qui s'appliquent quel que soit le style, est dans config/coaching-styles.md.

Le style ne change jamais le fond

Une séance annulée pour raison médicale reste annulée en bienveillant comme en exigeant. Le ton décide de la formulation, jamais du verdict.

Ce qui ne rentre pas dans un identifiant — « ce qui me motive », « ne me parle jamais de mon poids » — s'écrit dans la section « Préférences de coaching » de votre profil, qui prime sur le catalogue.

La discipline — [sport]

[sport]
primary     = "trail"    # trail | road
disciplines = ["cycling", "strength"]

primary charge un profil de sport qui définit l'unité de charge, le vocabulaire des séances, les corrections de terrain et le matériel par défaut.

Profil Raisonne en
trail Temps d'effort et D+ ; corrections de terrain ; marche rapide prescrite en forte pente.
road Kilomètres et allures dérivées d'une performance récente ; pas d'objectif de D+.

disciplines liste vos sports croisés : ce sont les seuls que le coach s'autorise à programmer.

L'athlète — [athlete]

[athlete]
profile = "planning/Runner_Profile.md"
units   = "metric"       # metric | imperial

Deux champs du profil changent le quotidien :

  • Lieu par défaut — sans lui, la météo est redemandée à chaque validation.
  • Créneau habituel — sans lui, le coach doit vous le demander avant de placer vos séances.

Deux champs de la section « Physiologie » alimentent le tableau de bord : FC max et FC de repos de référence (la FC au seuil et le sexe, facultatifs, affinent le calcul de charge).

Méthode des zones FC — [athlete].hr_zones

[athlete]
hr_zones = "auto"   # auto | lthr | karvonen | percent_max

Détermine comment le temps en zone et la polarisation 80/20 (#43) sont calculés à partir des champs de la section « Physiologie » du profil :

Valeur Méthode Repli si le champ requis manque
auto (défaut) FC au seuil (LTHR) si connue, sinon Karvonen (FC max/repos), sinon %FCmax (FC max seule) — c'est la précédence elle-même
lthr Force la FC au seuil Rien (jamais de repli implicite)
karvonen Force la réserve FC (FC max − FC repos) Rien si FC max ou repos absente
percent_max Force le %FCmax Rien si FC max absente

Une valeur autre que auto force cette méthode, sans repli automatique vers une autre si le champ requis manque au profil.

Les métriques dérivées — [metrics]

[metrics]
climb_min_gain_m = 50.0      # m, gain d'altitude minimal pour détecter une montée
climb_min_grade_pct = 5.0    # points de %, pente moyenne minimale

Détection des montées (VAM, #46) : les deux critères doivent être atteints pour qu'une montée soit reconnue. Ajustez au terrain habituel — montez climb_min_gain_m en plaine vallonnée pour ignorer les faux plats, descendez-le en montagne pour capter de courts raidillons.

Les garde-fous — [guardrails]

[guardrails]
enabled = true
r1_acwr_max = 1.3
r2_volume_increase_max_pct = 10.0
r2_volume_reference = "mean4"           # mean4 (défaut) | previous_week
r3_elevation_increase_max_pct = 10.0
r4_monotony_max = 2.0
r6_long_run_share_max_pct = 35.0
severity_r1_acwr_projected = "warn"     # info | warn | block
severity_r2_weekly_volume_jump = "warn"
severity_r3_weekly_elevation_jump = "warn"
severity_r4_monotony_projected = "warn"
severity_r5_quality_after_red = "block"
severity_r6_long_run_share = "warn"
severity_r7_consecutive_quality = "warn"

Chaque règle (R1 à R7) a sa propre clé severity_<id> — seule R5 (qualité après un verdict santé rouge) bloque par défaut, les autres sont warn. Le détail de chaque règle (R2 : hausse de volume, R3 : hausse de D+, R4 : monotonie de Foster, R6 : part de la plus longue sortie, R7 : deux séances de qualité rapprochées) est dans Les garde-fous.

Le moteur de garde-fous déterministe (scripts/arc_guardrails.py) est un second avis purement calculé, consulté par le coach avant d'écrire une semaine et avant de la pousser au calendrier Garmin. Chaque règle (R1 à R7) a son seuil et sa sévérité propres — voir la page dédiée pour le détail, les sources et le format de sortie.

Le style ne change jamais le fond, ici non plus

Une violation block (par défaut : qualité après un verdict rouge seulement — voir ci-dessous) reste bloquante quel que soit [coaching].style — voir « Le style ne change jamais le fond » ci-dessus.

R1 (ACWR) est warn par défaut, pas block

Les seuils publiés pour le ratio de charge aiguë/chronique viennent d'études en sports collectifs, avec une méthode de calcul différente de celle utilisée ici (voyez la page dédiée pour le détail) — la preuve est elle-même discutée dans la littérature de course à pied. Remettez severity_r1_acwr_projected à "block" si vous préférez la fermeté.

Le drapeau de risque de blessure

Section absente de config/workspace.toml par défaut

Contrairement aux sections ci-dessus, [injury_risk] n'a pas de valeurs livrées dans config/workspace.toml — chaque seuil a un défaut intégré au script (scripts/arc_guardrails.py). Le bloc ci-dessous n'est utile que si vous voulez surcharger un ou plusieurs seuils : ajoutez-le à config/workspace.user.toml avec uniquement les clés que vous changez.

[injury_risk]
enabled = true
acwr_max = 1.3
monotony_max = 2.0
pain_score_threshold = 4.0               # (0, 10]
pain_consult_threshold = 7.0             # (0, 10] — douleur sévère : level forcé "high", consult: true
pain_window_days = 3                     # entier >= 1
mismatch_ratio_max = 1.3
sleep_debt_alert_s = 36000               # 10 h, en secondes

Section [injury_risk]. Drapeau composite (#57, scripts/arc_guardrails.py injury-risk) qui combine ACWR/monotonie réels, douleur déclarée, écart effort perçu/charge FC, dette de sommeil et verdict rouge récent en un niveau à 3 paliers (low/moderate/high), toujours non-diagnostique — voir la page dédiée pour le détail de chaque facteur, ses conditions de saut (historique insuffisant, bilan matinal désactivé…) et l'escalade automatique à high sur une douleur sévère. Une valeur hors plage (ex. pain_score_threshold = 15, pain_window_days = 0.5) retombe sur son défaut avec un avertissement sur stderr, jamais silencieusement.

Le tableau de bord — [dashboard]

[dashboard]
port = 8765

Port du tableau de bord local. S'il est pris, les 9 suivants sont essayés. L'adresse d'écoute, elle, n'est pas réglable : 127.0.0.1 uniquement. Seul le conteneur Docker écoute ailleurs, derrière un reverse proxy authentifié.

La langue — [language]

[language]
documents = "fr"    # code ISO 639-1 des fichiers Markdown persistés
responses = "auto"  # auto = même langue que la requête de l'utilisateur
Clé Effet
documents Langue des fichiers Markdown écrits par les agents/skills (activities/, medical/, nutrition/, planning/, rapports/) — titres, tableaux, labels, contenu. Défaut fr.
responses Langue des réponses à l'utilisateur dans la conversation. auto (défaut) reprend la langue de la requête ; une valeur explicite (en, nl…) la fige, y compris pour les commandes headless (/garmin-daily-sync) qui n'ont pas de requête à imiter.

Les instructions des agents/skills restent en anglais ou en français selon le fichier — seule la langue de sortie (documents persistés, réponses) est réglée ici.

Notifications et synchronisation

[notifications] et [sync] sont décrits dans Votre workspace privé et Le coach dans la poche.

Vérifier

python3 scripts/coach_setup.py --status

Affiche le workspace détecté, les questions restant à poser, les fichiers installés et si votre configuration personnelle est bien exclue de git.