Skip to content

fix(guard,#19810): proxy CRLF serre - HUMAN seulement si prose UI web - #19812

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/19810-crlf-ui-web-proxy
Oct 8, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/19810-crlf-ui-web-proxy

Conversation

@jsboige

@jsboige jsboige commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Grain: LIGHT/guard -- lane myia-ai-01:CoursIA-2 -- prev: DEEP/research-code c.249 #19811

#19810 -- proxy CRLF serre : HUMAN seulement si prose UI web

Le proxy CRLF dans classify() (728146a, #11044/#11045, ai-01, 2026-08-15)
considerait tout corps avec \r\n comme un nit user UI web. Il attrapait les
VRAIS nits UI web (corpus USER_NIT, bullet lists, "Il reste un souci") mais
sur-firait sur les posts CLI Windows : un commentaire multi-ligne ecrit via
Path.write_text (mode texte, \n -> \r\n) devenait HUMAN sans aucun
marqueur de reserve.

Cas fondateur #19704 (2026-10-08, po-2026)

Lane po-2026 repond a une demande du coordinateur par un commentaire
multi-ligne poste via gh pr comment --body-file. Le fichier ecrit en
mode texte Windows produit du CRLF (15 \r\n constates en live). Le gate
B.0 rend BLOCKED ... 1 nit(s) non leve(s) -- le nit etant le
commentaire de la lane elle-meme
, gap 0.1 h, classifie HUMAN par la
seule presence de CRLF (aucun marqueur de reserve : CONCERN_MARKERS
= 0 hit).

Reparation mesuree : PATCH du corps en LF -> classify rend None ->
le gate rend OK ... aucun nit non leve.

Solution choisie (option 1 revisee)

classify() distingue maintenant UI-web-nit d'un artefact de transport.
Le CRLF tient HUMAN si et seulement si :

  1. live_concern (le corps porte un CONCERN_MARKERS vivant -- marqueur
    formel de reserve, pas de faux-positif possible), OU
  2. _looks_like_ui_web_nit(body) : structure de plainte UI web :
    • bullet list : \r\n\s*[-*]\s ou \r\n\s*\d+\.\s
    • phrase-repere plainte : regex couvre EN (attention, heads-up,
      warning, please, bug, wrong, broken, nit, reserve,
      souci, probleme, manque, casse, faut, ...) et FR (il va falloir, il reste, il y a, pourrais-tu, ne pas, ...)
    • couvre les 3 cas positifs du corpus (USER_NIT l.50 bullet +
      attention ; test_controle_positif_vrai_nit_user_crlf B.0 : une levee ecrite sous l'identite jsboige devient elle-meme un nit non levable (distinct de #16688) #16700 l.150
      "souci" ; test_rapport_verdict_ok_ne_flagge_pas l.248 "Verdict : OK"
      deja couvert par _HUMAN_VERDICT_RE).

Tests ajoutes (8)

test_19810_windows_cli_post_crlf_status_not_human     -- cas fondateur #19704
test_19810_windows_cli_crlf_path_sha_not_human        -- variante chemin + run
test_19810_user_nit_crlf_bullets_still_human          -- USER_NIT corpus preserve
test_19810_souci_crlf_prose_plainte_still_human       -- #16700 corpus preserve
test_19810_windows_cli_crlf_with_concern_still_human  -- live_concern bat
test_19810_lf_only_post_not_human                     -- LF inchange
test_19810_windows_cli_crlf_attention_phrase_human    -- phrase-repere plainte
test_19810_no_regression_on_existing_crlf_positive_verdict  -- Verdict : OK

Mesure

  • python -m pytest scripts/tests/test_check_unaddressed_nits.py
    483 passed, 1 skipped (+8 nouveaux tests).
  • Corpus test_check_unaddressed_nits_*.py : 9 + 8 + 9 + 10 + 15 + 14 + 8 + 6
    • 6 + 12 + 5 + 6 + 18 + 5 + 31 + 25 + 44 + 13 = 242 passed sur les
      fratries, aucune regression.

Ce que le fix ne change PAS

Cout / risque

  • Le signal UI web historique (CRLF = humain) est preserve pour les VRAIS
    nits (bullet lists, phrases plainte, marqueurs vivants).
  • Le cout faux-positif (post CLI Windows traite comme nit) retombe a 0.
  • Le seul cas marginal : un post CLI Windows qui contient un mot plainte
    (rare) reste HUMAN via _UI_WEB_NIT_PHRASE_RE. Test
    test_19810_windows_cli_crlf_attention_phrase_human couvre ce cas
    explicitement.

Liens

🤖 Generated with Claude Code

Le proxy CRLF dans classify() (728146a, #11044) considerait tout corps
avec \r\n comme un nit user UI web. Il attrapait les VRAIS nits UI web
(corpus USER_NIT, bullet lists, "Il reste un souci") mais sur-firait sur
les posts CLI Windows : un commentaire multi-ligne ecrit via
Path.write_text (mode texte, \n -> \r\n) devenait HUMAN sans aucun
marqueur de reserve.

Cas fondateur #19704 (2026-10-08, po-2026) : la lane s'est auto-bloquee
au merge-gate sur son propre commentaire, 0.1 h apres l'avoir poste,
gap = transport CRLF seul.

Fix : helper _looks_like_ui_web_nit() detecte une STRUCTURE de plainte
(bullet-list, phrase-repere plainte EN/FR). Le CRLF proxy tient HUMAN
seulement si live_concern OU cette structure est presente.

Tests : 8 cas (5 cas Windows CLI non-HUMAN, 3 cas UI web preserves),
483 passed, 1 skipped (test_check_unaddressed_nits). Corpus 16700,
14850, 15651, 15837, 15920, 16103, 16799, 16876, 18149, 18336, 18937,
19132, adjoint_dossier, dismissal, followup, hold, mention, unevaluated
: tous verts.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

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).

@jsboige

jsboige commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 19812
head: 4cff3e4
complete: true
body: read
comments-reviewed: 1
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: e0a7a839aeeba8007626619d1afb02ff4f6d91e33af511cae8ab47515cf04b05
diff-files: 2
diff-additions: 142
diff-deletions: 1
checks: BLOCKED
b0: clear
scope: pass
domain: pass
verdict: BLOCKED
organ: check_adjoint_prevalidation.py
organ-command: python scripts/check_adjoint_prevalidation.py --derive-verdict 19812
organ-rc: 3
[/ADJOINT PREFLIGHT]

@jsboige

jsboige commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 19812
head: 4cff3e4
complete: true
body: read
comments-reviewed: 2
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: f8e8f2f3d0cc0c8f6fcf933377bf173f4270a043ed3c2cce1f4d2af9e36103f5
diff-files: 2
diff-additions: 142
diff-deletions: 1
checks: BLOCKED
b0: clear
scope: pass
domain: pass
verdict: BLOCKED
organ: check_adjoint_prevalidation.py
organ-command: python scripts/check_adjoint_prevalidation.py --derive-verdict 19812
organ-rc: 3
[/ADJOINT PREFLIGHT]

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #19812 (fix(guard,#19810): proxy CRLF serre - HUMAN seulement si prose UI web) 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 Oct 8, 2026 •

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-ai-01:CoursIA
pr: 19812
head: 4cff3e4
complete: true
body: read
comments-reviewed: 4
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 4ca97fd561064fa1824db133a893463762a63dad00c429aa19d9d93d20260a70
diff-files: 2
diff-additions: 142
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: pass
domain: not-applicable
verdict: READY
supersedes: 3
supersedes-why: le dossier BLOCKED precedent attestait un etat de jambes ou de levees depasse ; a la meme tete, la derivation live rend checks verts, B.0 clear
organ: check_adjoint_prevalidation.py
organ-command: python scripts/check_adjoint_prevalidation.py --derive-verdict 19812
organ-rc: 0
[/ADJOINT PREFLIGHT]

Derivation live READY a la tete vive : le dossier BLOCKED anterieur attestait des jambes alors en cours ; jambes latest-wins vertes, B.0 clear, aucun thread non resolu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants