Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5e91a6d
fix(closure-gate): le gabarit rend l'item d'acceptation sous acceptance:
jsboige Sep 30, 2026
977eb66
vibe(#17636): relay c15 — w8 md prose (12 files + 24 attestations KEE…
jsboige Sep 30, 2026
932550d
Add: EPIC reconnue par label OU prefix titre [EPIC] dans le sweep del…
jsboige Sep 30, 2026
8858fb0
vibe(#17636): relay c19 — w8 md prose docs (5 files incl. 2 rescued r…
jsboige Sep 30, 2026
28aa519
Fix(Tweety): 5 notebooks C# sous Linux et macOS, RID IKVM derive de l…
jsboige Sep 30, 2026
ce1acd8
Add: epic_body_staleness branche au balayage quotidien EPIC, advisory…
jsboige Sep 30, 2026
28fd400
fix(guard): une URL web n'est pas un chemin de la machine d'execution…
jsboige Sep 30, 2026
c47fc01
feat(lean,#17978): Lean-15d -- visite guidee visuelle des abstraction…
jsboige Sep 30, 2026
600586b
fix(notebook-python,#17529): GameTheory-15 section 4 -- confronter Of…
jsboige Sep 30, 2026
3a2abe9
Add: iit_lean — premier lake IIT, proxy relationnel de coupe (Phase 1…
jsboige Sep 30, 2026
68abe36
feat(ict,#18147): ICT-36 -- digerer 3 sections et ajouter 3 exercices…
jsboige Sep 30, 2026
fad73c6
refactor(geometry,#18601): re-parenting SymbolicAI/Geometry/ -> Symbo…
jsboige Sep 30, 2026
19687db
feat(notebook-tools,#18411): instrument de census couverture + delta …
jsboige Sep 30, 2026
869d1a3
fix(prose,#17636): relay burst w4 c6 — Lean-10-LeanDojo + 04-2-Transc…
jsboige Sep 30, 2026
2fec54f
docs(vllm-story): episode 3 — late Aug security & recovery, September…
jsboige Sep 30, 2026
9a92bee
feat(guard,#18606): carve-out meta-notes par tag metadata (voie 2, de…
jsboige Sep 30, 2026
32905f1
Add: critere de sortie de docs/archive/ - 3 voies + interdiction d'en…
jsboige Sep 30, 2026
5e9e34e
vibe(#17636): relay c18 — w8 md prose docs (33 files, ledgers/genai-i…
jsboige Sep 30, 2026
0154ead
vibe(#17636): relay c20 — w8 md prose docs (14 files, suivis genai-im…
jsboige Sep 30, 2026
2bfd5a1
fix(probas,#18401): PyMC-01 kernelspec pymc-arviz11 + API arviz 1.1 (…
jsboige Sep 30, 2026
a2f8e85
docs(hygiene,#18493): scan + classification des compteurs litteraux c…
jsboige Sep 30, 2026
d015e14
fix(argu,#18434): correct provenance for Argumentation-07b bus port (…
jsboige Sep 30, 2026
b6f88f7
Fix(GenAI): 06-KernelMemory-InProcess sous Linux et macOS, backend na…
jsboige Sep 30, 2026
a8afb01
fix(argu,#18391): build DETECTEUR_SOPHISMES from taxonomy (38 vs 4) (…
jsboige Sep 30, 2026
d99cb3d
fix(genai-video,#18512): porter video_helpers + carnets 04-1/04-4 ver…
jsboige Sep 30, 2026
774fe98
fix(prose,#17636): relay burst w4 — Lean-16f + Planners-3-Csharp + TA…
jsboige Sep 30, 2026
a8d6111
fix(probas,#18406): rename Infer-20 → Quotients-Fibres — alignment th…
jsboige Oct 1, 2026
f4edd41
fix(picker,#18203): weight() mesure l'attente sur la derniere livrais…
jsboige Oct 1, 2026
7a8d40b
Rename(genai-texte,#18212): 23_Constrained_Decoding -> 03c_Constraine…
jsboige Oct 1, 2026
1f5519a
docs(argumentation,#18476): ancrage de provenance 08d -- chemins du t…
jsboige Oct 1, 2026
ef02880
fix(prose,#17636): relay burst w4 c11 -- 3.9e-Compression-Quantizatio…
jsboige Oct 1, 2026
5cab0a5
fix(ci,#12853): arXiv guard path filter covers every registry noteboo…
myia-ai-01 Oct 1, 2026
e360297
fix(lanes): myia-ai-01:CoursIA-2 devient une lane worker (picker, dos…
jsboige Oct 1, 2026
d581ca9
fix(planners,#18578): nav manquante sur les twins C# 5-Heuristics et …
jsboige Oct 1, 2026
55f3b5b
fix(planners,#18578): repair 03-Advanced C# nav chain (7/8-C# orphans…
jsboige Oct 1, 2026
b5d0faf
fix(planners,#18578): dedup interpretation cells 10/11 in 2-PDDL-Basi…
jsboige Oct 1, 2026
31db040
fix(notebook-dotnet,#17700): ML-3 — prose du leaderboard AutoML réali…
jsboige Oct 1, 2026
733ec1c
feat(knot_lean): scaffold unknotting_11n102_upper (2->2, build OK) (#…
jsboige Oct 1, 2026
6637c66
fix(ci,#18629): prose-counts-guard -- base du diff en HEAD^1, plus de…
jsboige Oct 1, 2026
5f1453b
feat(ci,#15574): garde advisory de variance runners (item 4) -- signa…
jsboige Oct 1, 2026
8f26cef
fix(planners,#18578): nav 3-State-Space-Csharp -- prev sautait le 2, …
jsboige Oct 1, 2026
206ffcd
fix(closure-dossier,#15578): lire body PR depuis timeline au lieu de …
claude Oct 1, 2026
9068545
ci: re-run CI post-fix body PR #18666 (prev_guard, #13475)
jsboige Oct 2, 2026
503d73e
merge origin/main into fix/18620-closure-dossier-timeline
jsboige Oct 2, 2026
59cf68f
Merge branch 'main' into fix/18620-closure-dossier-timeline
jsboige Oct 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions scripts/check_closure_dossier.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,19 @@ def _merged_referring_prs(repo: str, number: int) -> list[dict[str, Any]]:
# sinon gh rend "Could not resolve to a PullRequest" et l'organe crashe
# (mesure 2026-09-28, blocage Lot D #18140 sur #17301).
src_repo = ((src.get("repository") or {}).get("full_name")) or repo
# Pas de --jq : gh l'ecrit en TEXTE BRUT, que json.loads refuse
# (defaut mesure c.5849452860 -- tout temoin rendait UNKNOWN rc=2).
row = gh_json([
"pr", "view", str(src["number"]), "--repo", src_repo,
"--json", "body",
])
body = row.get("body") if isinstance(row, dict) else None
# Body preferentiellement lu depuis la timeline (source.issue.body),
# ce qui economise un appel `gh pr view` par PR mergee referencee.
# Mesure #15578 : 555 references = 4 min de latence eliminees.
# Fallback `gh pr view` si le champ body est absent de la timeline
# (defense en profondeur : payload timeline peut etre tronque sur PRs
# tres anciennes ou via depot soeur).
body = src.get("body")
if body is None:
row = gh_json([
"pr", "view", str(src["number"]), "--repo", src_repo,
"--json", "body",
])
body = row.get("body") if isinstance(row, dict) else None
out.append({"number": src["number"], "merged_at": pr["merged_at"],
"repo": src_repo,
"body": str(body) if body else ""})
Expand Down
79 changes: 79 additions & 0 deletions scripts/tests/test_check_closure_dossier.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
render_template,
validate_dossier,
main,
_merged_referring_prs,
)


Expand Down Expand Up @@ -587,3 +588,81 @@ def fake_gh_json(args):
verdict, errors, _ = evaluate(snap)
assert verdict == "REFUSED"
assert any("cited PR #31 is not MERGED" in e for e in errors)


# --- _merged_referring_prs : body depuis timeline -----------------------------

def test_merged_referring_prs_lit_body_depuis_timeline(monkeypatch):
"""Le body d'une PR mergée doit être lu depuis la timeline (source.issue.body)
quand il est présent, sans `gh pr view` supplémentaire.

Mesure : sur #15578, 555 references = 4 min de latence eliminees (1 appel
gh api de moins par referencee). Ce test verifie le fast-path.
"""
timeline = [
{"event": "cross-referenced",
"source": {"type": "issue",
"issue": {"number": 17901,
"body": "Grain: DEEP/notebook-python -- lane X",
"pull_request": {"merged_at": "2026-09-19T10:00:00Z"},
"repository": {"full_name": "o/r"}}}},
]
def fake_gh_json(args):
assert args[0] == "api", f"appel inattendu: {args}"
return timeline
monkeypatch.setattr(ccd, "gh_json", fake_gh_json)
out = _merged_referring_prs("o/r", 15578)
assert len(out) == 1
assert out[0]["number"] == 17901
assert out[0]["merged_at"] == "2026-09-19T10:00:00Z"
assert out[0]["repo"] == "o/r"
assert out[0]["body"] == "Grain: DEEP/notebook-python -- lane X"


def test_merged_referring_prs_fallback_gh_pr_view_si_body_absent(monkeypatch):
"""Si la timeline ne porte pas le body (PR tres ancienne ou depot soeur
tronque), fallback explicite vers `gh pr view --json body`.
Defense en profondeur : ne JAMAIS perdre un body qu'on avait avant ce fix.
"""
timeline = [
{"event": "cross-referenced",
"source": {"type": "issue",
"issue": {"number": 17901,
"pull_request": {"merged_at": "2026-09-19T10:00:00Z"},
"repository": {"full_name": "o/r"}}}} # body absent
]
calls = []
def fake_gh_json(args):
calls.append(args[:2])
if args[0] == "api":
return timeline
if args[:2] == ["pr", "view"]:
return {"body": "Body depuis fallback"}
raise AssertionError(f"appel inattendu: {args}")
monkeypatch.setattr(ccd, "gh_json", fake_gh_json)
out = _merged_referring_prs("o/r", 15578)
assert len(out) == 1
assert out[0]["body"] == "Body depuis fallback"
# On a bien appele gh pr view en fallback
assert ["pr", "view"] in [c[:2] for c in calls]


def test_merged_referring_prs_ignore_les_cross_ref_non_merged(monkeypatch):
"""Un cross-reference sans pull_request.merged_at ne doit pas être inclus.
Verifie qu'on ne perd pas le filtre existant en ajoutant le fast-path.
"""
timeline = [
{"event": "cross-referenced",
"source": {"type": "issue",
"issue": {"number": 17901,
"body": "Pas mergé",
"pull_request": {"merged_at": None},
"repository": {"full_name": "o/r"}}}},
{"event": "commented"}, # autre event, ignoré
]
def fake_gh_json(args):
return timeline
monkeypatch.setattr(ccd, "gh_json", fake_gh_json)
out = _merged_referring_prs("o/r", 15578)
assert out == []

Loading