Skip to content

chore: release v0.36.7#156

Merged
Destynova2 merged 1 commit intodevelopfrom
release-plz-2026-04-11T18-11-45Z
Apr 11, 2026
Merged

chore: release v0.36.7#156
Destynova2 merged 1 commit intodevelopfrom
release-plz-2026-04-11T18-11-45Z

Conversation

@Destynova2
Copy link
Copy Markdown
Contributor

🤖 New release

  • grob: 0.36.6 -> 0.36.7
Changelog

0.36.7 - 2026-04-11

Added

  • (router) ajouter le scoring heuristique de complexite

Fixed

  • (ci) ajouter RUSTSEC-2026-0097 a audit.toml (#153)

Other

  • (ci) documenter la dépendance ruleset → Required checks (#154)


This PR was generated with release-plz.

@Destynova2 Destynova2 enabled auto-merge (squash) April 11, 2026 18:11
@Destynova2 Destynova2 merged commit 4b16e9c into develop Apr 11, 2026
42 checks passed
@Destynova2 Destynova2 deleted the release-plz-2026-04-11T18-11-45Z branch April 11, 2026 18:18
Destynova2 added a commit that referenced this pull request Apr 12, 2026
* fix(security): résoudre 6 alertes CodeQL/Semgrep cleartext logging

Supprime le logging en cleartext de valeurs canary PII dans les assertions
de test (pii.rs), annote le faux positif HTTPS dans credential_check.rs,
et ajoute nosemgrep sur le token de test assemblé dynamiquement (tests.rs).

Résout: 4 alertes HIGH CodeQL (pii.rs L689/L1151/L1172/L1183),
1 alerte HIGH CodeQL (credential_check.rs L70),
1 faux positif Semgrep (tests.rs L58).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(exec): vérifier la santé avant spawn pour éviter le faux-démarrage

Re-vérifie is_instance_running avant spawn_background_service pour éviter
le faux-démarrage quand le flow credentials interactif prend du temps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): ajouter le tool grob_hint + header X-Grob-Hint

Ajoute ComplexityHint (trivial/medium/complex), le tool MCP grob_hint
(one-shot slot), la résolution multi-source dans dispatch (header →
metadata → MCP slot), et l'injection dans tools/list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.4 (#141)

* fix(mcp): gater grob_hint derrière cfg(feature = "mcp")

Les types ComplexityHint et le champ grob_hint dans AppState référencent
le module MCP qui n'existe pas quand le feature est désactivé. Ajoute les
guards #[cfg(feature = "mcp")] manquants dans dispatch/mod.rs et
server/mod.rs pour corriger les builds feature powerset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.5 (#143)

* test(dlp,router): ajouter proptests pour robustesse DLP et router

Add 13 proptest properties for DLP and router parsers:

DLP (7):
- sanitize idempotence (sanitize(sanitize(x)) == sanitize(x))
- output length bounded (len <= input + 200)
- known secrets never leak through sanitize
- DFA scanner never panics on arbitrary UTF-8
- Luhn-valid credit cards detected by PII scanner
- Mod97-valid IBANs detected by PII scanner
- sanitize preserves valid UTF-8

Router (6):
- extract_trailing_literal_byte never panics on arbitrary input
- deterministic (same input = same output)
- result always lowercase ASCII alphabetic
- alternation patterns always return None
- classify never panics on arbitrary model names
- route never panics on arbitrary user text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): add RUSTSEC-2026-0097 exception and fix gitleaks force-push

- deny.toml: ignore RUSTSEC-2026-0097 (rand unsound with custom logger
  calling rand::rng()). No impact: grob does not define a custom logger
  accessing ThreadRng.

- ci.yml: for PRs, scan gitleaks against origin/<base-ref> instead of
  github.event.before. Force-pushes invalidate the "before" SHA, causing
  gitleaks to fail on a broken commit range. Using the base branch ref
  always resolves to a valid range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(setup): ajouter support custom endpoint OpenAI/Anthropic-compatible

Ajoute deux nouvelles options dans le wizard setup pour configurer des
endpoints LLM custom compatibles OpenAI ou Anthropic. Le wizard demande
la base_url, valide la connexion via un appel GET /models, et écrit
le provider_type + base_url dans le TOML config.

Modifications :
- src/providers/registry.rs : nouveaux types "openai_compatible" et
  "anthropic_compatible" dans create_provider
- src/commands/credential_check.rs : validate_custom_endpoint() pour
  valider les clés API contre des endpoints custom
- src/commands/setup.rs : screen_custom_endpoints(), CustomEndpoint
  struct, intégration dans le wizard flow + 9 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cache): ajouter cache sémantique SimHash avec distance de Hamming

Adds an in-memory SimHash-based semantic cache layer that detects
near-duplicate prompts via 64-bit fingerprints and Hamming distance
(default threshold ≤ 3 bits). The fuzzy layer is consulted before the
exact SHA-256 cache to improve hit rates for rephrased requests.

- src/cache/simhash.rs: normalize, compute, hamming_distance, SimHashCache
- Integrated into ResponseCache via get_with_simhash / put_with_simhash
- 16 new unit tests covering normalization, hashing, distance, and cache ops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cache): corriger normalisation SimHash et utiliser moka pour eviction

- Supprimer le tri lexicographique des tokens qui detruisait le sens
  semantique (ex: "translate English to French" = "translate French to
  English"). L'ordre est desormais preserve.
- Hasher chaque token avec sa position (hash_token_at) pour rendre le
  SimHash sensible a l'ordre des mots.
- Remplacer RwLock<HashMap> par moka::sync::Cache avec max_capacity et
  TTL built-in, alignant le cycle de vie sur le cache exact.
- Adapter response_cache.rs pour passer capacity/TTL au constructeur.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tracing): ajouter rotation par taille et compression zstd des traces

Ajoute la rotation automatique des fichiers trace JSONL quand ils
dépassent la taille configurée (max_size_mb, défaut 50 MB). Les fichiers
rotatifs sont nommés trace.N.jsonl et limités à max_files (défaut 3).
L'option compress active la compression zstd des fichiers rotatifs.

Nouveaux champs TracingConfig : max_size_mb, max_files, compress.
6 tests unitaires couvrent la rotation, le shift, la suppression des
plus anciens, la compression zstd, et le déclenchement via write_trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tracing): utiliser streaming zstd pour compression rotation

