Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions tests/render/test_render_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,20 @@ def test_render_html_easy_layout_font_size():
html = render_html(_build_result())
assert "font-size: 18px" in html
assert "text-align: left" in html


# Bug regression (2026-08-25): pipeline._final_verdict() escalates a REVISE that
# survives max_revise to HUMAN_REVIEW (spec 6.8 case d), but render_html() read
# result.fidelity.verdict — the pre-escalation value — so the exact "we could not
# fix it, so we stopped" case rendered as "수정 필요" instead of "검수 필요".
# The badge MUST follow EasyReadResult.verdict (the pipeline's final verdict).
def test_render_html_badge_follows_final_verdict_not_last_fidelity_check():
result = _build_result()
result.fidelity = FidelityReport(slots=[], verdict=Verdict.REVISE)
result.verdict = Verdict.HUMAN_REVIEW

html = render_html(result)

assert "badge-human_review" in html
assert "검수 필요" in html
assert "수정 필요" not in html
17 changes: 17 additions & 0 deletions tests/web/test_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,20 @@ def test_handler_output_pictogram_src_is_gradio_servable():
assert 'src="assets/pictograms/' not in html, "raw core path leaked into Gradio HTML unrewritten"
assert "/gradio_api/file=" in html, "pictogram present but not rewritten to Gradio serving scheme"
assert str(webapp._PICTOGRAMS_DIR) in html


# Bug regression (2026-08-25): when the revise loop exhausts max_revise the
# pipeline's final verdict is HUMAN_REVIEW, but the web badge read
# result.fidelity.verdict (still REVISE) and showed "Fidelity 재교정됨 🔁" —
# a success signal on output that still has the amount missing.
def test_handler_badge_says_human_review_when_revise_loop_exhausts():
# Always drops the amount and the deadline -> REVISE every round -> exhausted.
dropping = FakeProvider(default="건강보험료를 기한 안에 내세요.")

_, _, fid_badge = webapp.simplify_handler(
"건강보험료 1,295,400원을 2026년 7월 17일까지 납부하세요.", None,
next(iter(webapp.LEVEL_CHOICES)), dropping,
)

assert "검수" in fid_badge
assert "재교정" not in fid_badge
7 changes: 5 additions & 2 deletions ttobak/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ def render_html(result: EasyReadResult) -> str:
disclaimer, the (non-validated) K-ER score + per-rule violations, the
fidelity verdict badge, and pictograms as file-path references only.
"""
badge_class, badge_label = _VERDICT_BADGE[result.fidelity.verdict]
# The badge MUST show the pipeline's FINAL verdict, not the last single
# fidelity check: a REVISE that survives max_revise is escalated to
# HUMAN_REVIEW (spec 6.8 case d) and the reader has to see that.
badge_class, badge_label = _VERDICT_BADGE[result.verdict]
template = _env.get_template(_TEMPLATE_NAME)
return template.render(
disclaimer=_DISCLAIMER,
Expand All @@ -70,7 +73,7 @@ def render_html(result: EasyReadResult) -> str:
{"rule": v.rule, "span": v.span, "severity": v.severity.value, "suggestion": v.suggestion}
for v in result.ker.violations
],
fidelity_verdict=result.fidelity.verdict.value,
fidelity_verdict=result.verdict.value,
fidelity_badge_class=badge_class,
fidelity_badge_label=badge_label,
pictograms=[{"src": _pictogram_src(p.glyph_id), "caption": p.caption} for p in result.pictograms],
Expand Down
2 changes: 1 addition & 1 deletion ttobak/web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def simplify_handler(text_input: str, file_obj, level_label: str, provider: LLMP
doc = parse(source, mime)
result = simplify(doc, level, provider)
html = _serve_pictograms_via_gradio(render_html(result))
return html, _ker_badge(result.ker), _fidelity_badge(result.fidelity.verdict)
return html, _ker_badge(result.ker), _fidelity_badge(result.verdict)
except Exception as exc: # noqa: BLE001 — 데모 UI는 어떤 실패도 메시지로 표시
msg = _html.escape(str(exc)) or "변환 중 오류가 발생했습니다."
return f'<div class="ttobak-error">변환 오류: {msg}</div>', "", ""
Loading