fix(dupont): reject out-of-domain window + bidirectional clip + suffix discipline (R1-R4/M2)
ci/woodpecker/push/main Pipeline failed

Per finance ruling 2026-10-05 (project-20261005-dupont-oob-window-fix):

- R1: no intersection with available month domain => explicit error (endpoint 400), no window fields

- R2: with intersection => intersection window, months>=1 (kills inversion and months<=0)

- R3: quarter/half/... suffix kept only when returned window == nominal window (clipped flag)

- R4: symmetric lower-bound clip note; M2: TTM nominal window = [anchor-11, anchor] (12 months)

- M1: docstring correction (lower-bound overflow is clipped, not 400)

No push / no deploy / no restart / no DB write.
This commit is contained in:
wecom-fullstack
2026-10-05 02:02:21 +08:00
parent 3ed9fa0611
commit 4f9bab6bc0
4 changed files with 278 additions and 21 deletions
+6 -2
View File
@@ -100,10 +100,14 @@ def test_ytd_ttm_unchanged():
assert (ytd["period_start"], ytd["period_end"]) == ("2026-01", "2026-10")
assert ytd["months"] == 10
# M2(2026-10-05 裁定 §4):TTM 名义区间 = [anchor−11, anchor] = **12 个月**。
# 历史断言写的是 13 个月(anchor 的「去年同月」),即被裁定为缺陷的口径,见
# test_dupont_oob_window_ruling_20261005.py / 本文件 §裁定回归。
ttm = rw("ttm", anchor="2026-10")
assert ttm["period_key"] == "ttm"
assert (ttm["period_start"], ttm["period_end"]) == ("2025-10", "2026-10")
assert ttm["months"] == 13
assert (ttm["period_start"], ttm["period_end"]) == ("2025-11", "2026-10")
assert ttm["nominal_months"] == 12
assert ttm["months"] == 12
def test_custom_unchanged():