Remplace `zstd::encode_all` (charge tout en mémoire) par un
`zstd::Encoder` en streaming avec `BufReader` + `io::copy`.
Élimine le pic mémoire lors de la compression de gros fichiers trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.6 (#150)

* fix(ci): ajouter RUSTSEC-2026-0097 a audit.toml (#153)

cargo-audit echoue sur develop depuis le merge #148 car
RUSTSEC-2026-0097 (rand unsound avec custom logger) n'etait
ignore que dans deny.toml, pas dans .cargo/audit.toml.

Pas d'impact : grob ne definit pas de custom logger utilisant
ThreadRng.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(ci): documenter la dépendance ruleset → Required checks (#154)

Le ruleset "Protect develop" ne doit référencer que le job
"Required checks" (et "cla-check"), jamais les jobs individuels
(Clippy, Rustfmt, etc.) car le path pruning les skip sur les
changements non-Rust, causant un pending éternel.

Voir PR #153 pour le contexte.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(router): ajouter le scoring heuristique de complexite

Classifie chaque requete en trivial/medium/complex via une somme
ponderee de signaux observables (max_tokens, presence d'outils,
taille du contexte, mots-cles, longueur du system prompt).

Le tier est attache a RouteDecision.complexity_tier pour usage
par le futur systeme de tiers declaratif (T-P3).

17 tests unitaires couvrent les combinaisons de signaux, les
cas limites et la configuration des poids.

* chore: release v0.36.7 (#156)

* feat(wizard): polir le wizard setup pour atteindre le score audit 85+

Implémente les 10 recommandations de l'audit cli-wizard :
- découverte automatique des credentials Tier 1 (env vars)
- pré-remplissage depuis la config existante en re-run
- messages d'erreur actionnables avec URLs d'inscription
- chaînage `grob doctor` en fin de wizard
- flag `--edit` / `--reconfigure` pour édition par section
- support `GROB_SETUP_*` env vars pour CI non-interactif
- détection de drift schema (sections inconnues/dépréciées)
- helper `open_browser` pour OAuth (préparé, non câblé auth)
- unification langue anglaise dans tous les écrans
- instructions next-step concrètes en fin de wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.8 (#159)

* feat(router): ajouter la config declarative des tiers de complexite

Permet de mapper les tiers de complexite (trivial/medium/complex) vers
des listes de providers via [[tiers]] dans le TOML. Le dispatch resout
le tier avant les mappings modele. Retrocompatible : sans [[tiers]],
le comportement est inchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.9 (#162)

---------

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Destynova2 added a commit that referenced this pull request Apr 12, 2026
* fix(security): résoudre 6 alertes CodeQL/Semgrep cleartext logging

Supprime le logging en cleartext de valeurs canary PII dans les assertions
de test (pii.rs), annote le faux positif HTTPS dans credential_check.rs,
et ajoute nosemgrep sur le token de test assemblé dynamiquement (tests.rs).

Résout: 4 alertes HIGH CodeQL (pii.rs L689/L1151/L1172/L1183),
1 alerte HIGH CodeQL (credential_check.rs L70),
1 faux positif Semgrep (tests.rs L58).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(exec): vérifier la santé avant spawn pour éviter le faux-démarrage

Re-vérifie is_instance_running avant spawn_background_service pour éviter
le faux-démarrage quand le flow credentials interactif prend du temps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): ajouter le tool grob_hint + header X-Grob-Hint

Ajoute ComplexityHint (trivial/medium/complex), le tool MCP grob_hint
(one-shot slot), la résolution multi-source dans dispatch (header →
metadata → MCP slot), et l'injection dans tools/list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.4 (#141)

* fix(mcp): gater grob_hint derrière cfg(feature = "mcp")

Les types ComplexityHint et le champ grob_hint dans AppState référencent
le module MCP qui n'existe pas quand le feature est désactivé. Ajoute les
guards #[cfg(feature = "mcp")] manquants dans dispatch/mod.rs et
server/mod.rs pour corriger les builds feature powerset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.5 (#143)

* test(dlp,router): ajouter proptests pour robustesse DLP et router

Add 13 proptest properties for DLP and router parsers:

DLP (7):
- sanitize idempotence (sanitize(sanitize(x)) == sanitize(x))
- output length bounded (len <= input + 200)
- known secrets never leak through sanitize
- DFA scanner never panics on arbitrary UTF-8
- Luhn-valid credit cards detected by PII scanner
- Mod97-valid IBANs detected by PII scanner
- sanitize preserves valid UTF-8

Router (6):
- extract_trailing_literal_byte never panics on arbitrary input
- deterministic (same input = same output)
- result always lowercase ASCII alphabetic
- alternation patterns always return None
- classify never panics on arbitrary model names
- route never panics on arbitrary user text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): add RUSTSEC-2026-0097 exception and fix gitleaks force-push

- deny.toml: ignore RUSTSEC-2026-0097 (rand unsound with custom logger
  calling rand::rng()). No impact: grob does not define a custom logger
  accessing ThreadRng.

- ci.yml: for PRs, scan gitleaks against origin/<base-ref> instead of
  github.event.before. Force-pushes invalidate the "before" SHA, causing
  gitleaks to fail on a broken commit range. Using the base branch ref
  always resolves to a valid range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(setup): ajouter support custom endpoint OpenAI/Anthropic-compatible

Ajoute deux nouvelles options dans le wizard setup pour configurer des
endpoints LLM custom compatibles OpenAI ou Anthropic. Le wizard demande
la base_url, valide la connexion via un appel GET /models, et écrit
le provider_type + base_url dans le TOML config.

Modifications :
- src/providers/registry.rs : nouveaux types "openai_compatible" et
  "anthropic_compatible" dans create_provider
- src/commands/credential_check.rs : validate_custom_endpoint() pour
  valider les clés API contre des endpoints custom
- src/commands/setup.rs : screen_custom_endpoints(), CustomEndpoint
  struct, intégration dans le wizard flow + 9 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cache): ajouter cache sémantique SimHash avec distance de Hamming

Adds an in-memory SimHash-based semantic cache layer that detects
near-duplicate prompts via 64-bit fingerprints and Hamming distance
(default threshold ≤ 3 bits). The fuzzy layer is consulted before the
exact SHA-256 cache to improve hit rates for rephrased requests.

- src/cache/simhash.rs: normalize, compute, hamming_distance, SimHashCache
- Integrated into ResponseCache via get_with_simhash / put_with_simhash
- 16 new unit tests covering normalization, hashing, distance, and cache ops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cache): corriger normalisation SimHash et utiliser moka pour eviction

- Supprimer le tri lexicographique des tokens qui detruisait le sens
  semantique (ex: "translate English to French" = "translate French to
  English"). L'ordre est desormais preserve.
- Hasher chaque token avec sa position (hash_token_at) pour rendre le
  SimHash sensible a l'ordre des mots.
- Remplacer RwLock<HashMap> par moka::sync::Cache avec max_capacity et
  TTL built-in, alignant le cycle de vie sur le cache exact.
- Adapter response_cache.rs pour passer capacity/TTL au constructeur.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tracing): ajouter rotation par taille et compression zstd des traces

Ajoute la rotation automatique des fichiers trace JSONL quand ils
dépassent la taille configurée (max_size_mb, défaut 50 MB). Les fichiers
rotatifs sont nommés trace.N.jsonl et limités à max_files (défaut 3).
L'option compress active la compression zstd des fichiers rotatifs.

Nouveaux champs TracingConfig : max_size_mb, max_files, compress.
6 tests unitaires couvrent la rotation, le shift, la suppression des
plus anciens, la compression zstd, et le déclenchement via write_trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tracing): utiliser streaming zstd pour compression rotation

Remplace `zstd::encode_all` (charge tout en mémoire) par un
`zstd::Encoder` en streaming avec `BufReader` + `io::copy`.
Élimine le pic mémoire lors de la compression de gros fichiers trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.6 (#150)

* fix(ci): ajouter RUSTSEC-2026-0097 a audit.toml (#153)

cargo-audit echoue sur develop depuis le merge #148 car
RUSTSEC-2026-0097 (rand unsound avec custom logger) n'etait
ignore que dans deny.toml, pas dans .cargo/audit.toml.

Pas d'impact : grob ne definit pas de custom logger utilisant
ThreadRng.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(ci): documenter la dépendance ruleset → Required checks (#154)

Le ruleset "Protect develop" ne doit référencer que le job
"Required checks" (et "cla-check"), jamais les jobs individuels
(Clippy, Rustfmt, etc.) car le path pruning les skip sur les
changements non-Rust, causant un pending éternel.

Voir PR #153 pour le contexte.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(router): ajouter le scoring heuristique de complexite

Classifie chaque requete en trivial/medium/complex via une somme
ponderee de signaux observables (max_tokens, presence d'outils,
taille du contexte, mots-cles, longueur du system prompt).

Le tier est attache a RouteDecision.complexity_tier pour usage
par le futur systeme de tiers declaratif (T-P3).

17 tests unitaires couvrent les combinaisons de signaux, les
cas limites et la configuration des poids.

* chore: release v0.36.7 (#156)

* feat(wizard): polir le wizard setup pour atteindre le score audit 85+

Implémente les 10 recommandations de l'audit cli-wizard :
- découverte automatique des credentials Tier 1 (env vars)
- pré-remplissage depuis la config existante en re-run
- messages d'erreur actionnables avec URLs d'inscription
- chaînage `grob doctor` en fin de wizard
- flag `--edit` / `--reconfigure` pour édition par section
- support `GROB_SETUP_*` env vars pour CI non-interactif
- détection de drift schema (sections inconnues/dépréciées)
- helper `open_browser` pour OAuth (préparé, non câblé auth)
- unification langue anglaise dans tous les écrans
- instructions next-step concrètes en fin de wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.8 (#159)

* feat(router): ajouter la config declarative des tiers de complexite

Permet de mapper les tiers de complexite (trivial/medium/complex) vers
des listes de providers via [[tiers]] dans le TOML. Le dispatch resout
le tier avant les mappings modele. Retrocompatible : sans [[tiers]],
le comportement est inchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(wizard): factoriser write_config/run_edit_section et supprimer unwrap

Corrige les 3 points bloquants du quality gate CQI 7.0 :
- extrait apply_auth_overrides, apply_fallback, apply_compliance comme
  fonctions partagees entre write_config et run_edit_section (C4 duplication)
- patch() retourne Result au lieu de unwrap() sur le TOML mal forme
- eclate screen_auth en 4 sous-fonctions par branche d'authentification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.9 (#162)

* docs(how-to): ajouter le guide auto-tune routing via trace et MCP

Documente le workflow complet : activer le tracing, analyser trace.jsonl
avec jq, identifier les patterns de routage sous-optimaux, ajuster les
prompt rules et seuils de scoring via grob_configure sans redemarrage.
Format Diataxis how-to.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

Le pipeline CI docs-only ne cree pas le job Required checks
requis par le ruleset. Ce commit touche src/lib.rs pour
declencher le pipeline complet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: corriger le formatage de lib.rs

* docs(router): lier classify.rs au guide auto-tune routing

* style: corriger 7 lints clippy nightly (collapsible_match, sort_by_key, checked_div)

Les toolchains beta et nightly introduisent 3 nouveaux lints qui
seront actifs en stable dans ~6 semaines. Anticipe la compatibilite
pour eviter un blocage CI futur.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ci): supprimer paths-ignore sur pull_request pour debloquer les PRs docs-only

Le paths-ignore au niveau du trigger pull_request empechait le
workflow CI de se lancer pour les PRs ne touchant que des fichiers
markdown. Le job Required checks n'etait jamais cree, bloquant
indefiniment le merge (ruleset exige ce status check).

Le pruning interne via dorny/paths-filter + les conditions if: sur
chaque job suffisent deja a skip les jobs Rust inutiles. Le job
Required checks tourne toujours (if: always()) et accepte les
resultats skipped.

Le paths-ignore sur push/develop est conserve pour eviter de
gaspiller des minutes CI sur les merges docs-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(readme): synchroniser le README avec l'etat v0.36.9

- Ajouter le badge Downloads
- Ajouter les 4 nouveaux providers (z.ai, MiniMax, Kimi, Zenmux)
- Deplacer Ollama en fin de table (seul provider local)
- Ajouter MCP tool matrix dans les features
- Mettre a jour l'arborescence src/ (watch, log_backend, log_export,
  models, cache, message_tracing)
- Ajouter prek dans les prerequisites et la section hooks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

---------

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Destynova2 added a commit that referenced this pull request Apr 13, 2026
* fix(security): résoudre 6 alertes CodeQL/Semgrep cleartext logging

Supprime le logging en cleartext de valeurs canary PII dans les assertions
de test (pii.rs), annote le faux positif HTTPS dans credential_check.rs,
et ajoute nosemgrep sur le token de test assemblé dynamiquement (tests.rs).

Résout: 4 alertes HIGH CodeQL (pii.rs L689/L1151/L1172/L1183),
1 alerte HIGH CodeQL (credential_check.rs L70),
1 faux positif Semgrep (tests.rs L58).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(exec): vérifier la santé avant spawn pour éviter le faux-démarrage

Re-vérifie is_instance_running avant spawn_background_service pour éviter
le faux-démarrage quand le flow credentials interactif prend du temps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): ajouter le tool grob_hint + header X-Grob-Hint

Ajoute ComplexityHint (trivial/medium/complex), le tool MCP grob_hint
(one-shot slot), la résolution multi-source dans dispatch (header →
metadata → MCP slot), et l'injection dans tools/list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.4 (#141)

* fix(mcp): gater grob_hint derrière cfg(feature = "mcp")

Les types ComplexityHint et le champ grob_hint dans AppState référencent
le module MCP qui n'existe pas quand le feature est désactivé. Ajoute les
guards #[cfg(feature = "mcp")] manquants dans dispatch/mod.rs et
server/mod.rs pour corriger les builds feature powerset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.5 (#143)

* test(dlp,router): ajouter proptests pour robustesse DLP et router

Add 13 proptest properties for DLP and router parsers:

DLP (7):
- sanitize idempotence (sanitize(sanitize(x)) == sanitize(x))
- output length bounded (len <= input + 200)
- known secrets never leak through sanitize
- DFA scanner never panics on arbitrary UTF-8
- Luhn-valid credit cards detected by PII scanner
- Mod97-valid IBANs detected by PII scanner
- sanitize preserves valid UTF-8

Router (6):
- extract_trailing_literal_byte never panics on arbitrary input
- deterministic (same input = same output)
- result always lowercase ASCII alphabetic
- alternation patterns always return None
- classify never panics on arbitrary model names
- route never panics on arbitrary user text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): add RUSTSEC-2026-0097 exception and fix gitleaks force-push

- deny.toml: ignore RUSTSEC-2026-0097 (rand unsound with custom logger
  calling rand::rng()). No impact: grob does not define a custom logger
  accessing ThreadRng.

- ci.yml: for PRs, scan gitleaks against origin/<base-ref> instead of
  github.event.before. Force-pushes invalidate the "before" SHA, causing
  gitleaks to fail on a broken commit range. Using the base branch ref
  always resolves to a valid range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(setup): ajouter support custom endpoint OpenAI/Anthropic-compatible

Ajoute deux nouvelles options dans le wizard setup pour configurer des
endpoints LLM custom compatibles OpenAI ou Anthropic. Le wizard demande
la base_url, valide la connexion via un appel GET /models, et écrit
le provider_type + base_url dans le TOML config.

Modifications :
- src/providers/registry.rs : nouveaux types "openai_compatible" et
  "anthropic_compatible" dans create_provider
- src/commands/credential_check.rs : validate_custom_endpoint() pour
  valider les clés API contre des endpoints custom
- src/commands/setup.rs : screen_custom_endpoints(), CustomEndpoint
  struct, intégration dans le wizard flow + 9 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cache): ajouter cache sémantique SimHash avec distance de Hamming

Adds an in-memory SimHash-based semantic cache layer that detects
near-duplicate prompts via 64-bit fingerprints and Hamming distance
(default threshold ≤ 3 bits). The fuzzy layer is consulted before the
exact SHA-256 cache to improve hit rates for rephrased requests.

- src/cache/simhash.rs: normalize, compute, hamming_distance, SimHashCache
- Integrated into ResponseCache via get_with_simhash / put_with_simhash
- 16 new unit tests covering normalization, hashing, distance, and cache ops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cache): corriger normalisation SimHash et utiliser moka pour eviction

- Supprimer le tri lexicographique des tokens qui detruisait le sens
  semantique (ex: "translate English to French" = "translate French to
  English"). L'ordre est desormais preserve.
- Hasher chaque token avec sa position (hash_token_at) pour rendre le
  SimHash sensible a l'ordre des mots.
- Remplacer RwLock<HashMap> par moka::sync::Cache avec max_capacity et
  TTL built-in, alignant le cycle de vie sur le cache exact.
- Adapter response_cache.rs pour passer capacity/TTL au constructeur.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tracing): ajouter rotation par taille et compression zstd des traces

Ajoute la rotation automatique des fichiers trace JSONL quand ils
dépassent la taille configurée (max_size_mb, défaut 50 MB). Les fichiers
rotatifs sont nommés trace.N.jsonl et limités à max_files (défaut 3).
L'option compress active la compression zstd des fichiers rotatifs.

Nouveaux champs TracingConfig : max_size_mb, max_files, compress.
6 tests unitaires couvrent la rotation, le shift, la suppression des
plus anciens, la compression zstd, et le déclenchement via write_trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tracing): utiliser streaming zstd pour compression rotation

Remplace `zstd::encode_all` (charge tout en mémoire) par un
`zstd::Encoder` en streaming avec `BufReader` + `io::copy`.
Élimine le pic mémoire lors de la compression de gros fichiers trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.6 (#150)

* fix(ci): ajouter RUSTSEC-2026-0097 a audit.toml (#153)

cargo-audit echoue sur develop depuis le merge #148 car
RUSTSEC-2026-0097 (rand unsound avec custom logger) n'etait
ignore que dans deny.toml, pas dans .cargo/audit.toml.

Pas d'impact : grob ne definit pas de custom logger utilisant
ThreadRng.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(ci): documenter la dépendance ruleset → Required checks (#154)

Le ruleset "Protect develop" ne doit référencer que le job
"Required checks" (et "cla-check"), jamais les jobs individuels
(Clippy, Rustfmt, etc.) car le path pruning les skip sur les
changements non-Rust, causant un pending éternel.

Voir PR #153 pour le contexte.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(router): ajouter le scoring heuristique de complexite

Classifie chaque requete en trivial/medium/complex via une somme
ponderee de signaux observables (max_tokens, presence d'outils,
taille du contexte, mots-cles, longueur du system prompt).

Le tier est attache a RouteDecision.complexity_tier pour usage
par le futur systeme de tiers declaratif (T-P3).

17 tests unitaires couvrent les combinaisons de signaux, les
cas limites et la configuration des poids.

* chore: release v0.36.7 (#156)

* feat(wizard): polir le wizard setup pour atteindre le score audit 85+

Implémente les 10 recommandations de l'audit cli-wizard :
- découverte automatique des credentials Tier 1 (env vars)
- pré-remplissage depuis la config existante en re-run
- messages d'erreur actionnables avec URLs d'inscription
- chaînage `grob doctor` en fin de wizard
- flag `--edit` / `--reconfigure` pour édition par section
- support `GROB_SETUP_*` env vars pour CI non-interactif
- détection de drift schema (sections inconnues/dépréciées)
- helper `open_browser` pour OAuth (préparé, non câblé auth)
- unification langue anglaise dans tous les écrans
- instructions next-step concrètes en fin de wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.8 (#159)

* feat(router): ajouter la config declarative des tiers de complexite

Permet de mapper les tiers de complexite (trivial/medium/complex) vers
des listes de providers via [[tiers]] dans le TOML. Le dispatch resout
le tier avant les mappings modele. Retrocompatible : sans [[tiers]],
le comportement est inchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(wizard): factoriser write_config/run_edit_section et supprimer unwrap

Corrige les 3 points bloquants du quality gate CQI 7.0 :
- extrait apply_auth_overrides, apply_fallback, apply_compliance comme
  fonctions partagees entre write_config et run_edit_section (C4 duplication)
- patch() retourne Result au lieu de unwrap() sur le TOML mal forme
- eclate screen_auth en 4 sous-fonctions par branche d'authentification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.9 (#162)

* docs(how-to): ajouter le guide auto-tune routing via trace et MCP

Documente le workflow complet : activer le tracing, analyser trace.jsonl
avec jq, identifier les patterns de routage sous-optimaux, ajuster les
prompt rules et seuils de scoring via grob_configure sans redemarrage.
Format Diataxis how-to.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

Le pipeline CI docs-only ne cree pas le job Required checks
requis par le ruleset. Ce commit touche src/lib.rs pour
declencher le pipeline complet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: corriger le formatage de lib.rs

* docs(router): lier classify.rs au guide auto-tune routing

* style: corriger 7 lints clippy nightly (collapsible_match, sort_by_key, checked_div)

Les toolchains beta et nightly introduisent 3 nouveaux lints qui
seront actifs en stable dans ~6 semaines. Anticipe la compatibilite
pour eviter un blocage CI futur.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ci): supprimer paths-ignore sur pull_request pour debloquer les PRs docs-only

Le paths-ignore au niveau du trigger pull_request empechait le
workflow CI de se lancer pour les PRs ne touchant que des fichiers
markdown. Le job Required checks n'etait jamais cree, bloquant
indefiniment le merge (ruleset exige ce status check).

Le pruning interne via dorny/paths-filter + les conditions if: sur
chaque job suffisent deja a skip les jobs Rust inutiles. Le job
Required checks tourne toujours (if: always()) et accepte les
resultats skipped.

Le paths-ignore sur push/develop est conserve pour eviter de
gaspiller des minutes CI sur les merges docs-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(readme): synchroniser le README avec l'etat v0.36.9

- Ajouter le badge Downloads
- Ajouter les 4 nouveaux providers (z.ai, MiniMax, Kimi, Zenmux)
- Deplacer Ollama en fin de table (seul provider local)
- Ajouter MCP tool matrix dans les features
- Mettre a jour l'arborescence src/ (watch, log_backend, log_export,
  models, cache, message_tracing)
- Ajouter prek dans les prerequisites et la section hooks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

* fix(security): resoudre les alertes CodeQL #64 et Semgrep #56

CodeQL #64 (cleartext-transmission credential_check.rs) : ajout d'un
garde HTTPS explicite avant l'envoi de credentials. Suppression du
commentaire lgtm obsolete.

Semgrep #56 (detected-github-token tests.rs) : ajout des annotations
nosemgrep sur les 4 lignes de test qui assemblent des faux tokens
GitHub pour valider le moteur DLP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: release v0.36.10 (#171)

* feat(hit): implementer le scoring de risque parametrable (#173)

Moteur de scoring dynamique pour le HIT Gateway : table de regles par
tool, modificateurs contextuels (MCP +10, URL +15, credentials +30),
seuils configurables auto/human/deny. Garde la compatibilite arriere
avec l'evaluation statique existante.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(control): implementer le moteur ControlEngine generique (#174)

Ajoute le moteur central (state, action) -> result pour unifier
CLI, MCP et UI derriere une meme couche de dispatch.

- Enum Action couvrant 9 namespaces RPC (server, model, provider,
  budget, keys, config, tools, hit, pledge)
- Mapping pur method_name -> Action via parse_method()
- Matrice role RBAC par action via required_role()
- 5 nouveaux namespaces RPC : keys_ns, config_ns, tools_ns, hit_ns,
  pledge_ns avec handlers async
- Dispatch rpc/mod.rs rewire via le ControlEngine
- 38 nouveaux tests unitaires (14 engine + 24 namespaces)
- Tous les 214 tests passent, clippy clean, fmt ok

Decision D-01 : le CLI thin client, les wizard MCP tools, et la future
UI sont 3 adapters partageant ce moteur.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(dlp): ajouter la detection d'injection indirecte dans les responses et tool_result (#175)

Implemente ADR-0015 : scan des responses LLM et des blocs tool_result
pour les patterns d'injection indirecte. Action par defaut warn (log),
configurable en block ou redact.

- Config : scan_responses, scan_tool_results, response_action dans [dlp.prompt_injection]
- Detecteur : scan_indirect() reutilise le pipeline de normalisation existant
- Pipeline : scan tool_result dans sanitize_request_checked, scan response dans sanitize_response_text_reported
- Stream : detection injection indirecte sur le buffer accumule SSE
- 13 nouveaux tests couvrant response, tool_result, false positive, multilingue, unicode, nested blocks
- Doc reference : docs/reference/dlp-indirect-injection.md

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.11 (#176)

* feat(cli): migrer les commandes CLI vers le client RPC thin (#178)

Ajoute rpc_client.rs (client JSON-RPC 2.0 leger) et migre status,
spend, model, key pour interroger le serveur via RPC quand il
tourne, avec fallback vers lecture locale sinon.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): exposer les namespaces control via MCP tools + pledge CLI (#179)

Ajoute 4 outils MCP (grob_keys, grob_tools, grob_hit, grob_pledge)
avec schemas JSON et pont generique vers le control plane RPC.
Cree le module pledge CLI (set, clear, status, list_profiles).
30 nouveaux tests (23 MCP handlers + 7 pledge CLI), 891 total pass.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(storage): remplacer redb par fichiers atomiques + journal append-only (ADR-0013) (#180)

Supprime la dependance redb au profit de fichiers humainement lisibles :
- spend/ : journal JSONL append-only par mois, replay au demarrage
- tokens/ : un fichier chiffre AES-256-GCM par provider (ecriture atomique)
- vkeys/ : un fichier chiffre par cle virtuelle (double index hash + UUID)
- migrate.rs : detection legacy grob.db avec warning (pas de migration auto)
- Suppression de redb de Cargo.toml (-1 dependance binaire)
- Mise a jour doc reference storage.md, callers, e2e tests

891 tests pass, 0 clippy warnings, 22 tests storage (3 atomic + 4 journal + 2 migrate + 4 encrypt + 9 GrobStore).

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.12 (#181)

---------

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Destynova2 added a commit that referenced this pull request Apr 13, 2026
* fix(security): résoudre 6 alertes CodeQL/Semgrep cleartext logging

Supprime le logging en cleartext de valeurs canary PII dans les assertions
de test (pii.rs), annote le faux positif HTTPS dans credential_check.rs,
et ajoute nosemgrep sur le token de test assemblé dynamiquement (tests.rs).

Résout: 4 alertes HIGH CodeQL (pii.rs L689/L1151/L1172/L1183),
1 alerte HIGH CodeQL (credential_check.rs L70),
1 faux positif Semgrep (tests.rs L58).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(exec): vérifier la santé avant spawn pour éviter le faux-démarrage

Re-vérifie is_instance_running avant spawn_background_service pour éviter
le faux-démarrage quand le flow credentials interactif prend du temps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): ajouter le tool grob_hint + header X-Grob-Hint

Ajoute ComplexityHint (trivial/medium/complex), le tool MCP grob_hint
(one-shot slot), la résolution multi-source dans dispatch (header →
metadata → MCP slot), et l'injection dans tools/list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.4 (#141)

* fix(mcp): gater grob_hint derrière cfg(feature = "mcp")

Les types ComplexityHint et le champ grob_hint dans AppState référencent
le module MCP qui n'existe pas quand le feature est désactivé. Ajoute les
guards #[cfg(feature = "mcp")] manquants dans dispatch/mod.rs et
server/mod.rs pour corriger les builds feature powerset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.5 (#143)

* test(dlp,router): ajouter proptests pour robustesse DLP et router

Add 13 proptest properties for DLP and router parsers:

DLP (7):
- sanitize idempotence (sanitize(sanitize(x)) == sanitize(x))
- output length bounded (len <= input + 200)
- known secrets never leak through sanitize
- DFA scanner never panics on arbitrary UTF-8
- Luhn-valid credit cards detected by PII scanner
- Mod97-valid IBANs detected by PII scanner
- sanitize preserves valid UTF-8

Router (6):
- extract_trailing_literal_byte never panics on arbitrary input
- deterministic (same input = same output)
- result always lowercase ASCII alphabetic
- alternation patterns always return None
- classify never panics on arbitrary model names
- route never panics on arbitrary user text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): add RUSTSEC-2026-0097 exception and fix gitleaks force-push

- deny.toml: ignore RUSTSEC-2026-0097 (rand unsound with custom logger
  calling rand::rng()). No impact: grob does not define a custom logger
  accessing ThreadRng.

- ci.yml: for PRs, scan gitleaks against origin/<base-ref> instead of
  github.event.before. Force-pushes invalidate the "before" SHA, causing
  gitleaks to fail on a broken commit range. Using the base branch ref
  always resolves to a valid range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(setup): ajouter support custom endpoint OpenAI/Anthropic-compatible

Ajoute deux nouvelles options dans le wizard setup pour configurer des
endpoints LLM custom compatibles OpenAI ou Anthropic. Le wizard demande
la base_url, valide la connexion via un appel GET /models, et écrit
le provider_type + base_url dans le TOML config.

Modifications :
- src/providers/registry.rs : nouveaux types "openai_compatible" et
  "anthropic_compatible" dans create_provider
- src/commands/credential_check.rs : validate_custom_endpoint() pour
  valider les clés API contre des endpoints custom
- src/commands/setup.rs : screen_custom_endpoints(), CustomEndpoint
  struct, intégration dans le wizard flow + 9 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cache): ajouter cache sémantique SimHash avec distance de Hamming

Adds an in-memory SimHash-based semantic cache layer that detects
near-duplicate prompts via 64-bit fingerprints and Hamming distance
(default threshold ≤ 3 bits). The fuzzy layer is consulted before the
exact SHA-256 cache to improve hit rates for rephrased requests.

- src/cache/simhash.rs: normalize, compute, hamming_distance, SimHashCache
- Integrated into ResponseCache via get_with_simhash / put_with_simhash
- 16 new unit tests covering normalization, hashing, distance, and cache ops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cache): corriger normalisation SimHash et utiliser moka pour eviction

- Supprimer le tri lexicographique des tokens qui detruisait le sens
  semantique (ex: "translate English to French" = "translate French to
  English"). L'ordre est desormais preserve.
- Hasher chaque token avec sa position (hash_token_at) pour rendre le
  SimHash sensible a l'ordre des mots.
- Remplacer RwLock<HashMap> par moka::sync::Cache avec max_capacity et
  TTL built-in, alignant le cycle de vie sur le cache exact.
- Adapter response_cache.rs pour passer capacity/TTL au constructeur.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tracing): ajouter rotation par taille et compression zstd des traces

Ajoute la rotation automatique des fichiers trace JSONL quand ils
dépassent la taille configurée (max_size_mb, défaut 50 MB). Les fichiers
rotatifs sont nommés trace.N.jsonl et limités à max_files (défaut 3).
L'option compress active la compression zstd des fichiers rotatifs.

Nouveaux champs TracingConfig : max_size_mb, max_files, compress.
6 tests unitaires couvrent la rotation, le shift, la suppression des
plus anciens, la compression zstd, et le déclenchement via write_trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tracing): utiliser streaming zstd pour compression rotation

Remplace `zstd::encode_all` (charge tout en mémoire) par un
`zstd::Encoder` en streaming avec `BufReader` + `io::copy`.
Élimine le pic mémoire lors de la compression de gros fichiers trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.6 (#150)

* fix(ci): ajouter RUSTSEC-2026-0097 a audit.toml (#153)

cargo-audit echoue sur develop depuis le merge #148 car
RUSTSEC-2026-0097 (rand unsound avec custom logger) n'etait
ignore que dans deny.toml, pas dans .cargo/audit.toml.

Pas d'impact : grob ne definit pas de custom logger utilisant
ThreadRng.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(ci): documenter la dépendance ruleset → Required checks (#154)

Le ruleset "Protect develop" ne doit référencer que le job
"Required checks" (et "cla-check"), jamais les jobs individuels
(Clippy, Rustfmt, etc.) car le path pruning les skip sur les
changements non-Rust, causant un pending éternel.

Voir PR #153 pour le contexte.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(router): ajouter le scoring heuristique de complexite

Classifie chaque requete en trivial/medium/complex via une somme
ponderee de signaux observables (max_tokens, presence d'outils,
taille du contexte, mots-cles, longueur du system prompt).

Le tier est attache a RouteDecision.complexity_tier pour usage
par le futur systeme de tiers declaratif (T-P3).

17 tests unitaires couvrent les combinaisons de signaux, les
cas limites et la configuration des poids.

* chore: release v0.36.7 (#156)

* feat(wizard): polir le wizard setup pour atteindre le score audit 85+

Implémente les 10 recommandations de l'audit cli-wizard :
- découverte automatique des credentials Tier 1 (env vars)
- pré-remplissage depuis la config existante en re-run
- messages d'erreur actionnables avec URLs d'inscription
- chaînage `grob doctor` en fin de wizard
- flag `--edit` / `--reconfigure` pour édition par section
- support `GROB_SETUP_*` env vars pour CI non-interactif
- détection de drift schema (sections inconnues/dépréciées)
- helper `open_browser` pour OAuth (préparé, non câblé auth)
- unification langue anglaise dans tous les écrans
- instructions next-step concrètes en fin de wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.8 (#159)

* feat(router): ajouter la config declarative des tiers de complexite

Permet de mapper les tiers de complexite (trivial/medium/complex) vers
des listes de providers via [[tiers]] dans le TOML. Le dispatch resout
le tier avant les mappings modele. Retrocompatible : sans [[tiers]],
le comportement est inchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(wizard): factoriser write_config/run_edit_section et supprimer unwrap

Corrige les 3 points bloquants du quality gate CQI 7.0 :
- extrait apply_auth_overrides, apply_fallback, apply_compliance comme
  fonctions partagees entre write_config et run_edit_section (C4 duplication)
- patch() retourne Result au lieu de unwrap() sur le TOML mal forme
- eclate screen_auth en 4 sous-fonctions par branche d'authentification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.9 (#162)

* docs(how-to): ajouter le guide auto-tune routing via trace et MCP

Documente le workflow complet : activer le tracing, analyser trace.jsonl
avec jq, identifier les patterns de routage sous-optimaux, ajuster les
prompt rules et seuils de scoring via grob_configure sans redemarrage.
Format Diataxis how-to.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

Le pipeline CI docs-only ne cree pas le job Required checks
requis par le ruleset. Ce commit touche src/lib.rs pour
declencher le pipeline complet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: corriger le formatage de lib.rs

* docs(router): lier classify.rs au guide auto-tune routing

* style: corriger 7 lints clippy nightly (collapsible_match, sort_by_key, checked_div)

Les toolchains beta et nightly introduisent 3 nouveaux lints qui
seront actifs en stable dans ~6 semaines. Anticipe la compatibilite
pour eviter un blocage CI futur.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ci): supprimer paths-ignore sur pull_request pour debloquer les PRs docs-only

Le paths-ignore au niveau du trigger pull_request empechait le
workflow CI de se lancer pour les PRs ne touchant que des fichiers
markdown. Le job Required checks n'etait jamais cree, bloquant
indefiniment le merge (ruleset exige ce status check).

Le pruning interne via dorny/paths-filter + les conditions if: sur
chaque job suffisent deja a skip les jobs Rust inutiles. Le job
Required checks tourne toujours (if: always()) et accepte les
resultats skipped.

Le paths-ignore sur push/develop est conserve pour eviter de
gaspiller des minutes CI sur les merges docs-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(readme): synchroniser le README avec l'etat v0.36.9

- Ajouter le badge Downloads
- Ajouter les 4 nouveaux providers (z.ai, MiniMax, Kimi, Zenmux)
- Deplacer Ollama en fin de table (seul provider local)
- Ajouter MCP tool matrix dans les features
- Mettre a jour l'arborescence src/ (watch, log_backend, log_export,
  models, cache, message_tracing)
- Ajouter prek dans les prerequisites et la section hooks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

* fix(security): resoudre les alertes CodeQL #64 et Semgrep #56

CodeQL #64 (cleartext-transmission credential_check.rs) : ajout d'un
garde HTTPS explicite avant l'envoi de credentials. Suppression du
commentaire lgtm obsolete.

Semgrep #56 (detected-github-token tests.rs) : ajout des annotations
nosemgrep sur les 4 lignes de test qui assemblent des faux tokens
GitHub pour valider le moteur DLP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: release v0.36.10 (#171)

* feat(hit): implementer le scoring de risque parametrable (#173)

Moteur de scoring dynamique pour le HIT Gateway : table de regles par
tool, modificateurs contextuels (MCP +10, URL +15, credentials +30),
seuils configurables auto/human/deny. Garde la compatibilite arriere
avec l'evaluation statique existante.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(control): implementer le moteur ControlEngine generique (#174)

Ajoute le moteur central (state, action) -> result pour unifier
CLI, MCP et UI derriere une meme couche de dispatch.

- Enum Action couvrant 9 namespaces RPC (server, model, provider,
  budget, keys, config, tools, hit, pledge)
- Mapping pur method_name -> Action via parse_method()
- Matrice role RBAC par action via required_role()
- 5 nouveaux namespaces RPC : keys_ns, config_ns, tools_ns, hit_ns,
  pledge_ns avec handlers async
- Dispatch rpc/mod.rs rewire via le ControlEngine
- 38 nouveaux tests unitaires (14 engine + 24 namespaces)
- Tous les 214 tests passent, clippy clean, fmt ok

Decision D-01 : le CLI thin client, les wizard MCP tools, et la future
UI sont 3 adapters partageant ce moteur.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(dlp): ajouter la detection d'injection indirecte dans les responses et tool_result (#175)

Implemente ADR-0015 : scan des responses LLM et des blocs tool_result
pour les patterns d'injection indirecte. Action par defaut warn (log),
configurable en block ou redact.

- Config : scan_responses, scan_tool_results, response_action dans [dlp.prompt_injection]
- Detecteur : scan_indirect() reutilise le pipeline de normalisation existant
- Pipeline : scan tool_result dans sanitize_request_checked, scan response dans sanitize_response_text_reported
- Stream : detection injection indirecte sur le buffer accumule SSE
- 13 nouveaux tests couvrant response, tool_result, false positive, multilingue, unicode, nested blocks
- Doc reference : docs/reference/dlp-indirect-injection.md

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.11 (#176)

* feat(cli): migrer les commandes CLI vers le client RPC thin (#178)

Ajoute rpc_client.rs (client JSON-RPC 2.0 leger) et migre status,
spend, model, key pour interroger le serveur via RPC quand il
tourne, avec fallback vers lecture locale sinon.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): exposer les namespaces control via MCP tools + pledge CLI (#179)

Ajoute 4 outils MCP (grob_keys, grob_tools, grob_hit, grob_pledge)
avec schemas JSON et pont generique vers le control plane RPC.
Cree le module pledge CLI (set, clear, status, list_profiles).
30 nouveaux tests (23 MCP handlers + 7 pledge CLI), 891 total pass.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(storage): remplacer redb par fichiers atomiques + journal append-only (ADR-0013) (#180)

Supprime la dependance redb au profit de fichiers humainement lisibles :
- spend/ : journal JSONL append-only par mois, replay au demarrage
- tokens/ : un fichier chiffre AES-256-GCM par provider (ecriture atomique)
- vkeys/ : un fichier chiffre par cle virtuelle (double index hash + UUID)
- migrate.rs : detection legacy grob.db avec warning (pas de migration auto)
- Suppression de redb de Cargo.toml (-1 dependance binaire)
- Mise a jour doc reference storage.md, callers, e2e tests

891 tests pass, 0 clippy warnings, 22 tests storage (3 atomic + 4 journal + 2 migrate + 4 encrypt + 9 GrobStore).

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.12 (#181)

* fix(ci): auto-cleanup des sync-main PRs obsoletes et resolution de conflits

Le workflow sync-main.yml s'empilait : chaque tag creait une PR sans
fermer les precedentes, et les conflits avec main bloquaient le merge.

Changements :
- Ferme les anciennes sync-main PRs (label sync-main) avant d'en creer
  une nouvelle
- Merge main dans la branche sync avec -X ours pour resoudre les
  conflits automatiquement (develop est la source de verite)
- Separe le push du checkout pour clarte

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(security): supprimer le faux positif CodeQL #66 (key UUID logging)

Le println qui affiche l'UUID de la cle revoquee est un identifiant
public, pas un secret. Meme pattern que les suppressions existantes
pour key.rs:135 et key.rs:140.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(adr): marquer ADR-0013 et ADR-0015 done apres Phase A

Les deux ADRs ont ete implementees dans le sprint grob-s2 Phase A :
- ADR-0013 (storage files) : PR #176
- ADR-0015 (indirect injection) : PR #175

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: absorber l'historique main dans develop

Merge main dans develop pour eliminer le delta 'behind' cause par
les merge commits des sync-main PRs anterieures. Develop gagne sur
tous les conflits (-X ours).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: release v0.36.13 (#187)

---------

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Destynova2 added a commit that referenced this pull request Apr 14, 2026
* fix(security): résoudre 6 alertes CodeQL/Semgrep cleartext logging

Supprime le logging en cleartext de valeurs canary PII dans les assertions
de test (pii.rs), annote le faux positif HTTPS dans credential_check.rs,
et ajoute nosemgrep sur le token de test assemblé dynamiquement (tests.rs).

Résout: 4 alertes HIGH CodeQL (pii.rs L689/L1151/L1172/L1183),
1 alerte HIGH CodeQL (credential_check.rs L70),
1 faux positif Semgrep (tests.rs L58).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(exec): vérifier la santé avant spawn pour éviter le faux-démarrage

Re-vérifie is_instance_running avant spawn_background_service pour éviter
le faux-démarrage quand le flow credentials interactif prend du temps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): ajouter le tool grob_hint + header X-Grob-Hint

Ajoute ComplexityHint (trivial/medium/complex), le tool MCP grob_hint
(one-shot slot), la résolution multi-source dans dispatch (header →
metadata → MCP slot), et l'injection dans tools/list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.4 (#141)

* fix(mcp): gater grob_hint derrière cfg(feature = "mcp")

Les types ComplexityHint et le champ grob_hint dans AppState référencent
le module MCP qui n'existe pas quand le feature est désactivé. Ajoute les
guards #[cfg(feature = "mcp")] manquants dans dispatch/mod.rs et
server/mod.rs pour corriger les builds feature powerset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.5 (#143)

* test(dlp,router): ajouter proptests pour robustesse DLP et router

Add 13 proptest properties for DLP and router parsers:

DLP (7):
- sanitize idempotence (sanitize(sanitize(x)) == sanitize(x))
- output length bounded (len <= input + 200)
- known secrets never leak through sanitize
- DFA scanner never panics on arbitrary UTF-8
- Luhn-valid credit cards detected by PII scanner
- Mod97-valid IBANs detected by PII scanner
- sanitize preserves valid UTF-8

Router (6):
- extract_trailing_literal_byte never panics on arbitrary input
- deterministic (same input = same output)
- result always lowercase ASCII alphabetic
- alternation patterns always return None
- classify never panics on arbitrary model names
- route never panics on arbitrary user text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): add RUSTSEC-2026-0097 exception and fix gitleaks force-push

- deny.toml: ignore RUSTSEC-2026-0097 (rand unsound with custom logger
  calling rand::rng()). No impact: grob does not define a custom logger
  accessing ThreadRng.

- ci.yml: for PRs, scan gitleaks against origin/<base-ref> instead of
  github.event.before. Force-pushes invalidate the "before" SHA, causing
  gitleaks to fail on a broken commit range. Using the base branch ref
  always resolves to a valid range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(setup): ajouter support custom endpoint OpenAI/Anthropic-compatible

Ajoute deux nouvelles options dans le wizard setup pour configurer des
endpoints LLM custom compatibles OpenAI ou Anthropic. Le wizard demande
la base_url, valide la connexion via un appel GET /models, et écrit
le provider_type + base_url dans le TOML config.

Modifications :
- src/providers/registry.rs : nouveaux types "openai_compatible" et
  "anthropic_compatible" dans create_provider
- src/commands/credential_check.rs : validate_custom_endpoint() pour
  valider les clés API contre des endpoints custom
- src/commands/setup.rs : screen_custom_endpoints(), CustomEndpoint
  struct, intégration dans le wizard flow + 9 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cache): ajouter cache sémantique SimHash avec distance de Hamming

Adds an in-memory SimHash-based semantic cache layer that detects
near-duplicate prompts via 64-bit fingerprints and Hamming distance
(default threshold ≤ 3 bits). The fuzzy layer is consulted before the
exact SHA-256 cache to improve hit rates for rephrased requests.

- src/cache/simhash.rs: normalize, compute, hamming_distance, SimHashCache
- Integrated into ResponseCache via get_with_simhash / put_with_simhash
- 16 new unit tests covering normalization, hashing, distance, and cache ops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cache): corriger normalisation SimHash et utiliser moka pour eviction

- Supprimer le tri lexicographique des tokens qui detruisait le sens
  semantique (ex: "translate English to French" = "translate French to
  English"). L'ordre est desormais preserve.
- Hasher chaque token avec sa position (hash_token_at) pour rendre le
  SimHash sensible a l'ordre des mots.
- Remplacer RwLock<HashMap> par moka::sync::Cache avec max_capacity et
  TTL built-in, alignant le cycle de vie sur le cache exact.
- Adapter response_cache.rs pour passer capacity/TTL au constructeur.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tracing): ajouter rotation par taille et compression zstd des traces

Ajoute la rotation automatique des fichiers trace JSONL quand ils
dépassent la taille configurée (max_size_mb, défaut 50 MB). Les fichiers
rotatifs sont nommés trace.N.jsonl et limités à max_files (défaut 3).
L'option compress active la compression zstd des fichiers rotatifs.

Nouveaux champs TracingConfig : max_size_mb, max_files, compress.
6 tests unitaires couvrent la rotation, le shift, la suppression des
plus anciens, la compression zstd, et le déclenchement via write_trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tracing): utiliser streaming zstd pour compression rotation

Remplace `zstd::encode_all` (charge tout en mémoire) par un
`zstd::Encoder` en streaming avec `BufReader` + `io::copy`.
Élimine le pic mémoire lors de la compression de gros fichiers trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.6 (#150)

* fix(ci): ajouter RUSTSEC-2026-0097 a audit.toml (#153)

cargo-audit echoue sur develop depuis le merge #148 car
RUSTSEC-2026-0097 (rand unsound avec custom logger) n'etait
ignore que dans deny.toml, pas dans .cargo/audit.toml.

Pas d'impact : grob ne definit pas de custom logger utilisant
ThreadRng.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(ci): documenter la dépendance ruleset → Required checks (#154)

Le ruleset "Protect develop" ne doit référencer que le job
"Required checks" (et "cla-check"), jamais les jobs individuels
(Clippy, Rustfmt, etc.) car le path pruning les skip sur les
changements non-Rust, causant un pending éternel.

Voir PR #153 pour le contexte.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(router): ajouter le scoring heuristique de complexite

Classifie chaque requete en trivial/medium/complex via une somme
ponderee de signaux observables (max_tokens, presence d'outils,
taille du contexte, mots-cles, longueur du system prompt).

Le tier est attache a RouteDecision.complexity_tier pour usage
par le futur systeme de tiers declaratif (T-P3).

17 tests unitaires couvrent les combinaisons de signaux, les
cas limites et la configuration des poids.

* chore: release v0.36.7 (#156)

* feat(wizard): polir le wizard setup pour atteindre le score audit 85+

Implémente les 10 recommandations de l'audit cli-wizard :
- découverte automatique des credentials Tier 1 (env vars)
- pré-remplissage depuis la config existante en re-run
- messages d'erreur actionnables avec URLs d'inscription
- chaînage `grob doctor` en fin de wizard
- flag `--edit` / `--reconfigure` pour édition par section
- support `GROB_SETUP_*` env vars pour CI non-interactif
- détection de drift schema (sections inconnues/dépréciées)
- helper `open_browser` pour OAuth (préparé, non câblé auth)
- unification langue anglaise dans tous les écrans
- instructions next-step concrètes en fin de wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.8 (#159)

* feat(router): ajouter la config declarative des tiers de complexite

Permet de mapper les tiers de complexite (trivial/medium/complex) vers
des listes de providers via [[tiers]] dans le TOML. Le dispatch resout
le tier avant les mappings modele. Retrocompatible : sans [[tiers]],
le comportement est inchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(wizard): factoriser write_config/run_edit_section et supprimer unwrap

Corrige les 3 points bloquants du quality gate CQI 7.0 :
- extrait apply_auth_overrides, apply_fallback, apply_compliance comme
  fonctions partagees entre write_config et run_edit_section (C4 duplication)
- patch() retourne Result au lieu de unwrap() sur le TOML mal forme
- eclate screen_auth en 4 sous-fonctions par branche d'authentification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.9 (#162)

* docs(how-to): ajouter le guide auto-tune routing via trace et MCP

Documente le workflow complet : activer le tracing, analyser trace.jsonl
avec jq, identifier les patterns de routage sous-optimaux, ajuster les
prompt rules et seuils de scoring via grob_configure sans redemarrage.
Format Diataxis how-to.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

Le pipeline CI docs-only ne cree pas le job Required checks
requis par le ruleset. Ce commit touche src/lib.rs pour
declencher le pipeline complet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: corriger le formatage de lib.rs

* docs(router): lier classify.rs au guide auto-tune routing

* style: corriger 7 lints clippy nightly (collapsible_match, sort_by_key, checked_div)

Les toolchains beta et nightly introduisent 3 nouveaux lints qui
seront actifs en stable dans ~6 semaines. Anticipe la compatibilite
pour eviter un blocage CI futur.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ci): supprimer paths-ignore sur pull_request pour debloquer les PRs docs-only

Le paths-ignore au niveau du trigger pull_request empechait le
workflow CI de se lancer pour les PRs ne touchant que des fichiers
markdown. Le job Required checks n'etait jamais cree, bloquant
indefiniment le merge (ruleset exige ce status check).

Le pruning interne via dorny/paths-filter + les conditions if: sur
chaque job suffisent deja a skip les jobs Rust inutiles. Le job
Required checks tourne toujours (if: always()) et accepte les
resultats skipped.

Le paths-ignore sur push/develop est conserve pour eviter de
gaspiller des minutes CI sur les merges docs-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(readme): synchroniser le README avec l'etat v0.36.9

- Ajouter le badge Downloads
- Ajouter les 4 nouveaux providers (z.ai, MiniMax, Kimi, Zenmux)
- Deplacer Ollama en fin de table (seul provider local)
- Ajouter MCP tool matrix dans les features
- Mettre a jour l'arborescence src/ (watch, log_backend, log_export,
  models, cache, message_tracing)
- Ajouter prek dans les prerequisites et la section hooks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: declencher pipeline CI complet pour PR docs-only

* fix(security): resoudre les alertes CodeQL #64 et Semgrep #56

CodeQL #64 (cleartext-transmission credential_check.rs) : ajout d'un
garde HTTPS explicite avant l'envoi de credentials. Suppression du
commentaire lgtm obsolete.

Semgrep #56 (detected-github-token tests.rs) : ajout des annotations
nosemgrep sur les 4 lignes de test qui assemblent des faux tokens
GitHub pour valider le moteur DLP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: release v0.36.10 (#171)

* feat(hit): implementer le scoring de risque parametrable (#173)

Moteur de scoring dynamique pour le HIT Gateway : table de regles par
tool, modificateurs contextuels (MCP +10, URL +15, credentials +30),
seuils configurables auto/human/deny. Garde la compatibilite arriere
avec l'evaluation statique existante.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(control): implementer le moteur ControlEngine generique (#174)

Ajoute le moteur central (state, action) -> result pour unifier
CLI, MCP et UI derriere une meme couche de dispatch.

- Enum Action couvrant 9 namespaces RPC (server, model, provider,
  budget, keys, config, tools, hit, pledge)
- Mapping pur method_name -> Action via parse_method()
- Matrice role RBAC par action via required_role()
- 5 nouveaux namespaces RPC : keys_ns, config_ns, tools_ns, hit_ns,
  pledge_ns avec handlers async
- Dispatch rpc/mod.rs rewire via le ControlEngine
- 38 nouveaux tests unitaires (14 engine + 24 namespaces)
- Tous les 214 tests passent, clippy clean, fmt ok

Decision D-01 : le CLI thin client, les wizard MCP tools, et la future
UI sont 3 adapters partageant ce moteur.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(dlp): ajouter la detection d'injection indirecte dans les responses et tool_result (#175)

Implemente ADR-0015 : scan des responses LLM et des blocs tool_result
pour les patterns d'injection indirecte. Action par defaut warn (log),
configurable en block ou redact.

- Config : scan_responses, scan_tool_results, response_action dans [dlp.prompt_injection]
- Detecteur : scan_indirect() reutilise le pipeline de normalisation existant
- Pipeline : scan tool_result dans sanitize_request_checked, scan response dans sanitize_response_text_reported
- Stream : detection injection indirecte sur le buffer accumule SSE
- 13 nouveaux tests couvrant response, tool_result, false positive, multilingue, unicode, nested blocks
- Doc reference : docs/reference/dlp-indirect-injection.md

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.11 (#176)

* feat(cli): migrer les commandes CLI vers le client RPC thin (#178)

Ajoute rpc_client.rs (client JSON-RPC 2.0 leger) et migre status,
spend, model, key pour interroger le serveur via RPC quand il
tourne, avec fallback vers lecture locale sinon.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mcp): exposer les namespaces control via MCP tools + pledge CLI (#179)

Ajoute 4 outils MCP (grob_keys, grob_tools, grob_hit, grob_pledge)
avec schemas JSON et pont generique vers le control plane RPC.
Cree le module pledge CLI (set, clear, status, list_profiles).
30 nouveaux tests (23 MCP handlers + 7 pledge CLI), 891 total pass.

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(storage): remplacer redb par fichiers atomiques + journal append-only (ADR-0013) (#180)

Supprime la dependance redb au profit de fichiers humainement lisibles :
- spend/ : journal JSONL append-only par mois, replay au demarrage
- tokens/ : un fichier chiffre AES-256-GCM par provider (ecriture atomique)
- vkeys/ : un fichier chiffre par cle virtuelle (double index hash + UUID)
- migrate.rs : detection legacy grob.db avec warning (pas de migration auto)
- Suppression de redb de Cargo.toml (-1 dependance binaire)
- Mise a jour doc reference storage.md, callers, e2e tests

891 tests pass, 0 clippy warnings, 22 tests storage (3 atomic + 4 journal + 2 migrate + 4 encrypt + 9 GrobStore).

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.12 (#181)

* fix(ci): auto-cleanup des sync-main PRs obsoletes et resolution de conflits

Le workflow sync-main.yml s'empilait : chaque tag creait une PR sans
fermer les precedentes, et les conflits avec main bloquaient le merge.

Changements :
- Ferme les anciennes sync-main PRs (label sync-main) avant d'en creer
  une nouvelle
- Merge main dans la branche sync avec -X ours pour resoudre les
  conflits automatiquement (develop est la source de verite)
- Separe le push du checkout pour clarte

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(security): supprimer le faux positif CodeQL #66 (key UUID logging)

Le println qui affiche l'UUID de la cle revoquee est un identifiant
public, pas un secret. Meme pattern que les suppressions existantes
pour key.rs:135 et key.rs:140.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(adr): marquer ADR-0013 et ADR-0015 done apres Phase A

Les deux ADRs ont ete implementees dans le sprint grob-s2 Phase A :
- ADR-0013 (storage files) : PR #176
- ADR-0015 (indirect injection) : PR #175

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: absorber l'historique main dans develop

Merge main dans develop pour eliminer le delta 'behind' cause par
les merge commits des sync-main PRs anterieures. Develop gagne sur
tous les conflits (-X ours).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: release v0.36.13 (#187)

* fix(security): passer SARIF_FILE par variable d'env dans codeql-check.sh

L'interpolation directe de $SARIF_FILE dans le heredoc Python inline
permettait une injection de code si le chemin contenait des caracteres
speciaux (CWE-78). Passage par os.environ pour isoler la donnee du code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(shell): supprimer le chemin hardcode et renforcer build.sh

Le script contenait un cd vers /Users/clementliard/Workspace/grob
qui cassait l'execution sur toute autre machine. Remplacement par
une resolution relative via BASH_SOURCE. Ajout de set -euo pipefail
et suppression des emojis pour compatibilite CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(shell): gater les couleurs ANSI sur TTY et NO_COLOR

Les 4 scripts emettaient des sequences ANSI meme en pipe, en CI,
ou quand NO_COLOR etait defini. Ajout du test standard [ -t 1 ] +
NO_COLOR + TERM=dumb pour respecter no-color.org.

Scripts modifies :
- scripts/install-rootless.sh
- scripts/build-podman.sh
- scripts/cleancode-audit.sh
- scripts/run_tests.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(control): deplacer Role dans le control engine

Casse la dependance bidirectionnelle control <-> server/rpc.
Role est un concept RBAC du control plane, pas du transport RPC.
Le re-export dans server::rpc::types preserve la compatibilite interne.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): ajouter retry aux installations curl dans le pipeline

gitleaks, cross et crane (ci.yml + setup-e2e-pod) sont installes via
curl sans retry. Un CDN temporairement indisponible cassait la CI.
Ajout de --retry 3 --retry-delay 10 --retry-all-errors a chaque curl.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: release v0.36.14 (#191)

---------

Co-authored-by: commis-ci-fix <commis-ci-fix@grob.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant