Skip to content

Commit e3c72c4

Browse files
Martossienclaude
andcommitted
feat(correction): réancrer la synthèse sur le SRT corrigé, sans passe supplémentaire
La synthèse livrée dans le Word était rédigée sur `summary/quick_transcript.txt` — la transcription RAPIDE, produite AVANT la correction — et n'était jamais réalignée sur le SRT qu'on livre à côté. Un ré-résumé autonome coûterait ≈ 1× la durée de l'audio (0,94× mesuré sur 122 runs, 345 s sur un extrait de 5 min). La passe de correction est la seule qui réunit déjà tout : elle relit l'intégralité du SRT par sous-agents, et elle reçoit déjà `job_context.yaml`, donc les participants validés et l'animateur. Le réancrage n'y coûte que la rédaction — **mesuré : 281 s contre 271,5 s, soit +9,5 s (+3,5 %)**. Garde-fous, parce que le SRT reste l'artefact critique de cette phase : - **ordonné, pas parallèle** : la consigne dit « ENSUITE SEULEMENT », une fois `transcription_corrigee.srt` terminé — un agent à qui on demande deux choses de front fait moins bien les deux ; - **best-effort** : pas de fichier rendu ⇒ la synthèse existante est conservée et la correction reste un succès ; - **le prompt EXIGE, le code VÉRIFIE** (même doctrine que la parité de segments du SRT) : longueur dans la bande 0,90–1,10, aucune ligne de SRT dans le fichier, sinon le texte est écarté avec la raison au journal ; - **l'humain est souverain** : si la synthèse de l'étape 4 diffère du préremplissage, elle a été éditée — on ne la réécrit pas, et on ne demande même pas le travail à la LLM (coût nul, risque nul). Vérifié en réel, E2E web complet sur un extrait de réunion : - la synthèse réancrée passe la garde (1377 → 1377 caractères) et est persistée ; - preuve de propagation : un sigle validé au lexique sous une autre graphie est appliqué au SRT par la correction **et suit dans la synthèse livrée** — ce qui était impossible tant qu'elle restait figée sur la transcription rapide. Règle répliquée à l'identique dans configs/prompts/{en,de,es,it}. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent f26009b commit e3c72c4

12 files changed

Lines changed: 376 additions & 12 deletions

File tree

configs/prompts/correction_prompt.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,39 @@ sera rejeté.)
287287

288288
---
289289

290+
## 8bis. Réancrage de la synthèse — SEULEMENT si `synthese_a_reancrer.md` est fourni
291+
292+
Fichier absent (cas fréquent) ⇒ **ignorer entièrement cette section**.
293+
294+
La synthèse livrée à l'utilisateur a été rédigée sur une transcription RAPIDE, produite
295+
AVANT ta correction. Tu viens de relire l'intégralité du SRT : tu es le seul à pouvoir la
296+
réancrer sur le texte réellement livré, et cela ne doit rien coûter d'autre que la
297+
rédaction.
298+
299+
**Uniquement après** que `transcription_corrigee.srt` est terminé et vérifié :
300+
301+
1. Lire `synthese_a_reancrer.md`.
302+
2. Corriger **ce que le SRT corrigé contredit** : noms, chiffres, dates, termes, une
303+
affirmation qui reposait sur une erreur de transcription.
304+
3. Si `job_context.yaml` marque un participant `is_animator: true`, c'est un **fait
305+
validé par l'humain** : sers-t'en comme **fil de structure** (ordre du jour,
306+
transitions, points mis en décision, gestion du temps) et attribue-lui l'animation.
307+
Il n'a **aucune autorité de contenu supplémentaire** : les faits de chaque locuteur
308+
pèsent à égalité, l'autorité sur un sujet revient à celui qui le porte, et un temps de
309+
parole élevé ne gonfle pas sa place dans la synthèse.
310+
4. Écrire `summary_reancree.md` — la synthèse rédigée SEULE, aucun autre bloc, aucune
311+
ligne de SRT.
312+
313+
**Contraintes, aussi strictes que pour le SRT** : tu ne re-résumes pas. Même longueur
314+
(ratio 0.90–1.10 avec la synthèse fournie), même structure, **aucun point supprimé**,
315+
rien d'ajouté qui ne soit dans le SRT corrigé. Le système vérifie ce ratio et rejette le
316+
fichier sinon.
317+
318+
**En cas de doute, n'écris pas le fichier** : la synthèse existante sera conservée. Une
319+
absence ne coûte rien, une dérive coûte un compte rendu.
320+
321+
---
322+
290323
## 9. Déroulé d'exécution
291324

292325
1. Lister le répertoire de travail avec Bash.

configs/prompts/de/correction_prompt.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,40 @@ zurückgewiesen.)
292292

293293
---
294294

295+
## 8bis. Neuverankerung der Zusammenfassung — NUR wenn `synthese_a_reancrer.md` vorliegt
296+
297+
Datei nicht vorhanden (der Normalfall) ⇒ **diesen Abschnitt vollständig überspringen**.
298+
299+
Die an die Nutzenden gelieferte Zusammenfassung wurde auf einer SCHNELLEN Transkription
300+
verfasst, die VOR deiner Korrektur entstand. Du hast soeben das gesamte SRT erneut
301+
gelesen: nur du kannst sie auf den tatsächlich gelieferten Text neu verankern, und das
302+
darf nichts kosten außer dem Schreiben.
303+
304+
**Erst nachdem** `transcription_corrigee.srt` fertig und geprüft ist:
305+
306+
1. `synthese_a_reancrer.md` lesen.
307+
2. Korrigiere, **was das korrigierte SRT widerlegt**: Namen, Zahlen, Daten, Begriffe,
308+
jede Aussage, die auf einem Transkriptionsfehler beruhte.
309+
3. Markiert `job_context.yaml` eine Person mit `is_animator: true`, ist das eine
310+
**vom Menschen bestätigte** Tatsache: nutze sie als **roten Faden der Struktur**
311+
(Tagesordnung, Übergänge, zur Entscheidung gestellte Punkte, Zeitmanagement) und
312+
schreibe ihr die Moderation korrekt zu. Sie hat **keine zusätzliche inhaltliche
313+
Autorität**: die Fakten aller Sprechenden wiegen gleich, die Autorität zu einem Thema
314+
liegt bei der Person, die es vertritt, und eine hohe Redezeit vergrößert ihren Platz
315+
in der Zusammenfassung nicht.
316+
4. `summary_reancree.md` schreiben — NUR die verfasste Zusammenfassung, kein weiterer
317+
Block, keine SRT-Zeilen.
318+
319+
**Auflagen, so streng wie beim SRT**: Du fasst nicht neu zusammen. Gleiche Länge
320+
(Verhältnis 0,90–1,10 zur gelieferten Zusammenfassung), gleiche Struktur, **kein Punkt
321+
entfernt**, nichts hinzugefügt, was nicht im korrigierten SRT steht. Das System prüft
322+
dieses Verhältnis und weist die Datei andernfalls zurück.
323+
324+
**Im Zweifel die Datei nicht schreiben**: die bestehende Zusammenfassung bleibt erhalten.
325+
Ein Fehlen kostet nichts, eine Abweichung kostet ein Protokoll.
326+
327+
---
328+
295329
## 9. Ausführungsablauf
296330

297331
1. Das Arbeitsverzeichnis mit Bash auflisten.

configs/prompts/en/correction_prompt.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,37 @@ segment count and this ratio: a non-conforming file will be rejected.)
268268

269269
---
270270

271+
## 8bis. Re-anchoring the summary — ONLY if `synthese_a_reancrer.md` is provided
272+
273+
File absent (the common case) ⇒ **skip this section entirely**.
274+
275+
The summary delivered to the user was written on a FAST transcription produced BEFORE
276+
your correction. You have just re-read the whole SRT: you are the only one who can
277+
re-anchor it on the text actually delivered, and it must cost nothing beyond the writing.
278+
279+
**Only after** `transcription_corrigee.srt` is finished and verified:
280+
281+
1. Read `synthese_a_reancrer.md`.
282+
2. Fix **whatever the corrected SRT contradicts**: names, figures, dates, terms, any
283+
statement that rested on a transcription error.
284+
3. If `job_context.yaml` marks a participant with `is_animator: true`, this is a fact
285+
**validated by a human**: use it as a **structural thread** (agenda, transitions,
286+
items put to a decision, time management) and attribute the facilitation correctly.
287+
It carries **no additional authority over content**: every speaker's facts weigh
288+
equally, authority on a topic belongs to whoever carries it, and a high speaking time
289+
does not inflate their place in the summary.
290+
4. Write `summary_reancree.md` — the written summary ONLY, no other block, no SRT lines.
291+
292+
**Constraints, as strict as for the SRT**: you do not re-summarise. Same length (ratio
293+
0.90–1.10 against the provided summary), same structure, **no item removed**, nothing
294+
added that is not in the corrected SRT. The system checks that ratio and rejects the
295+
file otherwise.
296+
297+
**When in doubt, do not write the file**: the existing summary will be kept. An absence
298+
costs nothing, a drift costs a report.
299+
300+
---
301+
271302
## 9. Execution flow
272303

273304
1. List the working directory with Bash.

configs/prompts/es/correction_prompt.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,38 @@ conforme será rechazado.)
298298

299299
---
300300

301+
## 8bis. Reanclaje del resumen — SOLO si se proporciona `synthese_a_reancrer.md`
302+
303+
Archivo ausente (el caso habitual) ⇒ **omitir por completo esta sección**.
304+
305+
El resumen entregado al usuario se redactó sobre una transcripción RÁPIDA, producida
306+
ANTES de tu corrección. Acabas de releer todo el SRT: eres el único que puede reanclarlo
307+
en el texto realmente entregado, y no debe costar nada más que la redacción.
308+
309+
**Solo después** de que `transcription_corrigee.srt` esté terminado y verificado:
310+
311+
1. Leer `synthese_a_reancrer.md`.
312+
2. Corregir **lo que el SRT corregido contradiga**: nombres, cifras, fechas, términos,
313+
cualquier afirmación que se apoyara en un error de transcripción.
314+
3. Si `job_context.yaml` marca a un participante con `is_animator: true`, es un hecho
315+
**validado por el humano**: úsalo como **hilo de estructura** (orden del día,
316+
transiciones, puntos sometidos a decisión, gestión del tiempo) y atribúyele la
317+
animación. No tiene **ninguna autoridad adicional sobre el fondo**: los hechos de cada
318+
locutor pesan por igual, la autoridad sobre un tema corresponde a quien lo lleva, y un
319+
tiempo de palabra elevado no aumenta su lugar en el resumen.
320+
4. Escribir `summary_reancree.md` — SOLO el resumen redactado, ningún otro bloque,
321+
ninguna línea de SRT.
322+
323+
**Restricciones, tan estrictas como para el SRT**: no vuelves a resumir. Misma longitud
324+
(ratio 0,90–1,10 respecto al resumen proporcionado), misma estructura, **ningún punto
325+
suprimido**, nada añadido que no esté en el SRT corregido. El sistema verifica ese ratio
326+
y rechaza el archivo en caso contrario.
327+
328+
**En caso de duda, no escribas el archivo**: se conservará el resumen existente. Una
329+
ausencia no cuesta nada, una deriva cuesta un acta.
330+
331+
---
332+
301333
## 9. Desarrollo de la ejecución
302334

303335
1. Listar el directorio de trabajo con Bash.

configs/prompts/it/correction_prompt.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,39 @@ file non conforme sarà respinto.)
290290

291291
---
292292

293+
## 8bis. Riancoraggio della sintesi — SOLO se `synthese_a_reancrer.md` è fornito
294+
295+
File assente (il caso abituale) ⇒ **ignorare del tutto questa sezione**.
296+
297+
La sintesi consegnata all'utente è stata redatta su una trascrizione RAPIDA, prodotta
298+
PRIMA della tua correzione. Hai appena riletto l'intero SRT: sei l'unico a poterla
299+
riancorare al testo effettivamente consegnato, e non deve costare nulla oltre la
300+
redazione.
301+
302+
**Solo dopo** che `transcription_corrigee.srt` è terminato e verificato:
303+
304+
1. Leggere `synthese_a_reancrer.md`.
305+
2. Correggere **ciò che l'SRT corretto contraddice**: nomi, cifre, date, termini, ogni
306+
affermazione che poggiava su un errore di trascrizione.
307+
3. Se `job_context.yaml` contrassegna un partecipante con `is_animator: true`, è un fatto
308+
**convalidato dall'essere umano**: usalo come **filo della struttura** (ordine del
309+
giorno, transizioni, punti messi in decisione, gestione del tempo) e attribuiscigli
310+
correttamente l'animazione. Non ha **alcuna autorità aggiuntiva sul merito**: i fatti
311+
di ogni locutore pesano allo stesso modo, l'autorità su un argomento spetta a chi lo
312+
porta, e un tempo di parola elevato non gonfia il suo posto nella sintesi.
313+
4. Scrivere `summary_reancree.md` — SOLO la sintesi redatta, nessun altro blocco, nessuna
314+
riga di SRT.
315+
316+
**Vincoli, severi quanto per l'SRT**: non riassumi di nuovo. Stessa lunghezza (rapporto
317+
0,90–1,10 rispetto alla sintesi fornita), stessa struttura, **nessun punto soppresso**,
318+
nulla di aggiunto che non sia nell'SRT corretto. Il sistema verifica tale rapporto e
319+
altrimenti rifiuta il file.
320+
321+
**Nel dubbio, non scrivere il file**: la sintesi esistente sarà conservata. Un'assenza
322+
non costa nulla, una deriva costa un verbale.
323+
324+
---
325+
293326
## 9. Svolgimento dell'esecuzione
294327

295328
1. Elencare la directory di lavoro con Bash.

