from pathlib import Path CURRENT_CONTRACT_ROOTS = [ Path("content_agent"), Path("tests"), Path("sql"), Path("product_documents"), ] def test_p8_learning_contract_has_no_legacy_action_or_effect_status(): text = _joined_text(CURRENT_CONTRACT_ROOTS) assert "HOLD_CONTENT_" + "PENDING" not in text assert "weak_" + "effective" not in text assert "search_query_effect_status" + '="block' + 'ed"' not in text assert "search_query_effect_status" + ":'block" + "ed'" not in text def test_p8_learning_contract_has_no_old_walk_strategy_name(): text = _joined_text(CURRENT_CONTRACT_ROOTS) assert "douyin_available_" + "walk_strategy_v1" not in text assert "douyin_available_" + "walk_strategy.v1.json" not in text def test_p8_recommendations_do_not_emit_auto_mutation_fields(): text = _joined_text([Path("content_agent/business_modules/learning_review.py")]) assert "requires_human_approval" in text assert "auto_" + "apply" not in text assert "rule_pack_" + "patch" not in text assert "walk_strategy_" + "patch" not in text assert "budget_" + "patch" not in text assert "publish_job_" + "patch" not in text def test_p8_default_tests_do_not_wire_real_external_sources(): text = _joined_text([Path("tests")]) assert "CONTENTFIND_OPENROUTER_" + "API_KEY=" not in text assert "CONTENT_SUPPLY_DB_" + "PASSWORD=" not in text assert "CRAWAPI_" + "COOKIE=" not in text assert "publish_jobs_real_" + "client" not in text def _joined_text(roots: list[Path]) -> str: chunks = [] for root in roots: paths = [root] if root.is_file() else list(root.rglob("*")) for path in paths: if path.is_file() and path.suffix in {".py", ".sql", ".md", ".json"}: chunks.append(path.read_text(encoding="utf-8")) return "\n".join(chunks)