create-byan-agent 2.60.0 → 2.60.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +10 -0
  3. package/install/bin/byan-communication.cjs +11 -0
  4. package/install/lib/communication-manifest.json +243 -0
  5. package/install/lib/communication-migration.cjs +91 -0
  6. package/install/lib/communication-previous.json +181 -0
  7. package/install/lib/gitignore.js +135 -0
  8. package/install/lib/install-engine.js +17 -1
  9. package/install/lib/ownership.js +24 -5
  10. package/install/package.json +1 -1
  11. package/install/templates/.claude/agents/bmad-byan.md +13 -26
  12. package/install/templates/.claude/agents/bmad-tao.md +47 -0
  13. package/install/templates/.claude/hooks/auto-dispatch-gate.js +81 -0
  14. package/install/templates/.claude/hooks/inject-tao.js +15 -71
  15. package/install/templates/.claude/hooks/inject-voice-anchor.js +21 -154
  16. package/install/templates/.claude/hooks/lib/dispatch-approval.cjs +135 -0
  17. package/install/templates/.claude/hooks/lib/dispatch-plan-format.js +293 -0
  18. package/install/templates/.claude/hooks/lib/plain-language.js +7 -14
  19. package/install/templates/.claude/hooks/lib/rtk-coverage.js +31 -0
  20. package/install/templates/.claude/hooks/lib/tool-log.js +143 -0
  21. package/install/templates/.claude/hooks/lib/voice-conformance.js +9 -32
  22. package/install/templates/.claude/hooks/lib/webfetch-output.js +37 -0
  23. package/install/templates/.claude/hooks/rtk-coverage.js +18 -0
  24. package/install/templates/.claude/hooks/tool-failure-guard.js +16 -9
  25. package/install/templates/.claude/hooks/webfetch-output.js +17 -0
  26. package/install/templates/.claude/rules/native-workflows.md +24 -5
  27. package/install/templates/.claude/rules/plain-language.md +7 -86
  28. package/install/templates/.claude/settings.json +56 -0
  29. package/install/templates/.claude/skills/byan-byan/SKILL.md +42 -83
  30. package/install/templates/.claude/skills/byan-hermes-dispatch/SKILL.md +22 -7
  31. package/install/templates/.claude/workflows/byan-auto-dispatch.js +86 -38
  32. package/install/templates/.codex/skills/byan/SKILL.md +7 -0
  33. package/install/templates/AGENTS.md +106 -0
  34. package/install/templates/_byan/_config/communication-policy.json +50 -0
  35. package/install/templates/_byan/_config/workflow-manifest.csv +2 -0
  36. package/install/templates/_byan/agent/byan/byan-soul.md +14 -2
  37. package/install/templates/_byan/agent/byan/byan-tao.md +35 -274
  38. package/install/templates/_byan/agent/byan/byan.md +6 -2
  39. package/install/templates/_byan/agent/byan/soul.md +419 -0
  40. package/install/templates/_byan/agent/byan/tao.md +60 -0
  41. package/install/templates/_byan/agent/tao/tao.md +26 -27
  42. package/install/templates/_byan/connaissance/mantras-sources.md +295 -0
  43. package/install/templates/_byan/core/activation/soul-activation.md +6 -5
  44. package/install/templates/_byan/core/communication.cjs +76 -0
  45. package/install/templates/_byan/mcp/byan-mcp-server/lib/agent-matcher.js +38 -1
  46. package/install/templates/_byan/mcp/byan-mcp-server/lib/communication.cjs +77 -0
  47. package/install/templates/_byan/mcp/byan-mcp-server/lib/dispatch-router.js +12 -3
  48. package/install/templates/_byan/mcp/byan-mcp-server/lib/dispatch.js +51 -20
  49. package/install/templates/_byan/mcp/byan-mcp-server/lib/fd-ack.js +75 -0
  50. package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-fd-core.js +12 -1
  51. package/install/templates/_byan/mcp/byan-mcp-server/lib/native-tiers.js +114 -2
  52. package/install/templates/_byan/mcp/byan-mcp-server/lib/routing-ledger.js +356 -0
  53. package/install/templates/_byan/mcp/byan-mcp-server/lib/soul.js +9 -0
  54. package/install/templates/_byan/mcp/byan-mcp-server/server.js +24 -6
  55. package/install/templates/_byan/mcp/byan-mcp-server/skill-bundles-manifest.json +2 -2
  56. package/install/templates/_byan/workflow/simple/byan/data/mantras.yaml +2 -5
  57. package/install/templates/_byan/workflow/simple/byan/templates/tao-template.md +56 -0
  58. package/install/templates/docs/auto-dispatch.md +76 -0
  59. package/install/templates/docs/communication.md +69 -0
  60. package/install/templates/docs/native-workflows-contract.md +33 -11
  61. package/install/templates/docs/tool-output-cost.md +88 -0
  62. package/install/templates/scripts/communication-eval.cjs +192 -0
  63. package/install/templates/scripts/rtk-coverage-report.js +30 -0
  64. package/install/templates/src/byan-v2/data/mantras.json +1058 -0
  65. package/install/templates/tests/communication/README.md +106 -0
  66. package/install/templates/tests/communication/incises.test.cjs +26 -0
  67. package/install/templates/tests/communication/scenarios.json +391 -0
  68. package/package.json +1 -1
  69. package/src/byan-v2/data/mantras.json +26 -6
@@ -0,0 +1,295 @@
1
+ # Mantras — Sources et Origines
2
+
3
+ **Version :** 2.0
4
+ **Derniere mise a jour :** 2026-02-19
5
+ **Usage :** Chaque mantra applique par BYAN a une origine sourcee.
6
+ Quand un mantra est invoque, BYAN peut pointer vers sa source originelle.
7
+
8
+ ---
9
+
10
+ ## Mantras de Conception (1-39)
11
+
12
+ ### Philosophie et Pensee
13
+
14
+ **Mantra #1 — Penser avant d'agir**
15
+ Origine : Rene Descartes, "Discours de la methode" (1637) — "je pense donc je suis"
16
+ Source : https://fr.wikisource.org/wiki/Discours_de_la_m%C3%A9thode
17
+
18
+ **Mantra #2 — Questionner les evidences**
19
+ Origine : Methode scientifique, Francis Bacon "Novum Organum" (1620)
20
+ Source : https://fr.wikipedia.org/wiki/Novum_Organum
21
+
22
+ **Mantra #3 — Connais ton domaine**
23
+ Origine : Domain-Driven Design, Eric Evans (2003)
24
+ Source : https://www.domainlanguage.com/ddd/
25
+
26
+ **Mantra #4 — Le contexte est roi**
27
+ Origine : Context-Driven Testing, James Bach & Cem Kaner (2001)
28
+ Source : https://context-driven-testing.com/
29
+
30
+ ### Collaboration
31
+
32
+ **Mantra #5 — Communiquer clairement**
33
+ Origine : Agile Manifesto, "Individuals and interactions over processes and tools" (2001)
34
+ Source : https://agilemanifesto.org/
35
+
36
+ **Mantra #6 — Partager la connaissance**
37
+ Origine : Collective Code Ownership, XP (Kent Beck, 1999)
38
+ Source : https://www.extremeprogramming.org/rules/collective.html
39
+
40
+ **Mantra #7 — Feedback rapide**
41
+ Origine : Extreme Programming, Kent Beck "XP Explained" (1999)
42
+ Source : https://www.oreilly.com/library/view/extreme-programming-explained/0201616416/
43
+
44
+ **Mantra #8 — Retrospective continue**
45
+ Origine : Scrum Guide, Ken Schwaber & Jeff Sutherland
46
+ Source : https://scrumguides.org/scrum-guide.html
47
+
48
+ ### Qualite
49
+
50
+ **Mantra #9 — Zero defaut**
51
+ Origine : Six Sigma, Motorola (1986) / Philip Crosby "Quality is Free" (1979)
52
+ Source : https://fr.wikipedia.org/wiki/Six_Sigma
53
+
54
+ **Mantra #10 — Tests d'abord**
55
+ Origine : Test-Driven Development, Kent Beck (2002)
56
+ Source : https://www.oreilly.com/library/view/test-driven-development/0321146530/
57
+
58
+ **Mantra #11 — Refactoring continu**
59
+ Origine : Martin Fowler "Refactoring" (1999)
60
+ Source : https://martinfowler.com/books/refactoring.html
61
+
62
+ **Mantra #12 — Code lisible**
63
+ Origine : Robert C. Martin "Clean Code" (2008)
64
+ Source : https://www.oreilly.com/library/view/clean-code-a/9780136083238/
65
+
66
+ ### Agilite
67
+
68
+ **Mantra #13 — Livrer souvent**
69
+ Origine : Continuous Delivery, Jez Humble & David Farley (2010)
70
+ Source : https://continuousdelivery.com/
71
+
72
+ **Mantra #14 — Adapter le plan**
73
+ Origine : Agile Manifesto, "Responding to change over following a plan" (2001)
74
+ Source : https://agilemanifesto.org/principles.html
75
+
76
+ **Mantra #15 — Equipe autonome**
77
+ Origine : Scrum, Ken Schwaber (1995)
78
+ Source : https://scrumguides.org/scrum-guide.html#scrum-team
79
+
80
+ **Mantra #16 — MVP d'abord**
81
+ Origine : Eric Ries "The Lean Startup" (2011)
82
+ Source : https://theleanstartup.com/principles
83
+
84
+ ### Technique
85
+
86
+ **Mantra #17 — Separation des preoccupations**
87
+ Origine : Edsger Dijkstra "On the role of scientific thought" (1974)
88
+ Source : https://www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html
89
+
90
+ **Mantra #18 — DRY (Don't Repeat Yourself)**
91
+ Origine : Andrew Hunt & David Thomas "The Pragmatic Programmer" (1999)
92
+ Source : https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/
93
+
94
+ **Mantra #19 — KISS (Keep It Simple, Stupid)**
95
+ Origine : Kelly Johnson, Lockheed Skunk Works (1960)
96
+ Source : https://fr.wikipedia.org/wiki/Principe_KISS
97
+
98
+ **Mantra #20 — SOLID**
99
+ Origine : Robert C. Martin, "Agile Software Development" (2002)
100
+ Source : https://web.archive.org/web/20150906155800/http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf
101
+
102
+ **Mantra #21 — Principe de moindre surprise**
103
+ Origine : Principe du moindre etonnement (PLS), Ken Arnold (Java design)
104
+ Source : https://en.wikipedia.org/wiki/Principle_of_least_astonishment
105
+
106
+ **Mantra #22 — Convention over Configuration**
107
+ Origine : Ruby on Rails, David Heinemeier Hansson (2004)
108
+ Source : https://rubyonrails.org/doctrine#convention-over-configuration
109
+
110
+ ### Tests
111
+
112
+ **Mantra #23 — Pyramide de tests**
113
+ Origine : Mike Cohn "Succeeding with Agile" (2009) + Martin Fowler blog
114
+ Source : https://martinfowler.com/articles/practical-test-pyramid.html
115
+
116
+ **Mantra #24 — Tests comme documentation**
117
+ Origine : BDD, Dan North "Introducing BDD" (2006)
118
+ Source : https://dannorth.net/introducing-bdd/
119
+
120
+ **Mantra #25 — Tester le comportement, pas l'implementation**
121
+ Origine : Behaviour-Driven Development, Dan North (2006)
122
+ Source : https://dannorth.net/introducing-bdd/
123
+
124
+ **Mantra #26 — Isolation des tests**
125
+ Origine : xUnit Patterns, Gerard Meszaros (2007)
126
+ Source : http://xunitpatterns.com/
127
+
128
+ **Mantra #27 — Tests rapides**
129
+ Origine : TDD, Kent Beck — "Run tests in under 10 minutes" (2002)
130
+ Source : https://www.oreilly.com/library/view/test-driven-development/0321146530/
131
+
132
+ ### Rigueur Merise
133
+
134
+ **Mantra #28 — Modeliser avant de coder**
135
+ Origine : Merise, Hubert Tardieu, Arnold Rochfeld, Rene Colletti (1978)
136
+ Source : https://fr.wikipedia.org/wiki/Merise_(informatique)
137
+
138
+ **Mantra #29 — MCD avant MLD**
139
+ Origine : Merise — Modele Conceptuel de Donnees → Modele Logique de Donnees
140
+ Source : https://fr.wikipedia.org/wiki/Merise_(informatique)#MCD
141
+
142
+ **Mantra #30 — MCT avant MOT**
143
+ Origine : Merise — Modele Conceptuel de Traitements → Modele Operationnel
144
+ Source : https://fr.wikipedia.org/wiki/Merise_(informatique)#MCT
145
+
146
+ **Mantra #31 — Normalisation des donnees**
147
+ Origine : Edgar F. Codd, "A Relational Model of Data" (1970)
148
+ Source : https://dl.acm.org/doi/10.1145/362384.362685
149
+
150
+ **Mantra #32 — Coherence donnees-traitements**
151
+ Origine : Merise, principe de coherence MCD ↔ MCT
152
+ Source : https://fr.wikipedia.org/wiki/Merise_(informatique)
153
+
154
+ **Mantra #33 — Data Dictionary First**
155
+ Origine : Merise + DDD (Eric Evans) — glossaire avant modelisation
156
+ Source : https://www.domainlanguage.com/ddd/reference/
157
+
158
+ **Mantra #34 — MCD ↔ MCT Cross-validation**
159
+ Origine : Merise, validation croisee conceptuelle
160
+ Source : https://fr.wikipedia.org/wiki/Merise_(informatique)
161
+
162
+ ### Resolution de Problemes
163
+
164
+ **Mantra #35 — Comprendre avant de resoudre**
165
+ Origine : G. Polya "How to Solve It" (1945)
166
+ Source : https://press.princeton.edu/books/paperback/9780691164076/how-to-solve-it
167
+
168
+ **Mantra #36 — Decomposer le probleme**
169
+ Origine : Divide and conquer, John von Neumann / informatique theorique classique
170
+ Source : https://en.wikipedia.org/wiki/Divide-and-conquer_algorithm
171
+
172
+ **Mantra #37 — Rasoir d'Ockham**
173
+ Origine : Guillaume d'Occam, philosophe (XIVe siecle) — "Entia non sunt multiplicanda praeter necessitatem"
174
+ Source : https://fr.wikipedia.org/wiki/Rasoir_d%27Ockham
175
+
176
+ **Mantra #38 — Inversion**
177
+ Origine : Carl Jacobi, mathematicien (XIXe) — "Invert, always invert" (cite par Charlie Munger)
178
+ Source : https://en.wikipedia.org/wiki/Inversion_(thinking)
179
+
180
+ **Mantra #39 — Chaque action a des consequences**
181
+ Origine : Newton, 3e loi (principe d'action-reaction) appliquee a la conception
182
+ Source : https://fr.wikipedia.org/wiki/Lois_de_Newton#Troisi%C3%A8me_loi_de_Newton
183
+
184
+ ---
185
+
186
+ ## Mantras IA (IA-1 a IA-25)
187
+
188
+ **Mantra IA-1 — Trust But Verify**
189
+ Origine : Proverbe russe "Doveryai, no proveryai", popularise par Ronald Reagan (1986)
190
+ Source : https://en.wikipedia.org/wiki/Trust,_but_verify
191
+ Application Fact-Check : Toute assertion recue est traitee comme non-verifiee jusqu'a preuve du contraire. Niveau de preuve requis avant d'accepter un claim : L1 (spec) a L3 (peer-reviewed) minimum. Sans source = [HYPOTHESIS] ou [REASONING], jamais [CLAIM]. Commande : [FC].
192
+
193
+ **Mantra IA-2 — Fail Fast**
194
+ Origine : Jim Shore "Fail Fast" IEEE Software (2004)
195
+ Source : https://www.martinfowler.com/ieeeSoftware/failFast.pdf
196
+
197
+ **Mantra IA-3 — Minimal Footprint**
198
+ Origine : Principe du moindre privilege, Jerome Saltzer & Michael Schroeder (1975)
199
+ Source : https://dl.acm.org/doi/10.1145/361011.361067
200
+
201
+ **Mantra IA-4 — Explainability**
202
+ Origine : GDPR Art. 22 "Right to explanation" (2016) + XAI research
203
+ Source : https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32016R0679
204
+
205
+ **Mantra IA-5 — Graceful Degradation**
206
+ Origine : Fault-tolerant computing, Algirdas Avizienis (1967)
207
+ Source : https://en.wikipedia.org/wiki/Graceful_degradation
208
+
209
+ **Mantra IA-6 — Context Awareness**
210
+ Origine : Context-aware computing, Mark Weiser "The Computer for the 21st Century" (1991)
211
+ Source : https://dl.acm.org/doi/10.1145/329124.329126
212
+
213
+ **Mantra IA-7 — Stateless by Default**
214
+ Origine : REST, Roy Fielding dissertation (2000)
215
+ Source : https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
216
+
217
+ **Mantra IA-8 — Human in the Loop**
218
+ Origine : HITL AI, Kamar et al., Microsoft Research (2012)
219
+ Source : https://en.wikipedia.org/wiki/Human-in-the-loop
220
+
221
+ **Mantra IA-9 — Auditability**
222
+ Origine : SOX Compliance (2002) + NIST SP 800-92 Log Management
223
+ Source : https://csrc.nist.gov/publications/detail/sp/800-92/final
224
+
225
+ **Mantra IA-10 — Separation of Concerns for AI**
226
+ Origine : Dijkstra (1974) applique aux systemes IA
227
+ Source : https://www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html
228
+
229
+ **Mantra IA-11 — No Surprise Outputs**
230
+ Origine : Principe du moindre etonnement (PLS) applique aux LLMs
231
+ Source : https://en.wikipedia.org/wiki/Principle_of_least_astonishment
232
+
233
+ **Mantra IA-12 — Reproducibility**
234
+ Origine : Methode scientifique — critere de reproductibilite de Popper (1934)
235
+ Source : https://fr.wikipedia.org/wiki/R%C3%A9futabilit%C3%A9
236
+ Application Fact-Check : Fondement du moteur de fact-check BYAN. Les 3 criteres obligatoires pour qu'une assertion soit CLAIM (et non HYPOTHESIS) : demonstrable (on peut le montrer), quantifiable (on peut le mesurer), reproductible (un tiers peut le verifier independamment). Si un seul critere manque : verdict HYPOTHESIS maximum.
237
+
238
+ **Mantra IA-13 — Versioning Everything**
239
+ Origine : Semantic Versioning, Tom Preston-Werner (2010)
240
+ Source : https://semver.org/
241
+
242
+ **Mantra IA-14 — Documentation as Code**
243
+ Origine : Docs-as-code movement, Anne Gentle "Docs Like Code" (2017)
244
+ Source : https://www.docslikecode.com/
245
+
246
+ **Mantra IA-15 — Least Privilege**
247
+ Origine : Saltzer & Schroeder "Protection of Information in Computer Systems" (1975)
248
+ Source : https://dl.acm.org/doi/10.1145/361011.361067
249
+
250
+ **Mantra IA-16 — Challenge Before Confirm**
251
+ Origine : Socratic method, Platon (Ve siecle av. J.-C.) appliquee a l'IA
252
+ Source : https://fr.wikipedia.org/wiki/Methode_soc ratique
253
+ Application Fact-Check : Le challenge inclut systematiquement la verification epistemique. Avant de confirmer une assertion : (1) identifier le domaine, (2) exiger source L2+ pour security/performance/compliance, (3) calculer la confiance de la chaine de raisonnement. Tout claim sans source = [UNVERIFIED] avec chemin de verification propose. Commande : [FC] mode 1.
254
+
255
+ **Mantra IA-17 — Progressive Disclosure**
256
+ Origine : UX design, Jakob Nielsen "Designing Web Usability" (1999)
257
+ Source : https://www.nngroup.com/articles/progressive-disclosure/
258
+
259
+ **Mantra IA-18 — Idempotency**
260
+ Origine : REST / HTTP, Roy Fielding (2000) + RFC 9110 Section 9.2.2
261
+ Source : https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2
262
+
263
+ **Mantra IA-19 — Observability First**
264
+ Origine : Charity Majors, Liz Fong-Jones "Observability Engineering" (2022)
265
+ Source : https://www.oreilly.com/library/view/observability-engineering/9781492076438/
266
+
267
+ **Mantra IA-20 — Bounded Context**
268
+ Origine : Domain-Driven Design, Eric Evans (2003)
269
+ Source : https://martinfowler.com/bliki/BoundedContext.html
270
+
271
+ **Mantra IA-21 — Self-Aware Agent**
272
+ Origine : Metacognition AI, Flavell (1979) applique aux LLMs
273
+ Source : https://en.wikipedia.org/wiki/Metacognition
274
+
275
+ **Mantra IA-22 — Incremental Learning**
276
+ Origine : Online learning / continual learning, Thrun & Mitchell (1995)
277
+ Source : https://en.wikipedia.org/wiki/Incremental_learning
278
+
279
+ **Mantra IA-23 — No Emoji Pollution**
280
+ Origine : BYAN Core Team — signal/bruit dans les outputs techniques (2024)
281
+ Source : `_byan/connaissance/axioms.md` (axiome interne BYAN)
282
+
283
+ **Mantra IA-24 — Clean Code = No Useless Comments**
284
+ Origine : Robert C. Martin "Clean Code" Ch. 4 (2008)
285
+ Source : https://www.oreilly.com/library/view/clean-code-a/9780136083238/
286
+
287
+ **Mantra IA-25 — Zero Trust Architecture**
288
+ Origine : John Kindervag, Forrester Research (2010) — "Never trust, always verify"
289
+ Source : https://en.wikipedia.org/wiki/Zero_trust_security_model
290
+ Application Fact-Check : Etendu aux assertions, pas seulement aux acces reseau. Aucune affirmation n'est vraie par defaut — meme si elle vient d'un expert, d'une doc, ou d'un LLM. Verification obligatoire : source, niveau de preuve, date d'expiration (security=180j, perf=365j). Une assertion expiree redevient HYPOTHESIS. Domains stricts (security/compliance/performance) : zero confiance sans L2. Commande : [FC].
291
+
292
+ **Mantra IA-26 : Parler Réel**
293
+ Origine : BYAN Core Team, clarté de communication (2026), précisée par la demande de Yan du 13 septembre 2026.
294
+ Source : `_byan/_config/communication-policy.json`, règle `.claude/rules/plain-language.md`.
295
+ Application : précision constante et registre adapté au destinataire de chaque livrable ; conservation des faits, conditions, réserves, incertitudes et éléments exacts. Les tirets de ponctuation sont exclus de la prose hors marqueurs initiaux de listes, avec préservation des traits d’union orthographiques, commandes, code, identifiants et citations. Aucun remplacement lexical automatique. Les incises utilisent des virgules ou des parenthèses, y compris dans les listes ; seuls leurs tirets de ponctuation sont interdits. Les titres nomment précisément le sujet ou le mécanisme, sans dramatisation ni généralisation non étayée. Ne pas inventer les événements détectés par le système. Les contrôles formels ne prouvent pas la qualité sémantique du français. La règle est une décision de conception approuvée, pas une conclusion scientifique sur l’origine des habitudes lexicales.
@@ -65,10 +65,11 @@ Exception : si l'agent declare `soul-required: true` dans son activation, STOP e
65
65
  **SI Agent autonome :**
66
66
  - Lire `{project-root}/_byan/agents/{agent_name}-tao.md` si il existe → stocker comme `{tao}`
67
67
 
68
- **Application** : Si tao charge, appliquer les directives vocales a TOUS les outputs :
69
- - Registre et signatures verbales
70
- - Vocabulaire interdit
71
- - Temperature emotionnelle
68
+ **Application** : Si le Tao est chargé, appliquer les règles au livrable et à son destinataire réel :
69
+ - Pour BYAN principal, charger la politique référencée par le Tao et résoudre chaque profil selon la demande autorisée.
70
+ - Les signatures, préférences de conversation et températures ne constituent pas des obligations pour les documents destinés à des tiers.
71
+ - Les spécialistes conservent leur identité ; lorsqu’ils contribuent à un livrable BYAN, recevoir et appliquer ses contraintes compactes de précision et de rédaction.
72
+ - La mémoire reste une source historique, sans priorité sur les consignes approuvées de la tâche.
72
73
  - Si tao absent : continuer sans directives vocales (non-bloquant)
73
74
 
74
75
  ### Etape 5 — Charger le profil ELO (confiance calibree)
@@ -94,7 +95,7 @@ Exception : si l'agent declare `soul-required: true` dans son activation, STOP e
94
95
  1. **Silence total** — Aucun output pendant le chargement
95
96
  2. **Non-bloquant par defaut** — Un fichier manquant ne bloque pas l'activation
96
97
  3. **Soul avant Tao** — Toujours charger le soul avant le tao (le tao derive du soul)
97
- 4. **Tao applique partout** Si charge, les directives vocales s'appliquent a CHAQUE output
98
+ 4. **Registre par livrable** : le Tao guide la rédaction selon le destinataire ; le registre conversationnel ne s’impose pas aux documents.
98
99
  5. **ELO partage** — Le profil ELO est global, pas par agent
99
100
  6. **Pas de pre-chargement** — Charger au moment de l'activation uniquement
100
101
 
@@ -0,0 +1,76 @@
1
+ 'use strict';
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const crypto = require('crypto');
5
+ const SOURCE = '_byan/_config/communication-policy.json';
6
+ const FALLBACK = Object.freeze({ version: 'minimal-1', default_profile: 'fr-technique', common: ['Français technique précis, naturel et respectueux. Adapter chaque livrable à son destinataire. Préserver faits, incertitudes, commandes, identifiants et citations exactes. Aucun emoji ni tiret de ponctuation hors marqueurs de listes. Encadrer les incises par des virgules ou des parenthèses, y compris dans une liste. Les titres nomment leur sujet sans dramatisation ni généralisation non étayée.'], profiles: { 'fr-technique': { rules: ['Nommer les objets, opérations, conditions et conséquences.'], address_mode: 'context' } } });
7
+ const validLines = x => Array.isArray(x) && x.length > 0 && x.every(s => typeof s === 'string' && s.trim() && s.length <= 4000);
8
+ function validatePolicy(p) {
9
+ if (!p || p.version !== 'fr-1' || p.default_profile !== 'fr-technique' || !validLines(p.common) || !p.profiles || !Object.prototype.hasOwnProperty.call(p.profiles, p.default_profile)) throw Error('policy-invalid');
10
+ for (const [id, profile] of Object.entries(p.profiles)) {
11
+ if (!/^fr-(technique|pedagogique|client|procedure|analyse)$/.test(id) || !validLines(profile.rules) || !['context', 'tu', 'vous'].includes(profile.address_mode)) throw Error('policy-invalid');
12
+ }
13
+ return p;
14
+ }
15
+ function loadPolicy(root) {
16
+ try {
17
+ const raw = fs.readFileSync(path.join(root, SOURCE), 'utf8');
18
+ if (Buffer.byteLength(raw) > 65536) throw Error('policy-invalid');
19
+ return { policy: validatePolicy(JSON.parse(raw)), diagnostic: { status: 'active', source: SOURCE, revision: crypto.createHash('sha256').update(raw).digest('hex').slice(0, 16) } };
20
+ } catch (e) {
21
+ return { policy: FALLBACK, diagnostic: { status: 'degraded', source: 'builtin', reason: e.code === 'ENOENT' ? 'policy-missing' : 'policy-invalid' } };
22
+ }
23
+ }
24
+ // Callers supply only task/configuration metadata from authorized channels here.
25
+ // Free text and recovered context are intentionally not inspected or persisted.
26
+ function resolveContract(loaded, metadata = {}, channel = 'deliverable') {
27
+ const p = loaded.policy;
28
+ const fields = {};
29
+ for (const level of [metadata.identified, metadata.project, metadata.explicit]) {
30
+ if (!level || typeof level !== 'object') continue;
31
+ for (const key of ['profile', 'audience', 'deliverable_id', 'language', 'address_mode', 'explanation_level']) {
32
+ if (typeof level[key] === 'string' && level[key].trim() && level[key].length <= 500) fields[key] = level[key];
33
+ }
34
+ }
35
+ const requested = fields.profile || p.default_profile;
36
+ const found = Object.prototype.hasOwnProperty.call(p.profiles, requested);
37
+ const profile = found ? requested : p.default_profile;
38
+ const selected = p.profiles[profile];
39
+ const diagnostic = { ...loaded.diagnostic, version: p.version, profile, channel };
40
+ if (!found) Object.assign(diagnostic, { status: 'degraded', reason: 'profile-missing' });
41
+ return { ...fields, policy_version: p.version, language: fields.language || 'fr', profile,
42
+ address_mode: ['tu', 'vous', 'context'].includes(fields.address_mode) ? fields.address_mode : selected.address_mode,
43
+ rules: [...p.common, ...selected.rules], diagnostic };
44
+ }
45
+ function renderContract(c) {
46
+ const { diagnostic, rules, ...metadata } = c;
47
+ return `BYAN communication ${JSON.stringify(diagnostic)}\nMétadonnées du livrable : ${JSON.stringify(metadata)}\n${rules.map(s => '- ' + s).join('\n')}`;
48
+ }
49
+ function protectedProse(text) {
50
+ if (typeof text !== 'string') return '';
51
+ const blank = value => value.replace(/[^\n]/g, ' ');
52
+ let fence = null;
53
+ const withoutCode = text.split('\n').map(line => {
54
+ const marker = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
55
+ if (fence) {
56
+ if (marker && marker[1][0] === fence[0] && marker[1].length >= fence.length && !marker[2].trim()) fence = null;
57
+ return blank(line);
58
+ }
59
+ if (marker) { fence = marker[1]; return blank(line); }
60
+ if (/^\s*>/.test(line) || /^\s*\|?\s*:?-{3,}\s*\|/.test(line) || /^\s*(?:-{3,}|\*{3,}|_{3,})\s*$/.test(line)) return blank(line);
61
+ return line.replace(/(`+)[\s\S]*?\1/g, blank).replace(/https?:\/\/\S+/g, blank).replace(/^\s*[-\u2013\u2014*+]\s+/, blank);
62
+ }).join('\n');
63
+ return withoutCode.replace(/«[^»]*»|“[^”]*”|"[^"\n]*"/g, blank);
64
+ }
65
+ function scanPunctuation(text) {
66
+ const hits = [];
67
+ protectedProse(text).split('\n').forEach((line, i) => {
68
+ for (const match of line.matchAll(/[\u2013\u2014]|(?<=\s)-(?=\s)/g)) {
69
+ const j = match.index;
70
+ if (match[0] === '\u2013' && /\d/.test(line[j - 1] || '') && /\d/.test(line[j + 1] || '')) continue;
71
+ hits.push({ kind: 'punctuation', line: i + 1, column: j + 1, good: 'Employer une virgule, un point, deux-points ou des parenthèses. Préserver les éléments exacts.' });
72
+ }
73
+ });
74
+ return hits;
75
+ }
76
+ module.exports = { SOURCE, FALLBACK, validatePolicy, loadPolicy, resolveContract, renderContract, protectedProse, scanPunctuation };
@@ -59,6 +59,43 @@ function tokenize(text) {
59
59
  .filter((w) => w.length >= 3 && !STOPWORDS.has(w));
60
60
  }
61
61
 
62
+ // matchesKeyword — does a keyword really occur in the text?
63
+ //
64
+ // LEFT word boundary only: the keyword must START a word, but may continue.
65
+ //
66
+ // WHY. Measured 2026-08-07 on real chat sentences, plain `includes` scored a
67
+ // specialist that had nothing to do with the request:
68
+ // "tu peux me lister le dossier src" -> "peux" contains "ux" -> ux-designer
69
+ // "deploie la version en production" -> "production" has "product" -> pm
70
+ // Short keywords (ux, ui, ci, cd) sit inside common French words. A wrong agent
71
+ // proposed is worse than none: it looks like understanding while being wrong.
72
+ //
73
+ // Why not a boundary on BOTH sides: these are STEMS, not whole words.
74
+ // "documente" must catch "documenter" and "documentation" — that is what makes
75
+ // the French list work at all. With a right-hand boundary, "il faut documenter
76
+ // l'API" stopped routing to the technical writer.
77
+ //
78
+ // What this does NOT fix, and it should be said: "production" does start with
79
+ // "product". That is a VOCABULARY problem (the stem is too short for its
80
+ // meaning), not a mechanism one, and it belongs in DOMAIN_KEYWORDS.
81
+ const WORD_CHAR = /[a-z0-9]/;
82
+
83
+ export function matchesKeyword(text, keyword) {
84
+ if (!keyword) return false;
85
+ // Multi-word keywords keep substring matching: their length already protects
86
+ // them, and requiring a boundary would break spacing variants.
87
+ if (/\s/.test(keyword)) return text.includes(keyword);
88
+
89
+ let from = 0;
90
+ for (;;) {
91
+ const i = text.indexOf(keyword, from);
92
+ if (i === -1) return false;
93
+ const before = i === 0 ? '' : text[i - 1];
94
+ if (!WORD_CHAR.test(before)) return true;
95
+ from = i + 1;
96
+ }
97
+ }
98
+
62
99
  // scoreAgent — pure per-agent score. keyword hits (x3) + title/role text overlap.
63
100
  export function scoreAgent(taskText, agent) {
64
101
  const task = deburr(taskText);
@@ -67,7 +104,7 @@ export function scoreAgent(taskText, agent) {
67
104
  const hits = [];
68
105
  const kws = DOMAIN_KEYWORDS[agent.name] || [];
69
106
  for (const kw of kws) {
70
- if (task.includes(deburr(kw))) { keywordScore += 1; hits.push(kw); }
107
+ if (matchesKeyword(task, deburr(kw))) { keywordScore += 1; hits.push(kw); }
71
108
  }
72
109
  const agentTokens = tokenize(`${agent.title || ''} ${agent.role || ''}`);
73
110
  let textScore = 0;
@@ -0,0 +1,77 @@
1
+ // Generated from _byan/core/communication.cjs. Do not edit.
2
+ 'use strict';
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const crypto = require('crypto');
6
+ const SOURCE = '_byan/_config/communication-policy.json';
7
+ const FALLBACK = Object.freeze({ version: 'minimal-1', default_profile: 'fr-technique', common: ['Français technique précis, naturel et respectueux. Adapter chaque livrable à son destinataire. Préserver faits, incertitudes, commandes, identifiants et citations exactes. Aucun emoji ni tiret de ponctuation hors marqueurs de listes. Encadrer les incises par des virgules ou des parenthèses, y compris dans une liste. Les titres nomment leur sujet sans dramatisation ni généralisation non étayée.'], profiles: { 'fr-technique': { rules: ['Nommer les objets, opérations, conditions et conséquences.'], address_mode: 'context' } } });
8
+ const validLines = x => Array.isArray(x) && x.length > 0 && x.every(s => typeof s === 'string' && s.trim() && s.length <= 4000);
9
+ function validatePolicy(p) {
10
+ if (!p || p.version !== 'fr-1' || p.default_profile !== 'fr-technique' || !validLines(p.common) || !p.profiles || !Object.prototype.hasOwnProperty.call(p.profiles, p.default_profile)) throw Error('policy-invalid');
11
+ for (const [id, profile] of Object.entries(p.profiles)) {
12
+ if (!/^fr-(technique|pedagogique|client|procedure|analyse)$/.test(id) || !validLines(profile.rules) || !['context', 'tu', 'vous'].includes(profile.address_mode)) throw Error('policy-invalid');
13
+ }
14
+ return p;
15
+ }
16
+ function loadPolicy(root) {
17
+ try {
18
+ const raw = fs.readFileSync(path.join(root, SOURCE), 'utf8');
19
+ if (Buffer.byteLength(raw) > 65536) throw Error('policy-invalid');
20
+ return { policy: validatePolicy(JSON.parse(raw)), diagnostic: { status: 'active', source: SOURCE, revision: crypto.createHash('sha256').update(raw).digest('hex').slice(0, 16) } };
21
+ } catch (e) {
22
+ return { policy: FALLBACK, diagnostic: { status: 'degraded', source: 'builtin', reason: e.code === 'ENOENT' ? 'policy-missing' : 'policy-invalid' } };
23
+ }
24
+ }
25
+ // Callers supply only task/configuration metadata from authorized channels here.
26
+ // Free text and recovered context are intentionally not inspected or persisted.
27
+ function resolveContract(loaded, metadata = {}, channel = 'deliverable') {
28
+ const p = loaded.policy;
29
+ const fields = {};
30
+ for (const level of [metadata.identified, metadata.project, metadata.explicit]) {
31
+ if (!level || typeof level !== 'object') continue;
32
+ for (const key of ['profile', 'audience', 'deliverable_id', 'language', 'address_mode', 'explanation_level']) {
33
+ if (typeof level[key] === 'string' && level[key].trim() && level[key].length <= 500) fields[key] = level[key];
34
+ }
35
+ }
36
+ const requested = fields.profile || p.default_profile;
37
+ const found = Object.prototype.hasOwnProperty.call(p.profiles, requested);
38
+ const profile = found ? requested : p.default_profile;
39
+ const selected = p.profiles[profile];
40
+ const diagnostic = { ...loaded.diagnostic, version: p.version, profile, channel };
41
+ if (!found) Object.assign(diagnostic, { status: 'degraded', reason: 'profile-missing' });
42
+ return { ...fields, policy_version: p.version, language: fields.language || 'fr', profile,
43
+ address_mode: ['tu', 'vous', 'context'].includes(fields.address_mode) ? fields.address_mode : selected.address_mode,
44
+ rules: [...p.common, ...selected.rules], diagnostic };
45
+ }
46
+ function renderContract(c) {
47
+ const { diagnostic, rules, ...metadata } = c;
48
+ return `BYAN communication ${JSON.stringify(diagnostic)}\nMétadonnées du livrable : ${JSON.stringify(metadata)}\n${rules.map(s => '- ' + s).join('\n')}`;
49
+ }
50
+ function protectedProse(text) {
51
+ if (typeof text !== 'string') return '';
52
+ const blank = value => value.replace(/[^\n]/g, ' ');
53
+ let fence = null;
54
+ const withoutCode = text.split('\n').map(line => {
55
+ const marker = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
56
+ if (fence) {
57
+ if (marker && marker[1][0] === fence[0] && marker[1].length >= fence.length && !marker[2].trim()) fence = null;
58
+ return blank(line);
59
+ }
60
+ if (marker) { fence = marker[1]; return blank(line); }
61
+ if (/^\s*>/.test(line) || /^\s*\|?\s*:?-{3,}\s*\|/.test(line) || /^\s*(?:-{3,}|\*{3,}|_{3,})\s*$/.test(line)) return blank(line);
62
+ return line.replace(/(`+)[\s\S]*?\1/g, blank).replace(/https?:\/\/\S+/g, blank).replace(/^\s*[-\u2013\u2014*+]\s+/, blank);
63
+ }).join('\n');
64
+ return withoutCode.replace(/«[^»]*»|“[^”]*”|"[^"\n]*"/g, blank);
65
+ }
66
+ function scanPunctuation(text) {
67
+ const hits = [];
68
+ protectedProse(text).split('\n').forEach((line, i) => {
69
+ for (const match of line.matchAll(/[\u2013\u2014]|(?<=\s)-(?=\s)/g)) {
70
+ const j = match.index;
71
+ if (match[0] === '\u2013' && /\d/.test(line[j - 1] || '') && /\d/.test(line[j + 1] || '')) continue;
72
+ hits.push({ kind: 'punctuation', line: i + 1, column: j + 1, good: 'Employer une virgule, un point, deux-points ou des parenthèses. Préserver les éléments exacts.' });
73
+ }
74
+ });
75
+ return hits;
76
+ }
77
+ module.exports = { SOURCE, FALLBACK, validatePolicy, loadPolicy, resolveContract, renderContract, protectedProse, scanPunctuation };
@@ -139,11 +139,18 @@ export function claudeModelForComplexity(complexity) {
139
139
  return 'sonnet'; // unknown -> a safe middle
140
140
  }
141
141
 
142
+ // Claude Workflow leaves expose effort independently of the model. Agent-tool
143
+ // callers may keep effort null; native workflows consume this mapping explicitly.
144
+ export function claudeEffortForModel(model) {
145
+ return ({ haiku: 'low', sonnet: 'medium', opus: 'high', fable: 'max' })[model] ?? null;
146
+ }
147
+
142
148
  // dispatch({ nature, complexity }) -> the full routing decision:
143
149
  // { runtime, model, effort, reasoning }
144
150
  // - Codex: model = CODEX_MODEL, effort = complexity bucket (the real knob).
145
151
  // - Claude: model = haiku/sonnet/opus/fable on the complexity ladder, effort =
146
- // null (Claude has no effort knob its "effort" IS the model tier).
152
+ // null for the direct Claude Agent transport; Workflow effort is exposed
153
+ // separately by claudeEffortForModel / native-tiers.effortForTask.
147
154
  // The red lines are enforced here regardless of caller input: Codex keeps its
148
155
  // no-Fable guard ; verification stays on Claude.
149
156
  export function dispatch({ nature, complexity } = {}) {
@@ -158,8 +165,10 @@ export function dispatch({ nature, complexity } = {}) {
158
165
  }
159
166
  return {
160
167
  runtime,
161
- model: claudeModelForComplexity(complexity), // haiku/sonnet/opus/fable by complexity
162
- effort: null, // Claude effort = model tier, no separate knob
168
+ model: isVerification(nature) || complexity == null ||
169
+ (typeof complexity === 'number' && !Number.isFinite(complexity))
170
+ ? null : claudeModelForComplexity(complexity),
171
+ effort: null, // direct Agent transport; native Workflow callers use effortForTask
163
172
  reasoning: isVerification(nature)
164
173
  ? 'verification stays on Claude (red line: a runtime never grades its own work)'
165
174
  : `nature "${normalize(nature)}" stays on Claude (default-safe) ; model scaled to complexity`,