docs/DATA_MODEL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ Assemblé par `JobContextBuilder.build()` à partir de `meeting_context.json`, `
771771

772772
Chaque participant y porte `is_animator: true` **seulement** si la case « ★ Animateur » a été cochée à l'étape 5 (clé absente sinon : une réunion sans animateur laisse le contexte strictement identique). C'est la seule information du contexte qui soit un choix humain explicite plutôt qu'une déduction ; le prompt de résumé s'en sert comme fil de structure, jamais comme autorité de contenu.
773773

774+
La phase de correction s'en sert aussi pour **réancrer la synthèse** : elle relit déjà l'intégralité du SRT, elle reçoit déjà le contexte validé (dont l'animateur), et la synthèse livrée avait été rédigée sur la transcription RAPIDE d'avant correction. Le texte réancré remplace `meeting_context["summary"]` **seulement** s'il est resté identique au préremplissage de l'étape 4 (l'édition humaine est souveraine) et s'il tient dans la bande de longueur 0,90–1,10 — sinon la synthèse existante est conservée.
775+
774776
Ce fichier est construit après le mapping des locuteurs puis reconstruit après la sauvegarde du lexique afin d'inclure `session_lexicon.json`. Il n'existe pas encore au moment du résumé ; le résumé LLM reçoit donc un fichier dédié `summary/diarization_context.md` pour les données pyannote disponibles à cette étape.
775777

776778
### audio_scene.json

quality_baseline.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@
231231
"transcria.workflow.gpu_phase": 8,
232232
"transcria.workflow.multi_stt_review": 1,
233233
"transcria.workflow.phases": 9,
234-
"transcria.workflow.phases.correction": 7,
234+
"transcria.workflow.phases.correction": 8,
235235
"transcria.workflow.phases.diarization": 7,
236236
"transcria.workflow.phases.export": 4,
237237
"transcria.workflow.phases.final_review": 6,

tests/test_animator.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from transcria.jobs.filesystem import JobFilesystem
2323
from transcria.jobs.models import Job, JobState
2424
from transcria.web.pages_routes import _apply_animator_suggestion
25+
from transcria.workflow.phases.correction import reanchored_summary_error, summary_to_reanchor
2526
from transcria.workflow.animator_hint import animator_from_roles, suggest_animator
2627

2728
ROOT = Path(__file__).resolve().parents[1]
@@ -181,3 +182,70 @@ def test_le_bouton_ne_coche_pas_d_office(self):
181182
assert "s.get('animator_suggested')" in template
182183
assert "{% if s.get('animator_suggested') %} checked" not in template
183184
assert "W.applyAnimatorSuggestion" in js
185+
186+
187+
class TestReancrageSynthese:
188+
"""Lot 1bis — la synthèse est réancrée sur le SRT corrigé PAR LA PASSE QUI LE RELIT.
189+
190+
Constat qui motive le lot : la synthèse livrée est rédigée sur `quick_transcript.txt`,
191+
la transcription RAPIDE d'avant correction — jamais sur le SRT qu'on livre à côté. La
192+
passe de correction est la seule qui relit tout le SRT ET reçoit déjà le contexte
193+
validé (animateur compris) : le réancrage n'y coûte que la génération, contre une
194+
passe complète (≈ 1× la durée de l'audio) pour un ré-résumé autonome.
195+
"""
196+
197+
_HEADINGS = ["## Synthèse", "## Summary"]
198+
199+
def test_la_synthese_non_editee_part_au_reancrage(self):
200+
ctx = {"summary_llm": "# Résumé\n\n## Synthèse\nDeux points discutés.\n\n## Termes\n(aucun)",
201+
"summary": "Deux points discutés."}
202+
203+
assert summary_to_reanchor(ctx, self._HEADINGS) == "Deux points discutés."
204+
205+
def test_une_synthese_EDITEE_par_l_humain_n_est_jamais_reecrite(self):
206+
"""Et on ne la demande même pas à la LLM : coût nul, risque nul."""
207+
ctx = {"summary_llm": "## Synthèse\nDeux points discutés.",
208+
"summary": "Deux points discutés, dont le budget que j'ai ajouté."}
209+
210+
assert summary_to_reanchor(ctx, self._HEADINGS) == ""
211+
212+
def test_sans_synthese_il_n_y_a_rien_a_reancrer(self):
213+
assert summary_to_reanchor({}, self._HEADINGS) == ""
214+
assert summary_to_reanchor({"summary_llm": ""}, self._HEADINGS) == ""
215+
216+
def test_la_garde_rejette_une_synthese_qui_fond(self):
217+
"""Même doctrine que le SRT : le prompt EXIGE, le code VÉRIFIE. C'est la dérive
218+
observée quand on laisse un modèle « réécrire » librement."""
219+
precedente = "x" * 1000
220+
221+
assert reanchored_summary_error(precedente, "x" * 400) is not None
222+
assert reanchored_summary_error(precedente, "x" * 1500) is not None
223+
assert reanchored_summary_error(precedente, "x" * 950) is None
224+
225+
def test_la_garde_rejette_un_fichier_qui_n_est_pas_une_synthese(self):
226+
"""Vécu ailleurs : l'agent recrache des lignes de SRT dans le mauvais fichier."""
227+
srt = "1\n00:00:01,000 --> 00:00:04,000\nBonjour."
228+
229+
assert "SRT" in (reanchored_summary_error("x" * 60, srt) or "")
230+
assert reanchored_summary_error("x" * 60, " ") is not None
231+
232+
def test_la_regle_est_repliquee_dans_les_cinq_prompts(self):
233+
"""Une consigne ajoutée au FR et oubliée ailleurs = une fonctionnalité qui
234+
n'existe que pour les livrables français."""
235+
fr = (ROOT / "configs/prompts/correction_prompt.txt").read_text(encoding="utf-8")
236+
assert "synthese_a_reancrer.md" in fr and "summary_reancree.md" in fr
237+
for loc in ("en", "de", "es", "it"):
238+
texte = (ROOT / f"configs/prompts/{loc}/correction_prompt.txt").read_text(encoding="utf-8")
239+
assert "synthese_a_reancrer.md" in texte, f"{loc} : entrée absente"
240+
assert "summary_reancree.md" in texte, f"{loc} : sortie absente"
241+
assert "is_animator" in texte, f"{loc} : règle animateur absente"
242+
243+
def test_le_reancrage_est_demande_APRES_le_srt(self):
244+
"""Le SRT est l'artefact critique : la re-synthèse est une étape finale, jamais un
245+
second objectif mené de front (un agent à qui on demande deux choses fait moins
246+
bien les deux)."""
247+
source = (ROOT / "transcria/llm_tools/opencode_runner.py").read_text(encoding="utf-8")
248+
bloc = source.split("def run_correction(", 1)[1].split("def ", 1)[0]
249+
250+
assert "ENSUITE SEULEMENT" in bloc
251+
assert bloc.index("transcription_corrigee.srt") < bloc.index("summary_reancree.md")

transcria/context/meeting_context.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@
1212

1313

1414

15+
def synthese_section(raw_md: str, headings: list[str]) -> str:
16+
"""La seule section « Synthèse » d'un summary.md brut, sinon le markdown entier.
17+
18+
PURE : les marqueurs de section (langue-dépendants) sont fournis par l'appelant —
19+
c'est ce qui permet à la phase de correction comme au wizard de partager l'extraction
20+
sans que ce module ait à connaître le catalogue de marqueurs.
21+
"""
22+
for heading in headings:
23+
if heading and heading in raw_md:
24+
return raw_md.split(heading, 1)[1].split("\n##", 1)[0].strip()
25+
return raw_md.strip()
26+
27+
1528
class MeetingContextManager:
1629
@staticmethod
1730
def get(job: Job, jobs_dir: str) -> dict:

transcria/llm_tools/opencode_runner.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ def run_correction(
617617
lexicon_path: str,
618618
invite_path: str | None = None,
619619
output_language: str = "fr",
620+
summary_path: str | None = None,
620621
) -> dict:
621622
"""Corrige le SRT via opencode : speakers + lexique + orthographe.
622623
@@ -626,8 +627,15 @@ def run_correction(
626627
627628
``output_language`` : langue des livrables (Axe B) — prompt localisé + consigne.
628629
630+
``summary_path`` (facultatif) : la synthèse à RÉANCRER sur le SRT corrigé. La
631+
synthèse livrée est aujourd'hui rédigée sur la transcription RAPIDE, d'avant
632+
correction ; l'agent relit déjà l'intégralité du SRT ici, le réancrage ne coûte
633+
donc que la génération. Tâche BORNÉE et best-effort : pas de fichier rendu ⇒ la
634+
synthèse existante est conservée telle quelle.
635+
629636
Returns:
630-
{"success": bool, "corrected_srt": str, "report": str, "error": str}
637+
{"success": bool, "corrected_srt": str, "report": str,
638+
"rewritten_summary": str, "error": str}
631639
"""
632640
prompt_file = resolve_prompt_file(self._config, "correction_prompt.txt", output_language)
633641

@@ -658,6 +666,16 @@ def run_correction(
658666
"(2) correction_report.md — rapport Markdown uniquement, "
659667
"aucune ligne SRT dans ce fichier."
660668
)
669+
if summary_path and os.path.isfile(summary_path):
670+
# ORDRE, pas parallèle : le SRT est l'artefact critique (gardes de parité et
671+
# de ratio côté code). Le réancrage se fait APRÈS, depuis le fichier corrigé.
672+
instruction += (
673+
f" ENSUITE SEULEMENT, une fois transcription_corrigee.srt terminé : lis la "
674+
f"synthèse {summary_path} et réancre-la sur le SRT corrigé selon le § 8 du "
675+
"prompt système, puis écris un 3e fichier summary_reancree.md. Si tu ne peux "
676+
"pas le faire dans ces contraintes, n'écris pas ce fichier — le système "
677+
"conservera la synthèse existante."
678+
)
661679

662680
timeout = self._get_correction_timeout()
663681
result = self.run(instruction, prompt_file, timeout=timeout)
@@ -666,10 +684,14 @@ def run_correction(
666684

667685
corrected_file = self.work_dir / "transcription_corrigee.srt"
668686
report_file = self.work_dir / "correction_report.md"
687+
summary_file = self.work_dir / "summary_reancree.md"
688+
rewritten_summary = ""
669689
if corrected_file.is_file():
670690
corrected_srt = corrected_file.read_text(encoding="utf-8").strip()
671691
if report_file.is_file():
672692
report = report_file.read_text(encoding="utf-8").strip()
693+
if summary_file.is_file():
694+
rewritten_summary = summary_file.read_text(encoding="utf-8").strip()
673695

674696
# Recovery : si transcription_corrigee.srt est présent et non-vide, la correction
675697
# est faite quelle que soit la raison de sortie d'opencode — timeout, SIGTERM (-15),
@@ -686,6 +708,7 @@ def run_correction(
686708
"success": result["success"],
687709
"corrected_srt": corrected_srt,
688710
"report": report,
711+
"rewritten_summary": rewritten_summary,
689712
"error": result.get("error", ""),
690713
"warning": result.get("warning", ""),
691714
}

0 commit comments

Comments
 (0)