test(IMP-05): tighten Step 9 candidate evidence guard
Refs #5 Replace the hand-built Case 7 payload assertion with a temporary production-source guard. The test now fails if Step 9 stops emitting candidate_evidence, breaks the fallback_chain compat alias, or removes the alias intent comment. This is intentionally temporary because Step 9 application-plan unit assembly is inline. Follow-up IMP-32 should extract a helper and replace this source-string guard with a direct helper test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,9 @@ from typing import Optional
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
from src import phase_z2_pipeline
|
||||||
from src.phase_z2_pipeline import lookup_v4_match_with_fallback
|
from src.phase_z2_pipeline import lookup_v4_match_with_fallback
|
||||||
|
|
||||||
|
|
||||||
@@ -292,42 +295,25 @@ def test_existing_trace_shape_does_not_regress(patch_selector_deps):
|
|||||||
assert trace["selection_path"] == "rank_1"
|
assert trace["selection_path"] == "rank_1"
|
||||||
|
|
||||||
|
|
||||||
# ─── Case 7 : Step 9 application_plan candidate_evidence + fallback_chain alias ───
|
# ─── Case 7 : Step 9 production-source guard (Codex #20 blocker fix) ───
|
||||||
|
|
||||||
|
|
||||||
def test_step9_candidate_evidence_field_and_alias_equality():
|
def test_step9_production_emits_candidate_evidence_and_alias():
|
||||||
"""Codex #16 idea A + Codex #17 idea E + Claude #19 / #21 — Step 9 application_plan
|
"""Temporary production-source guard for IMP-05 Step 9 evidence fields.
|
||||||
must expose `candidate_evidence` as the primary per-unit evidence field, with
|
|
||||||
`fallback_chain` kept as a compat alias pointing to the same data.
|
|
||||||
|
|
||||||
Both fields must reference the same selection_trace.candidates payload so
|
Step 9 application-plan unit assembly is currently inline, so this test
|
||||||
downstream readers (new = candidate_evidence, legacy = fallback_chain) see
|
checks the exact production assignments until IMP-32 extracts a helper.
|
||||||
identical data.
|
Once that helper exists, replace this source-string guard with a direct
|
||||||
|
helper-call test.
|
||||||
"""
|
"""
|
||||||
# Synthetic selection_trace.candidates shape — mirrors selector output (Step 9 input)
|
source = inspect.getsource(phase_z2_pipeline)
|
||||||
fake_candidates = [
|
candidate_line = '"candidate_evidence": selection_trace.get("candidates", [])'
|
||||||
{"rank": 1, "template_id": "MOCK_template_direct_a", "v4_label": "use_as_is",
|
alias_line = '"fallback_chain": selection_trace.get("candidates", [])'
|
||||||
"decision": "selected", "reason": "primary_selected"},
|
|
||||||
{"rank": 2, "template_id": "MOCK_template_direct_b", "v4_label": "use_as_is",
|
|
||||||
"decision": "skipped", "reason": None},
|
|
||||||
]
|
|
||||||
|
|
||||||
# Simulated Step 9 application_plan unit payload (post-Step-3 schema)
|
assert candidate_line in source
|
||||||
selection_trace = {"candidates": fake_candidates}
|
assert alias_line in source
|
||||||
unit_payload = {
|
assert source.index(candidate_line) < source.index(alias_line)
|
||||||
"candidate_evidence": selection_trace.get("candidates", []),
|
assert "compat alias; prefer candidate_evidence" in source
|
||||||
"fallback_chain": selection_trace.get("candidates", []),
|
|
||||||
}
|
|
||||||
|
|
||||||
# candidate_evidence must be present as the primary field
|
|
||||||
assert "candidate_evidence" in unit_payload
|
|
||||||
assert unit_payload["candidate_evidence"] == fake_candidates
|
|
||||||
|
|
||||||
# fallback_chain compat alias must reference the same data (no regression for legacy readers)
|
|
||||||
assert "fallback_chain" in unit_payload
|
|
||||||
assert unit_payload["fallback_chain"] == unit_payload["candidate_evidence"]
|
|
||||||
assert unit_payload["fallback_chain"] is unit_payload["candidate_evidence"] or \
|
|
||||||
unit_payload["fallback_chain"] == unit_payload["candidate_evidence"]
|
|
||||||
|
|
||||||
|
|
||||||
# ─── Case 8 : Step 20 slide-status qualifier fields presence + defensive default
|
# ─── Case 8 : Step 20 slide-status qualifier fields presence + defensive default
|
||||||
|
|||||||
Reference in New Issue
Block a user