Repository navigation
feat(probas,#16620): Infer-5 — effets naturels NDE/NIE calculés, raccourcis CDE corrigés (P5a) #8427
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Translation Drift Check | |
| # Purpose: DETECT (non-blocking, read-only) when a notebook source or one of its | |
| # translations drifts out of sync with the translation CSV | |
| # (translations/<famille>/<série>.csv, Epic #4957 / #1650). The CSV is the source | |
| # of truth for the multilingual alignment maintained by extract_cells_to_csv.py. | |
| # | |
| # This job is intentionally NON-BLOCKING and READ-ONLY — same philosophy as | |
| # catalog-drift.yml. It surfaces drift as a notice annotation so reviewers see | |
| # it, but never writes to a branch and never fails the PR gate. The actual | |
| # re-translation is PROPOSED by this check but EXECUTED manually by an agent | |
| # (running the Argumentum datasetupdater motor on flagged rows, #4957 §3) — | |
| # never an auto-commit LLM in CI. | |
| # | |
| # See #4957 (infra design) and #1650 (multilingual translation epic). | |
| on: | |
| pull_request: | |
| branches: [ main ] | |
| paths: | |
| - 'MyIA.AI.Notebooks/**/*.ipynb' | |
| - 'translations/**' | |
| - 'scripts/translation/**' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: translation-drift-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| translation-drift: | |
| name: "Translation drift (read-only)" | |
| # Route vers la jambe Linux auto-hebergee (#13378 tranche 5, decision ai-01 | |
| # 2026-09-02) : garde Python pur, sans secret. La garde same-repo ci-dessous | |
| # saute les PRs de fork (pr_gate.py compte `skipped` comme OK) : aucun code de | |
| # fork n'atteint le runner. Retour arriere = revert de la PR. | |
| runs-on: [self-hosted, coursia-ephemeral, coursia-linux] | |
| if: github.event.pull_request.head.repo.full_name == null || github.event.pull_request.head.repo.full_name == github.repository | |
| steps: | |
| - name: Checkout PR | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| filter: blob:none | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| # Non-blocking: --check always exits 0. Drift is surfaced as a notice | |
| # annotation + JSON report. Pre-T1 (no translations/ committed yet) the | |
| # script reports "0 CSV, nothing to verify" and the job is green. | |
| - name: Detect translation drift | |
| id: drift | |
| run: | | |
| if [ ! -d translations ]; then | |
| echo "::notice title=Translation drift (informational)::No translations/ directory yet (pre-T1 phase, #4957). Nothing to verify." | |
| echo "drift=none" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # Capture stdout (JSON report) and stderr (diagnostics) separately. | |
| # A drift detector that crashes must announce itself, NOT stay silent | |
| # behind 2>/dev/null and report a false "all in sync". | |
| STDERR_FILE="$(mktemp)" | |
| REPORT="$(python scripts/translation/check_translation_sync.py translations --check --repo-root . 2>"$STDERR_FILE")" | |
| SCRIPT_EXIT=$? | |
| STDERR_CONTENT="$(cat "$STDERR_FILE")" | |
| rm -f "$STDERR_FILE" | |
| # Distinguish a script crash from a legitimately empty report. | |
| if [ "$SCRIPT_EXIT" -ne 0 ] || ! echo "$REPORT" | python -c 'import sys,json; json.load(sys.stdin)' 2>/dev/null; then | |
| echo "::warning title=Translation drift check (broken)::The drift detector itself failed (exit $SCRIPT_EXIT, non-JSON stdout). A false 'all in sync' cannot be trusted. Investigate the job log. Stderr: $STDERR_CONTENT" | |
| echo "drift=broken" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| COUNT="$(echo "$REPORT" | python -c 'import sys,json; print(json.load(sys.stdin)["anomaly_count"])')" | |
| # Fill rate by target language (#6949 point 1): a drift count alone is | |
| # non-informative while 0% of cells carry a translation. The check | |
| # script already prints this on stderr and in the JSON report; here we | |
| # surface it into the PR annotation so a SRC_DRIFT=0 on a 0%-translated | |
| # table can no longer read as "up to date" at the merge gate (#8678: | |
| # a bare count perishes, a count plus its denominator self-contradicts). | |
| FILL_SUMMARY="$(echo "$REPORT" | python -c 'import sys,json; sys.path.insert(0,"scripts/translation"); from check_perimeter import TARGET_LANGS as t; gf=json.load(sys.stdin).get("fill_rate",{}).get("global",{}); print(" ".join("%s=%s%%" % (l, gf.get(l,{}).get("pct",0.0)) for l in t))')" | |
| ANY_FILLED="$(echo "$REPORT" | python -c 'import sys,json; sys.path.insert(0,"scripts/translation"); from check_perimeter import TARGET_LANGS as t; gf=json.load(sys.stdin).get("fill_rate",{}).get("global",{}); print(any(gf.get(l,{}).get("filled",0)>0 for l in t))')" | |
| if [ "$COUNT" = "0" ]; then | |
| if [ "$ANY_FILLED" = "True" ]; then | |
| echo "::notice title=Translation sync::All translation CSVs in sync with notebooks. No drift. (fill rate: $FILL_SUMMARY)" | |
| else | |
| echo "::notice title=Translation sync (caveat)::Drift count is 0, BUT no translation is deposited in ANY target language ($FILL_SUMMARY). 'No drift' does NOT mean 'translated' here — the drift count is non-informative while the fill rate is 0%. Re-translation is gated on the T3 motor GO (#6949 point 2)." | |
| fi | |
| echo "drift=none" >> "$GITHUB_OUTPUT" | |
| else | |
| SUMMARY="$(echo "$REPORT" | python -c 'import sys,json; from collections import Counter; d=json.load(sys.stdin); print(", ".join(f"{v}={n}" for v,n in Counter(a["verdict"] for a in d["anomalies"]).items()))')" | |
| echo "::notice title=Translation drift (informational)::$COUNT drift(s) detected ($SUMMARY). Fill rate: $FILL_SUMMARY. This does NOT block the PR. Re-translation is proposed here but executed manually by an agent (Argumentum motor, #4957 §3). See JSON report in the job log." | |
| echo "$REPORT" | |
| echo "drift=detected" >> "$GITHUB_OUTPUT" | |
| fi | |
| # This job is always green. Drift is surfaced as a notice annotation only. | |
| - name: Done (non-blocking, read-only) | |
| run: echo "Translation drift check complete (non-blocking, read-only)." |