from agent.prompts import PROSE_FIELDS, SYNTHESIS_STRUCTURED_PROMPT def _json_template_block() -> str: """Return the 'Required JSON structure' example block from the synthesis prompt.""" start = SYNTHESIS_STRUCTURED_PROMPT.index("Required JSON structure:") end = SYNTHESIS_STRUCTURED_PROMPT.index("## Field counts") return SYNTHESIS_STRUCTURED_PROMPT[start:end] def test_every_example_with_evidence_snippet_also_shows_evidence_ref(): """Regression guard: the JSON template the model is told to match 'exactly' must show `evidence_ref` on every SourcedFact-shaped example object, not just describe the requirement in prose above it. A template that has `evidence_snippet` without a paired `evidence_ref` previously caused the model to omit `evidence_ref` from every claim, which agent.evidence.verify_fact then fails closed on (missing_evidence_ref), stripping every fact from the brief. """ block = _json_template_block() snippet_count = block.count('"evidence_snippet"') ref_count = block.count('"evidence_ref"') assert snippet_count > 0 assert ref_count == snippet_count def test_guidance_history_example_does_not_contradict_the_null_out_rule(): """`actual_result`/`verdict` are reserved for the deterministic comparator (see 'Guidance actuals comparison' rule) — the example must not show the model a literal 'beat' value that contradicts that instruction.""" block = _json_template_block() guidance_start = block.index('"guidance_history"') guidance_block = block[guidance_start:block.index("],", guidance_start) + 2] assert '"actual_result": null' in guidance_block assert '"verdict": null' in guidance_block def test_company_profile_contract_is_in_synthesis_prompt(): assert "## COMPANY PROFILE SECTION" in SYNTHESIS_STRUCTURED_PROMPT assert '"company_profile"' in _json_template_block() for field in ( "identity", "business_lines", "geographic_exposures", "strategic_changes", "attention_themes", "watch_variables", ): assert f'"{field}"' in _json_template_block() def test_company_profile_analytical_prose_fields_are_translatable(): assert { "economics", "why_it_matters", "theme", "variable", "next_datapoint", "alert_signal", } <= PROSE_FIELDS