refactor(#41): IMP-32 Step 9 application_plan helper extraction (u1~u5)
Pure refactor — extract inline Step 9 per-unit application_plan dict
assembly into module-level private helpers for testability. Replaces
IMP-05 Case 7 inspect.getsource() literal guard with direct helper-call
shape test. Behavior preserved: key set/order, candidate_evidence +
fallback_chain compat alias identity, IMP-06 additive plan fields,
IMP-11 D-2 markers (single _contract = get_contract(c.template_id)
bind + catalog_registered + min_height_px chain).
- u1 _application_candidates_for_unit(unit) at src/phase_z2_pipeline.py
:2829-2853 — APPLICATION_MODE_BY_V4_LABEL mapping (pure extraction)
- u2 _v4_all_judgments_for_unit(v4_all_for_unit) at :2855-2882 —
IMP-11 D-2 chain preserved literally
- u3 _build_application_plan_unit(unit, zone_plan, selection_trace,
plan_record, v4_all_for_unit, layout_preset, layout_candidates_list)
at :2885-2995 — byte-identical per-unit dict (key set + order +
value identity), candidate_evidence / fallback_chain compat alias,
v4_candidates list, v4_all_judgments, application_candidates, IMP-06
additive plan fields
- u4 Step 9 inline loop body at :4620-4658 replaced with helper call;
per-index/per-id lookups (zone_region_plans[i], v4_fallback_traces
.get(...), plan_record_by_unit_id.get(id(unit)), section_alias_by_id,
lookup_v4_all_judgments(...)) stay at call-site
- u5 tests/test_phase_z2_v4_fallback.py Case 7 rewritten to
test_build_application_plan_unit_emits_candidate_evidence_and_alias
— direct helper call with SimpleNamespace duck-typed input; asserts
candidate_evidence list identity (is), fallback_chain compat-alias
identity (is), key order (candidate_evidence before fallback_chain),
and compat-alias comment scoped to inspect.getsource(_build_
application_plan_unit)
Verification: targeted 22 passed, full pytest 408 passed (0 fail/skip),
smoke 11/11 PASS (2 pre-existing baseline SKIPs unchanged).
Cross-ref: IMP-05 (#5) commit 23d1b25 Case 7 temporary source guard
(replaced) / Codex #20 + #21 / IMP-11 D-2 marker preserved.
This commit is contained in:
@@ -295,25 +295,79 @@ def test_existing_trace_shape_does_not_regress(patch_selector_deps):
|
||||
assert trace["selection_path"] == "rank_1"
|
||||
|
||||
|
||||
# ─── Case 7 : Step 9 production-source guard (Codex #20 blocker fix) ───
|
||||
# ─── Case 7 : Step 9 helper-call shape test (IMP-32 u5 — replaces source guard) ───
|
||||
|
||||
|
||||
def test_step9_production_emits_candidate_evidence_and_alias():
|
||||
"""Temporary production-source guard for IMP-05 Step 9 evidence fields.
|
||||
def test_build_application_plan_unit_emits_candidate_evidence_and_alias():
|
||||
"""IMP-32 u5 — direct helper-call shape test for Step 9 evidence fields.
|
||||
|
||||
Step 9 application-plan unit assembly is currently inline, so this test
|
||||
checks the exact production assignments until IMP-32 extracts a helper.
|
||||
Once that helper exists, replace this source-string guard with a direct
|
||||
helper-call test.
|
||||
Replaces the IMP-05 Case 7 `inspect.getsource(phase_z2_pipeline)` literal
|
||||
guard (introduced at commit `23d1b25` while Step 9 unit assembly was
|
||||
inline) with a direct call to `_build_application_plan_unit`, the helper
|
||||
extracted in IMP-32 u3. Verification axes preserved:
|
||||
|
||||
- candidate_evidence list identity sourced from `selection_trace["candidates"]`
|
||||
- fallback_chain compat-alias identity (same list object as candidate_evidence)
|
||||
- key order: candidate_evidence before fallback_chain
|
||||
- compat-alias comment preserved on the helper's fallback_chain line
|
||||
"""
|
||||
source = inspect.getsource(phase_z2_pipeline)
|
||||
candidate_line = '"candidate_evidence": selection_trace.get("candidates", [])'
|
||||
alias_line = '"fallback_chain": selection_trace.get("candidates", [])'
|
||||
from types import SimpleNamespace
|
||||
|
||||
assert candidate_line in source
|
||||
assert alias_line in source
|
||||
assert source.index(candidate_line) < source.index(alias_line)
|
||||
assert "compat alias; prefer candidate_evidence" in source
|
||||
from src.phase_z2_pipeline import _build_application_plan_unit
|
||||
|
||||
candidates_list = [
|
||||
{"rank": 1, "template_id": "MOCK_template_direct_a", "label": "use_as_is"},
|
||||
]
|
||||
selection_trace = {"candidates": candidates_list}
|
||||
|
||||
# Synthetic CompositionUnit-shape duck-typed input — matches V4Match attrs
|
||||
# used inside the helper (template_id / frame_id / frame_number / v4_rank /
|
||||
# confidence / label per src/phase_z2_pipeline.py V4Match dataclass).
|
||||
v4_candidate = SimpleNamespace(
|
||||
template_id="MOCK_template_direct_a",
|
||||
frame_id="MOCK_frame_001",
|
||||
frame_number=1,
|
||||
v4_rank=1,
|
||||
confidence=0.9,
|
||||
label="use_as_is",
|
||||
)
|
||||
unit = SimpleNamespace(
|
||||
source_section_ids=["S1"],
|
||||
v4_candidates=[v4_candidate],
|
||||
v4_rank=1,
|
||||
selection_path="rank_1",
|
||||
fallback_reason=None,
|
||||
frame_template_id="MOCK_template_direct_a",
|
||||
)
|
||||
|
||||
result = _build_application_plan_unit(
|
||||
unit=unit,
|
||||
zone_plan={},
|
||||
selection_trace=selection_trace,
|
||||
plan_record=None,
|
||||
v4_all_for_unit=[],
|
||||
layout_preset="Type A",
|
||||
layout_candidates_list=[],
|
||||
)
|
||||
|
||||
# IMP-05 L2 — candidate_evidence is the primary field, identity-bound to
|
||||
# selection_trace["candidates"] (not a copy).
|
||||
assert "candidate_evidence" in result
|
||||
assert result["candidate_evidence"] is candidates_list
|
||||
|
||||
# compat alias — fallback_chain references the SAME list object as
|
||||
# candidate_evidence (verified by `is` identity, not equality).
|
||||
assert "fallback_chain" in result
|
||||
assert result["fallback_chain"] is candidates_list
|
||||
|
||||
# key order — candidate_evidence MUST precede fallback_chain in the
|
||||
# returned dict to preserve documented L2 ordering.
|
||||
keys = list(result.keys())
|
||||
assert keys.index("candidate_evidence") < keys.index("fallback_chain")
|
||||
|
||||
# compat-alias comment preserved on the helper's fallback_chain line.
|
||||
helper_source = inspect.getsource(_build_application_plan_unit)
|
||||
assert "compat alias; prefer candidate_evidence" in helper_source
|
||||
|
||||
|
||||
# ─── Case 8 : Step 20 slide-status qualifier fields presence + defensive default
|
||||
|
||||
Reference in New Issue
Block a user