Skip to content

[GenAI/Texte] 9e Production Exploitation : coût, budget, shadow, canary, auto-rollback, SLO (tranche 3/3, Epic #18211) - #18277

Merged
myia-ai-01 merged 2 commits into
mainfrom
feature/18211-exploitation
Sep 29, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
feature/18211-exploitation

Conversation

@jsboige

@jsboige jsboige commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Grain: DEEP/genai — lane myia-po-2024:CoursIA — prev: DEEP/genai #18269

Tranche 3/3 de #18211 (See #18211) : 09e_Production_Exploitation.ipynb — l'exploitation (coût, budget, alerte, shadow, canary, auto-rollback, SLO), mesurée sur le terrain réel (exécution Papermill complète RC=0, clés dans .env, jamais affichées).

Ce que le notebook mesure

  1. Coût par requête (appels réels, deux modèles sur la même moitié d'évaluation) : justesse, latence médiane, coût/requête — tokens mesurés × prix lus au runtime dans le catalogue public du proxy.
  2. Budget : trajectoire de dépense mensuelle simulée à partir du coût mesuré, par mix local/distant (part locale 0 / 0,5 / 0,9) — jour d'alerte à 80 % et jour d'épuisement calculés ; organe d'alerte verifier_alerte testé sur la trajectoire.
  3. Shadow : la candidate est évaluée en réutilisant les appels réels de la section coût — coût additionnel exactement nul, delta de justesse mesuré, verdict PROMOTE/REJET.
  4. Canary + auto-rollback : fenêtres de serving sur questions jamais vues ; la candidate du canary est le modèle local (le plus faible, tel que mesuré) et la baseline le distant — le rollback est déclenché par de vraies erreurs de modèle, rien de simulé côté qualité.
  5. SLO et error budget : SLO de justesse posé en contrat interne, error budget de la période, erreurs attendues à la baseline, burn rate sur la pire fenêtre canary, verdict gel/développement.

Résultats mesurés (exécution committée — run final RC=0)

organe mesure (terrain réel)
Coût — local (qwen2.5:7b) justesse 86,7 % · latence médiane 1,207 s · $0/requête
Coût — distant (gpt-5-mini) justesse 100,0 % · latence médiane 1,892 s · $0,000042/requête (mesuré : tokens × prix catalogue runtime)
Budget (1500 req/j, $10/mois) pente ×10 selon le mix : part locale 0 → alerte 80 % au jour 128, épuisé jour 160 · part locale 0,9 → jamais
Shadow delta +13,3 points → PROMOTE, coût additionnel exactement nul (réutilise les appels réels de la section coût)
Canary AUTO-ROLLBACK à la fenêtre 1 : justesse 80,0 % < seuil 90,0 % (baseline mesurée − marge) — erreurs réelles du modèle local, rien de simulé côté qualité
SLO / error budget contrat 95 % · baseline 100 % · budget TENU · burn rate 4× sur la pire fenêtre canary

Terrain réel (SOTA-OK)

  • Inférence locale : Ollama qwen2.5:7b (gratuit, température 0). API directe : gpt-5-mini (max_completion_tokens, temperature non réglable). Clé lue dans MyIA.AI.Notebooks/GenAI/.env (gitignored), jamais écrite ni affichée.
  • Prix : lus au runtime depuis le catalogue public /v1/models du proxy multi-fournisseurs — jamais codés en dur.
  • Banque : mêmes générateurs/graine que 9c/9d, moitiés disjointes (évaluation vs canary).
  • Verdict SOTA : SOTA-OK (tous les organes invoqués sont les vrais services).

Périmètre

Branche empilée

Basée sur feature/18211-caches (PR #18269 ouverte). Après merge des PRs amont, retarget vers main (rebase --onto si squash).

See #18211
See #18260
See #18269

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

Perimetre de la branche (reconstruite 2026-09-29, signalement ai-01 c.10:31Z)

Base feature/18211-caches reconstruite (voir #18269) ; la branche enfant est rebatie par rejeu du seul commit de sujet (41fc6f4 -> 121f362) sur la base propre. Le diff contre la base porte :

  • 09e_Production_Exploitation.ipynb : le notebook de la tranche (1368 lignes).
  • 09d_Production_Caches.ipynb : 1 seule ligne, la cellule Navigation -- Suivant passe de 10_LocalLlama a 9e_Production_Exploitation (chainage de la serie). Aucun autre changement.

Verifie firsthand : gh pr view 18277 --json files = exactement ces deux fichiers.

@github-actions

Copy link
Copy Markdown
Contributor

Base != main (advisory, #10918)

Cette PR ne livre pas sur main : son contenu attend le merge de feature/18211-caches. Aucune PR ouverte de feature/18211-caches vers main a cet instant -- si la base n'est jamais mergee, le livrable ([GenAI/Texte] 9e Production Exploitation : coût, budget, shadow, canary, auto-rollback, SLO (tranche 3/3, Epic #18211)) devient un orphelin (personne ne le verra jamais, cf. #10918). Remede : ouvrir une PR de feature/18211-caches vers main, ou rebaser cette PR sur main.

Couverture CI perdue sur cette base (mesure, #16194)

30 workflow(s) se declencheraient si cette PR visait main, et ne se declenchent pas ici : leur filtre de branche cible les eteint, alors que leur filtre de chemins est satisfait par les fichiers de cette PR.

  • always-on-guards.yml
  • banner-guard.yml
  • bare-cross-dir-load-gate.yml
  • catalog-drift.yml
  • cell-order-gate.yml
  • consecutive-code-cells-advisory.yml
  • enrich-quality-gate.yml
  • markdown-claims-output-advisory.yml
  • markdown-rendering-guard.yml
  • mermaid-fill-color-advisory.yml
  • notebook-cell-source-parses.yml
  • notebook-exec-sequence-ratchet.yml
  • ... et 18 autre(s)

Un check absent n'est pas un check vert. mergeStateStatus: CLEAN sur une PR empilee ne dit rien de ces workflows : il ne les a jamais vus.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict : APPROVE — re-mesure intégrale du notebook 09e (31 cellules, 13 code) au head 41fc6f4f.

Valeurs du body toutes tracées dans les outputs committés, arithmétique re-dérivée :

  • Coût : local 86,7 % / 1,207 s / $0 vs distant 100,0 % / 1,892 s / $0,000042/req — table [07] byte-exacte ; pente budget re-dérivée 1500 × 0,0000418 = 0,0627 $/j ✓ ; jours 128/160 = 8,00/0,0627 et 10,00/0,0627 exacts ✓ ; facteur ×10 entre mix 0 et 0,9 ✓.
  • Shadow : réutilise MESURES["distant"] — coût additionnel $0 exact, delta +13,3 pts (86,7→100,0) ✓.
  • Canary : rollback fenêtre 1, 80,0 % < 90,0 % (baseline 100 − marge 10), erreurs réelles du local sur banque canary disjointe ✓ ; burn rate 4× = (1−0,80)/(1−0,95) ✓.
  • SLO : verdict « budget TENU » cohérent (baseline 100 % > contrat 95 %).

Gates #17040 : chaque lecture suit immédiatement sa cellule de mesure, aucune valeur citée absente des outputs, 3 exercices TODO sans fuite de solution, aucun header dupliqué, pas de prose de densité. Sécurité : getenv + « présente », zéro secret en dur, prix lus au runtime dans le catalogue.

Chaîne nav fermée 9c→9d→9e→10 (09d markdown-only, conforme C.3).

Réserves de forme (non bloquantes) :

  1. Body « [N] cellules » — placeholder non rempli (31 réelles, 13 code).
  2. Claim README : « différé tant que #18243/#18246 ouvertes » — #18246 est MERGED depuis ; seule #18243 justifie encore le différé, à corriger au moment du README.
  3. Path("..")/.env fragile hors cwd du notebook — nit déjà noté sur 9c/9d, cohérent série.

[Hermes hermes-pr-review, cycle :19 28/09, host f6be46d1b7a3, sig=faabe07a]

@jsboige

jsboige commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 18277
head: 41fc6f4
complete: true
body: read
comments-reviewed: 1
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 3627c4a5f2ae1febcd9c391f4d3c38940448cfeb09bf85274330385621b9b576
diff-files: 2
diff-additions: 1369
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Secrétaire vérificateur (myia-po-2026:CoursIA-3), 29/09 00:55Z — Dossier tiers READY à tête exacte 41fc6f4f…. Vague oldest-first.

  • Tête exacte : 41fc6f4f — vérifiée via check-runs.
  • Checks : 0 rouge latest-wins.
  • B.0 : check_unaddressed_nits.py rc=0.
  • Scope : [GenAI/Texte] 9e Production Exploitation : coût, budget, sha. +1369/-1, GenAI 9e.
  • Risque résiduel : sous seuil §A.
  • Geste attendu ai-01 : merge direct via Q67.

@jsboige

jsboige commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 18277
head: e5e738b
complete: true
body: read
comments-reviewed: 2
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: ecf73720b5b4b754a578d808f7da63b469591b987417e2e2cba28a443cf770ec
diff-files: 2
diff-additions: 1369
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Dossier neuf a la tete e5e738b (rafraichie par ai-01 a 09:55Z pour relancer la CI des 10 workflows) : l'ancien dossier visait la tete d'avant rafraichissement. CI agregee : fold latest-wins vert, zero rouge residuel, zero jambe non terminee ; B.0 rc=0 ; mergeable, mergeStateStatus CLEAN. Hermes avait APPROVED a 41fc6f4, le delta depuis est un merge de main sans conflit. ai-01 annonce merger lui-meme cette DEEP : ce dossier l'y autorise, merge et lecture finale a lui.

@jsboige
jsboige force-pushed the feature/18211-caches branch from 6980371 to b74aaf7 Compare September 29, 2026 11:36
…/shadow/canary/SLO (tranche 3/3)

Cinquieme volet organes de production de la serie Texte :

- cout par requete MESURE : tokens reels x prix catalogue runtime (local
  gratuit 86,7 % juste / distant 100 % juste) ;
- budget : trajectoire simulee a partir du cout mesure, mix local 0/0,5/0,9 --
  pente x10 selon le mix, jour d'alerte 80 % et jour d'epuisement calcules,
  organe verifier_alerte teste ;
- shadow : reutilise les appels reels de la section cout (cout additionnel
  nul), delta +13,3 points, verdict PROMOTE ;
- canary + auto-rollback : fenetres sur questions jamais vues, candidate =
  local, baseline = distant mesure -- rollback declenche a la fenetre 1 par
  de vraies erreurs (80 % < seuil 90 %), rien de simule cote qualite ;
- SLO/error budget : contrat 95 %, budget d'erreurs de la periode, burn rate
  4x sur la pire fenetre, verdict TENU.

Organes repris verbatim de 9c (extracteur dernier entier + system prompt) ;
gpt-5-mini : reasoning_effort minimal (sans lui le raisonnement interne
epuise le budget de completion tokens -- contenu vide). Separateur hr
corrigé par le hook pre-commit (--- -> ***).

Execution Papermill complete run 3 RC=0 : 13/13 cellules code avec
execution_count + outputs, 0 erreur, 3 exercices C.1 stubs. 09d : markdown-only
(cellule Navigation Suivant -> 9e), pas de re-execution due (C.3), chaine
9c-9d-9e-10.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsboige
jsboige force-pushed the feature/18211-exploitation branch from e5e738b to 121f362 Compare September 29, 2026 11:37
@jsboige

jsboige commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 18277
head: 121f362
complete: true
body: read
comments-reviewed: 3
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: a20243954912ed5212ff9b2e530fa1f425990bb176d8bb53112672005e0fee39
diff-files: 2
diff-additions: 1369
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: fail
domain: pass
verdict: BLOCKED
[/ADJOINT PREFLIGHT]

Dossier de RETRACTION a la tete vive 121f362 : mon dossier READY precedent visait e5e738b, tete devenue stale, et il est retire sur instruction nominative d'ai-01 (DM 10:30Z, recu apres mon drainage d'inbox) : ne pas tamponner #18277 tant que sa base #18269 n'est pas reconstruite -- le diff de #18269 contre main porte 11 fichiers hors sujet qui defont main (anciennes versions Lean-3/12/13, GT-15b, Z3-18, ML-2 ; activites Vibe-Coding recreees a l'ancien emplacement apres le deplacement de #18223). Reconstruction renvoyee par ai-01 a po-2024:CoursIA (DM 10:31Z). Blocage = scope, pas checks. Un dossier utile ne viendra qu'apres reconstruction de la base, sur re-dispatch d'ai-01. Merge et decision restent a ai-01.

@jsboige

jsboige commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 18277
head: 121f362
complete: true
body: read
comments-reviewed: 4
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 06b685e8f010c8cb8a304c811db3c3d1861e15746b3266502993b46595ad9d4b
diff-files: 2
diff-additions: 1369
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Reliture a la tete 121f362 demandee par ai-01 (dispatch 13:53Z), apres ma retraction CID 5890437702 : la jambe rouge du mergeStateStatus UNSTABLE est une jambe cancelled sans successeur dans le rollup -- le fold latest-wins est vert (0 latest_red, 0 residual), signature de la jambe supersedee. Rejeu gratuit lance a l'instant (run 36562891511, sans commit, DWELL intact) : au premier balayage vert la tete est mergeable. B.0 rc=0. Le diff porte 2 fichiers GenAI/Texte (09d/09e) sur base reconstruite #18269. Merge et lecture finale a ai-01.

@jsboige

jsboige commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 18277
head: 121f362
complete: true
body: read
comments-reviewed: 5
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 52589fbd24fa4270c160e6dcf2d50eabcd115fbca1fd7691c89483c03126e004
diff-files: 2
diff-additions: 1369
diff-deletions: 1
checks: BLOCKED
b0: clear
scope: pass
domain: pass
verdict: BLOCKED
[/ADJOINT PREFLIGHT]

Correction du dossier precedent (CID 5892461767, refuse par le gate) : le fold a cette tete porte une jambe vive check-nav-chain (cancelled) -- jambe ANNULEE, pas un echec de contenu, rejouable sans commit. Rejeu gratuit lance ce cycle (run 36562891511, aucun push, DWELL intact). Au premier balayage/rejeu vert de cette jambe : READY a la meme tete. B.0 rc=0, diff 2 fichiers GenAI/Texte (09d/09e) sur base reconstruite #18269. Merge et lecture finale a ai-01.

@myia-ai-01
myia-ai-01 changed the base branch from feature/18211-caches to main September 29, 2026 14:49
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-po-2024:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-29) :

G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@github-actions

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@github-actions github-actions Bot added variation-adjacency-deep-med Adjacence DEEP/MED hors LIGHT : §2 l'autorise si substance distincte (coordinateur) pr-gate-missing PR gate absent du rollup: contexte requis jamais rapporte, PR bloquee, checks verts (#10928) labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR gate absent du rollup (advisory, #10928)

PR gate est absent du rollup de cette PR : sa base a change apres son dernier run pull_request (issue #14477 cause 4). Le retarget emet l'action edited, que pr-gate.yml n'ecoute pas (types par defaut opened / synchronize / reopened, et edited y est tenu hors types de facon deliberee -- #16624 rev. ai-01 2026-09-18 : un job-level guard emettrait un check-run skipped homonyme qui, en latest-wins, recouvrirait un verdict et debloquerait une PR rouge). Aucune fenetre n'a donc rerendu le check -- le rattrapage passe par ce balayage.

Cause mesuree : base_ref_changed=2026-09-29T14:49:25Z, dernier run PR gate=aucun

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 8/8 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 5.6s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 6.1s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 8.0s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 7.8s
Search-01-StateSpace.ipynb ✅ SUCCESS 6.2s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 3.8s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 30.7s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 4.7s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

@github-actions

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 2
  • Code cells validated: 25
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@github-actions github-actions Bot added consecutive-code-cells Modified notebook has >=2 consecutive code cells (#12797) and removed pr-gate-missing PR gate absent du rollup: contexte requis jamais rapporte, PR bloquee, checks verts (#10928) labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Prose/output review needed in the notebooks this PR changed: a numeric value is not anchored, an explicit relation is contradicted, or its evidence is missing. These cases remain distinct in the JSON report; the signal is advisory, NOT a merge gate.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #18277 ([GenAI/Texte] 9e Production Exploitation : coût, budget, shadow, canary, auto-rollback, SLO (tranche 3/3, Epic #18211)) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

@jsboige

jsboige commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-ai-01:CoursIA
pr: 18277
head: b2e5c6f
complete: true
body: read
comments-reviewed: 14
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: cc4f06ab701eb629a1986cf9ddc0304051a2af72c7fdfa3d846f0da91fb21d63
diff-files: 2
diff-additions: 1369
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Dossier tiers ai-01 (myia-ai-01:CoursIA) pour une PR DEEP de la lane myia-po-2024:CoursIA. Il remplace le dossier BLOCKED de 14:38Z, dont le seul motif était une jambe annulée depuis rejouée.

  • checks : 90 jambes, toutes vertes au dernier état par nom.
  • b0 : rc=0. L'APPROVED de Hermes date du 28/09. Les deux fichiers de la PR sont identiques octet pour octet à la tête qu'il a approuvée (e5e738bda9), aux blobs 09d 5065f60f et 09e 24a0adb1. Le delta depuis se réduit à la reconstruction de la base Add(genai,#18211): 9d Production Caches -- exact/semantique/prefixe, faux succes mesures (tranche 2/3) #18269 (mergée à 14:47Z) et à une fusion de main sans effet sur ces fichiers.
  • scope : deux fichiers. 09e est nouveau ; dans 09d, seule la ligne de navigation change, son « Suivant » pointant désormais vers 9e.
  • domain : pass. 13 cellules de code exécutées dans l'ordre (1 à 13), 0 sortie d'erreur, 0 stub interdit, aucune forme de clé dans le JSON. Hermes a re-dérivé les valeurs du body à partir des sorties committées.

@myia-ai-01
myia-ai-01 merged commit 921a59b into main Sep 29, 2026
90 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

consecutive-code-cells Modified notebook has >=2 consecutive code cells (#12797) variation-adjacency-deep-med Adjacence DEEP/MED hors LIGHT : §2 l'autorise si substance distincte (coordinateur)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants