fix(release): bind scene prompts and holdout plan

This commit is contained in:
2026-10-06 17:59:19 +08:00
parent f377391637
commit 77e60366de
11 changed files with 785 additions and 22 deletions
@@ -3,6 +3,7 @@ from datetime import UTC, datetime
from types import SimpleNamespace
from yuqei_sdk.contract_drafting import draft_digest
from yuqei_sdk.prompt_source_baseline import scene_prompt_source_identity
from yuqei_sdk.review_routing import (
SCENE_REVIEW_ROUTES,
REVIEW_ROUTING_VERSION,
@@ -28,6 +29,13 @@ def _identity(snapshot):
"resolution": "platform_shared_published" if status == "published" else status}
def _matches_source_identity(actual, expected):
return bool(actual and expected and all(
actual.get(key) == expected.get(key)
for key in ("name", "version", "content_sha256")
))
def build_scene_runtime_manifest(store, settings, *, template_id, contract_type):
route = SCENE_REVIEW_ROUTES.get(template_id)
if route is None:
@@ -44,9 +52,16 @@ def build_scene_runtime_manifest(store, settings, *, template_id, contract_type)
request.review_profile = "standard"
ordinary = _identity(capture_review_prompt_snapshot(store, request))
drafting = _identity(capture_drafting_prompt_snapshot(store))
source_identity = scene_prompt_source_identity(template_id)
issues = []
if not source_identity:
issues.append("prompt_source_identity_unresolved")
expected_draft = (source_identity or {}).get("draft_prompt")
expected_review = (source_identity or {}).get("review_prompt")
if not drafting or drafting["status"] != "published" or not drafting["enabled"]:
issues.append("draft_prompt_not_published")
if not _matches_source_identity(drafting, expected_draft):
issues.append("draft_runtime_source_mismatch")
if not ordinary:
issues.append("review_prompt_missing")
else:
@@ -54,6 +69,8 @@ def build_scene_runtime_manifest(store, settings, *, template_id, contract_type)
issues.append("review_runtime_fallback")
if ordinary["status"] != "published" or not ordinary["enabled"]:
issues.append("review_prompt_not_published")
if not _matches_source_identity(ordinary, expected_review):
issues.append("review_runtime_source_mismatch")
if any(ordinary[key] != trial[key] for key in ("name", "version", "content_sha256")):
issues.append("review_trial_runtime_mismatch")
if settings.provider_call_mode != "codex_cli" or settings.codex_cli_model != "gpt-5.6-sol":
@@ -62,6 +79,15 @@ def build_scene_runtime_manifest(store, settings, *, template_id, contract_type)
payload = {"schema_version": "scene-runtime-manifest.v1", "tenant_id": current_tenant_id(),
"template_id": template_id, "contract_type": contract_type, "routing_version": REVIEW_ROUTING_VERSION,
"requested_review_route": requested_review_route, "draft_prompt": drafting,
"source_prompt_identity": source_identity,
"source_prompt_identity_resolved": source_identity is not None,
"runtime_source_alignment": {
"draft_identity_match": _matches_source_identity(drafting, expected_draft),
"review_identity_match": _matches_source_identity(ordinary, expected_review),
"draft_published": bool(drafting and drafting["status"] == "published" and drafting["enabled"]),
"review_published": bool(ordinary and ordinary["status"] == "published" and ordinary["enabled"]),
"trial_review_matches_runtime": _matches_source_identity(trial, ordinary),
},
"prompt_storage_scope": "platform_shared",
"trial_review_prompt": trial, "runtime_review_prompt": ordinary,
"provider_mode": settings.provider_call_mode,
@@ -1,4 +1,5 @@
"""Unit route identities only; these tests do not call or approve a model."""
from datetime import UTC, datetime
from types import SimpleNamespace
import httpx
@@ -7,11 +8,31 @@ from fastapi.testclient import TestClient
from yuqei_sdk import AiPlatformClient, RequestContext
from yuqei_sdk.contract_drafting import draft_digest
from yuqei_sdk.prompt_source_baseline import (
DOMAIN_REVIEW_RUNTIME_IDENTITIES,
DRAFTING_MODULES,
DRAFT_RUNTIME_IDENTITY,
NEW_REVIEW_RUNTIME_IDENTITIES,
REVIEW_MODULES,
scene_prompt_source_identity,
)
from yuqei_sdk.review_routing import SCENE_REVIEW_ROUTES, scene_review_evaluation_profile
from yuqei_ai_platform_api.config import AiPlatformSettings
from yuqei_ai_platform_api.contract_drafting import capture_drafting_prompt_snapshot
from yuqei_ai_platform_api.contract_drafting import (
DRAFT_PROMPT_CONTENT,
DRAFT_PROMPT_NAMES,
DRAFT_PROMPT_VERSION,
capture_drafting_prompt_snapshot,
)
from yuqei_ai_platform_api.drafting_prompt_modules import drafting_module_evidence
from yuqei_ai_platform_api.main import create_app
from yuqei_ai_platform_api.review_scene_prompts import scene_review_template
from yuqei_ai_platform_api.packaged_prompt_assets_import import (
DEFAULT_SOURCE_FILE,
DEFAULT_VERSION,
load_packaged_prompt_assets,
)
from yuqei_ai_platform_api.repository import PromptTemplate
from yuqei_ai_platform_api.review_scene_prompts import review_modules, scene_review_template
from yuqei_ai_platform_api.scene_runtime_manifest import build_scene_runtime_manifest
from yuqei_contract_api.contract_templates import get_contract_template
from yuqei_ai_platform_api.scene_evaluation_gate import (
@@ -38,7 +59,6 @@ def fixture_store(template_id=SCENE):
review_profile=scene_review_evaluation_profile(template_id),
)
review = scene_review_template(request).model_copy(update={"status": "published"})
from yuqei_ai_platform_api.repository import PromptTemplate
empty = SimpleNamespace(get_prompt_template=lambda _name: None)
drafting = PromptTemplate.model_validate(capture_drafting_prompt_snapshot(empty)["template"]).model_copy(update={"status": "published"})
prompts = {review.name: review, drafting.name: drafting}
@@ -51,8 +71,22 @@ def test_manifest_matches_actual_routes_without_returning_prompt_content(templat
template = get_contract_template(template_id)
manifest = build_scene_runtime_manifest(store, AiPlatformSettings(provider_call_mode="codex_cli"),
template_id=template_id, contract_type=template.contract_type)
assert manifest["alignment_errors"] == []
assert manifest["published_prompt_alignment_verified"] is True
expected = scene_prompt_source_identity(template_id)
review_source_match = all(
manifest["runtime_review_prompt"].get(key) == expected["review_prompt"][key]
for key in ("name", "version", "content_sha256")
)
assert manifest["alignment_errors"] == ([] if review_source_match else ["review_runtime_source_mismatch"])
assert manifest["published_prompt_alignment_verified"] is review_source_match
assert manifest["source_prompt_identity"] == expected
assert manifest["source_prompt_identity_resolved"] is True
assert manifest["runtime_source_alignment"] == {
"draft_identity_match": True,
"review_identity_match": review_source_match,
"draft_published": True,
"review_published": True,
"trial_review_matches_runtime": True,
}
assert manifest["model"] == "gpt-5.6-sol" and manifest["model_calls"] == 0
assert manifest["authorizes_publication"] is False
assert manifest["evaluation_gate"]["development_gate_passed"] is True
@@ -143,7 +177,12 @@ def test_builtin_trial_fallback_and_unpublished_runtime_are_distinct():
review = prompts.pop(SCENE_REVIEW_ROUTES[SCENE][1])
prompts["contract_review_default"] = review.model_copy(update={"name": "contract_review_default", "version": "legacy"})
manifest = build_scene_runtime_manifest(store, AiPlatformSettings(provider_call_mode="codex_cli"), template_id=SCENE, contract_type="transport")
assert set(manifest["alignment_errors"]) == {"draft_prompt_not_published", "review_runtime_fallback", "review_trial_runtime_mismatch"}
assert set(manifest["alignment_errors"]) == {
"draft_prompt_not_published",
"review_runtime_fallback",
"review_runtime_source_mismatch",
"review_trial_runtime_mismatch",
}
assert manifest["draft_prompt"]["status"] == "builtin_development"
assert manifest["draft_prompt"]["resolution"] == "builtin_development"
@@ -154,6 +193,7 @@ def test_same_content_with_new_version_requires_reevaluation():
prompts[name] = prompts[name].model_copy(update={"version": "different-version"})
manifest = build_scene_runtime_manifest(store, AiPlatformSettings(provider_call_mode="codex_cli"), template_id=SCENE, contract_type="transport")
assert "review_trial_runtime_mismatch" in manifest["alignment_errors"]
assert "review_runtime_source_mismatch" in manifest["alignment_errors"]
with pytest.raises(ValueError):
build_scene_runtime_manifest(store, AiPlatformSettings(), template_id=SCENE, contract_type="labor")
@@ -168,6 +208,78 @@ def test_catalog_classification_is_not_source_approval():
assert manifest["legal_correctness_verified"] is False
def test_prompt_source_catalog_is_recomputed_from_the_actual_module_composers_and_packaged_assets():
assert drafting_module_evidence(DRAFT_PROMPT_CONTENT) == list(DRAFTING_MODULES)
draft = PromptTemplate(
id="source-check",
name=DRAFT_PROMPT_NAMES[0],
version=DRAFT_PROMPT_VERSION,
content=DRAFT_PROMPT_CONTENT,
status="draft",
updated_at=datetime(2026, 10, 6, tzinfo=UTC),
)
assert {
"name": draft.name,
"version": draft.version,
"content_sha256": draft.content_hash,
"source_kind": "composed_drafting_modules",
} == DRAFT_RUNTIME_IDENTITY
actual_review_modules = review_modules()
assert [
{key: actual_review_modules[item["key"]][key] for key in ("key", "version", "content_sha256")}
for item in REVIEW_MODULES
] == list(REVIEW_MODULES)
route_inputs = {
"contract_review_trade_procurement": ("purchase", "scene_evaluation_v3"),
"contract_review_services": ("service", "scene_evaluation_v3"),
"contract_review_transport_warehousing": ("transport", "scene_evaluation_v4"),
"contract_review_manufacturing": ("manufacturing", "scene_evaluation_v4"),
"contract_review_construction": ("construction", "scene_evaluation_v3"),
"contract_review_marketing": ("marketing", "scene_evaluation_v4"),
"contract_review_consumer_services": ("consumer_service", "scene_evaluation_v3"),
"contract_review_notices_amendments": ("amendment", "scene_evaluation_v4"),
}
recomputed_new_review = {}
for route, (contract_type, profile) in route_inputs.items():
template = scene_review_template(SimpleNamespace(
contract_type=contract_type,
scene_template_id=None,
review_profile=profile,
))
assert template.name == route
recomputed_new_review[route] = {
"name": template.name,
"version": template.version,
"content_sha256": template.content_hash,
"source_kind": "new_review_module_composite",
}
assert recomputed_new_review == NEW_REVIEW_RUNTIME_IDENTITIES
assets, _, duplicate_keys = load_packaged_prompt_assets(DEFAULT_SOURCE_FILE)
assert duplicate_keys == []
assets_by_key = {asset.prompt_key: asset for asset in assets}
recomputed_domain = {}
for route in DOMAIN_REVIEW_RUNTIME_IDENTITIES:
asset = assets_by_key[route]
template = PromptTemplate(
id=f"source-check-{route}",
name=asset.prompt_key,
version=DEFAULT_VERSION,
content=asset.content,
status="draft",
updated_at=datetime(2026, 10, 6, tzinfo=UTC),
)
recomputed_domain[route] = {
"name": template.name,
"version": template.version,
"content_sha256": template.content_hash,
"source_kind": "existing_domain_prompt_asset",
}
assert recomputed_domain == DOMAIN_REVIEW_RUNTIME_IDENTITIES
def test_sdk_uses_configured_prefix_and_scope_headers():
seen = []
def transport(request):
@@ -0,0 +1,171 @@
"""Current source Prompt identities for the multi-scene release baseline.
This catalog describes code-owned source bytes. It is deliberately separate
from tenant Prompt rows: resolving an identity here never means that the row is
published, enabled, evaluated by a real model, or approved for release.
"""
from __future__ import annotations
from copy import deepcopy
from .contract_drafting import draft_digest
from .review_routing import REVIEW_MODULE_KEYS, SCENE_REVIEW_ROUTES
BASELINE_SCHEMA_VERSION = "prompt-source-baseline.v1"
BASELINE_VERSION = "rc05-current-source-20261006"
DRAFTING_MODULES = (
{"key": "draft_intake", "version": "tp06-22-20260909-1", "content_sha256": "64519f6e5e95d9f1408e8b3db4feb818dec7cb0386de7983f591947f1cb53983"},
{"key": "template_match", "version": "tp05-20260828-1", "content_sha256": "68a7e57f142da85e4e1878f018f34e95a778b72995f1452a4e5778b753e0e560"},
{"key": "missing_facts_questions", "version": "tp06-18-20260909-1", "content_sha256": "5643ab97bf661d546a99a3e609db390d574cb0e2940a6ace984e2a08e4ab83aa"},
{"key": "clause_assembly_plan", "version": "tp06-22-20260909-1", "content_sha256": "eddb6c1685b33031d1f781220bbcc631e756f6ed8b8b30a706fc9af482a8c827"},
{"key": "draft_consistency_check", "version": "tp06-20260830-2", "content_sha256": "005e2308d6d041968a9c1c5f2bbc20afa91feadea9f0ad0bdb48d8ed97fb5b52"},
{"key": "candidate_revision_explanation", "version": "tp06-23-20260909-1", "content_sha256": "a204d4be6de9fde497a7b4fd0dbad81758a6981220480eb46a82753b53c79f3a"},
)
REVIEW_MODULES = (
{"key": "contract_review_trade_procurement", "version": "tp05-2-20260828-1", "content_sha256": "412b23ab4860866c05281e721d0c77090ffa302d1ecfe049ab5da627b2f92d6a"},
{"key": "contract_review_services", "version": "tp05-2-20260828-1", "content_sha256": "a1472d3819dd19993872ff8b9d5e1206ba0c8a60a4a31a07fbe5c3957a73dc5e"},
{"key": "contract_review_transport_warehousing", "version": "tp05-2-20260828-1", "content_sha256": "96d74ec8b5ac8239d63fba0bb46ea59afa25774d6f04620f89d321b6d5acf91a"},
{"key": "contract_review_manufacturing", "version": "tp05-2-20260828-1", "content_sha256": "dc45ec97b7a924dd9b0b59da8b142399e390f2d69ffc20dce248a2f56576b5cb"},
{"key": "contract_review_construction", "version": "tp05-2-20260828-1", "content_sha256": "c4772d3bcc4de00d0d932cda5c55e4a22478838fb20c1e6cf846ed0963ec9eba"},
{"key": "contract_review_marketing", "version": "tp05-2-20260828-1", "content_sha256": "0bffc870ff1f60f0f0d4efbff34771e62481b3a38e65fecabd4e69f80f6c8ed6"},
{"key": "contract_review_consumer_services", "version": "tp05-2-20260828-1", "content_sha256": "687976935fd5bf237deb3da1a5e6ba05226226ce54fec5079641088efd9692c1"},
{"key": "contract_review_notices_amendments", "version": "tp05-2-20260828-1", "content_sha256": "c919316f36cc36c84b0e559a5b80587ae141d84074f7daa403e0eb1173fd0bf5"},
)
DRAFT_RUNTIME_IDENTITY = {
"name": "contract_drafting_v1",
"version": "tp06-23-20260909-1",
"content_sha256": "ab823d6efcf6cdb9cbc7741620bca7cb09f4c462b3a33295308d8cd7b0b82255",
"source_kind": "composed_drafting_modules",
}
# The eight newly authored review modules resolve to composed Prompt assets.
# A route has one release-target identity even when older evaluation evidence is
# still bound to an earlier profile. That evidence is not rewritten here.
NEW_REVIEW_RUNTIME_IDENTITIES = {
"contract_review_trade_procurement": {"name": "contract_review_trade_procurement", "version": "tp06-2-20260831-1", "content_sha256": "71956dde40698f3a7488da8f8b8214db8ca7bc8ebeddda6c4b965d74185bb457", "source_kind": "new_review_module_composite"},
"contract_review_services": {"name": "contract_review_services", "version": "tp06-2-20260831-1", "content_sha256": "21ce149263a42f8cdd76f11800aedb66f5ee8e4b43cd5e41696092d96b31114d", "source_kind": "new_review_module_composite"},
"contract_review_transport_warehousing": {"name": "contract_review_transport_warehousing", "version": "tp06-8-20260909-1", "content_sha256": "950d6a02476bf37e6c2a733710bdfdfefe474b44743bd9d7448bbf95c01c6b14", "source_kind": "new_review_module_composite"},
"contract_review_manufacturing": {"name": "contract_review_manufacturing", "version": "tp06-8-20260909-1", "content_sha256": "97ba767d8d47166697d7c0790fa4e17cb7b7c72950e149d6bbf4bda9bfb3d5c4", "source_kind": "new_review_module_composite"},
"contract_review_construction": {"name": "contract_review_construction", "version": "tp06-2-20260831-1", "content_sha256": "444552139eeec9b210f652c132ffb1ea42697e28be0c8fe33e2b46a663238cbc", "source_kind": "new_review_module_composite"},
"contract_review_marketing": {"name": "contract_review_marketing", "version": "tp06-8-20260909-1", "content_sha256": "261fb010dcab3d20f6f0751df941b3be11a1db06be5e4f2e43122ea2e538fcf5", "source_kind": "new_review_module_composite"},
"contract_review_consumer_services": {"name": "contract_review_consumer_services", "version": "tp06-2-20260831-1", "content_sha256": "c42da047fae64cf91cf544f3c694ef3ff99226dd8af0d4465b71f272d3b3f603", "source_kind": "new_review_module_composite"},
"contract_review_notices_amendments": {"name": "contract_review_notices_amendments", "version": "tp06-8-20260909-1", "content_sha256": "19fbfc866d6a67c5da9aa18e55fcd239b3d8d9915a5fa1076e8befb64c64d6e3", "source_kind": "new_review_module_composite"},
}
# These five routes predate the eight new review modules. Their release-target
# identities come from the packaged phase-15 assets and remain separate runtime
# dependencies; they are not counted as extra modules in the 14-module batch.
DOMAIN_REVIEW_RUNTIME_IDENTITIES = {
"contract_review_tech_saas_data_compliance": {"name": "contract_review_tech_saas_data_compliance", "version": "v1-phase15", "content_sha256": "0075ab909b0622fd0e50817b2f4cfc6498e4ddea740c6f7a185cbc498f05b5c1", "source_kind": "existing_domain_prompt_asset"},
"contract_review_real_estate_property": {"name": "contract_review_real_estate_property", "version": "v1-phase15", "content_sha256": "87cdcc6ed723b6a1f1574a15da84e2e0b61d51e9fde47b190ecd1ad4aeb4eabb", "source_kind": "existing_domain_prompt_asset"},
"contract_review_channel_franchise": {"name": "contract_review_channel_franchise", "version": "v1-phase15", "content_sha256": "523aba6a76a6a3ec0e5f1c38d92287462f4286ceb5d3a588bcd7496c37022859", "source_kind": "existing_domain_prompt_asset"},
"contract_review_employment_hr": {"name": "contract_review_employment_hr", "version": "v1-phase15", "content_sha256": "c30e1424723565d76b1d4b5708593efc0bd67d74bf6c7ae56940d9af4dd0d1d7", "source_kind": "existing_domain_prompt_asset"},
"contract_review_investment_finance": {"name": "contract_review_investment_finance", "version": "v1-phase15", "content_sha256": "37bb23f09cada7b04746b77a5cc6898719fe257a97b6de4a6e2ca22ca2f69bc6", "source_kind": "existing_domain_prompt_asset"},
}
REVIEW_RUNTIME_IDENTITIES = {
**NEW_REVIEW_RUNTIME_IDENTITIES,
**DOMAIN_REVIEW_RUNTIME_IDENTITIES,
}
def _payload() -> dict:
scenes = {}
drafting_keys = [item["key"] for item in DRAFTING_MODULES]
review_modules = {item["key"]: item for item in REVIEW_MODULES}
for template_id, (contract_type, route) in sorted(SCENE_REVIEW_ROUTES.items()):
target = REVIEW_RUNTIME_IDENTITIES[route]
scenes[template_id] = {
"template_id": template_id,
"contract_type": contract_type,
"review_route": route,
"review_route_kind": (
"new_review_module"
if route in NEW_REVIEW_RUNTIME_IDENTITIES
else "existing_domain_prompt"
),
"draft_prompt": deepcopy(DRAFT_RUNTIME_IDENTITY),
"review_prompt": deepcopy(target),
"drafting_module_keys": list(drafting_keys),
"review_module_keys": [route] if route in review_modules else [],
"source_identity_resolved": True,
"technical_drafting_coverage_represented": True,
"technical_review_coverage_represented": True,
"published_runtime_verified": False,
"real_model_result": False,
"authorizes_publication": False,
}
return {
"schema_version": BASELINE_SCHEMA_VERSION,
"baseline_version": BASELINE_VERSION,
"module_baseline": {
"drafting": deepcopy(list(DRAFTING_MODULES)),
"review": deepcopy(list(REVIEW_MODULES)),
"module_count": len(DRAFTING_MODULES) + len(REVIEW_MODULES),
},
"runtime_targets": {
"drafting": deepcopy(DRAFT_RUNTIME_IDENTITY),
"new_review_modules": deepcopy(NEW_REVIEW_RUNTIME_IDENTITIES),
"existing_domain_prompts": deepcopy(DOMAIN_REVIEW_RUNTIME_IDENTITIES),
"identity_count": 1 + len(REVIEW_RUNTIME_IDENTITIES),
},
"scenes": scenes,
"summary": {
"scenes": len(scenes),
"source_identities_resolved": sum(item["source_identity_resolved"] for item in scenes.values()),
"technical_drafting_coverage_represented": sum(item["technical_drafting_coverage_represented"] for item in scenes.values()),
"technical_review_coverage_represented": sum(item["technical_review_coverage_represented"] for item in scenes.values()),
"published_runtime_verified": 0,
"real_model_results": 0,
"authorizes_publication": 0,
},
"not_runtime_publication_evidence": True,
"not_legal_approval": True,
"authorizes_publication": False,
}
def _validated_payload() -> dict:
payload = _payload()
module_baseline = payload["module_baseline"]
if (module_baseline["module_count"] != 14
or tuple(item["key"] for item in module_baseline["drafting"]) != tuple(
item["key"] for item in DRAFTING_MODULES)
or tuple(item["key"] for item in module_baseline["review"]) != REVIEW_MODULE_KEYS
or len(payload["runtime_targets"]["new_review_modules"]) != 8
or len(payload["runtime_targets"]["existing_domain_prompts"]) != 5
or payload["runtime_targets"]["identity_count"] != 14
or set(payload["scenes"]) != set(SCENE_REVIEW_ROUTES)
or payload["summary"]["source_identities_resolved"] != 30
or payload["summary"]["technical_drafting_coverage_represented"] != 30
or payload["summary"]["technical_review_coverage_represented"] != 30):
raise RuntimeError("Prompt source baseline is incomplete or inconsistent")
return payload
def prompt_source_baseline() -> dict:
"""Return a defensive copy of the 14-module/14-runtime source baseline."""
payload = _validated_payload()
return {**deepcopy(payload), "manifest_sha256": draft_digest(payload)}
def scene_prompt_source_identity(template_id: str) -> dict | None:
"""Resolve one scene without consulting or mutating a runtime Prompt store."""
if not isinstance(template_id, str):
return None
baseline = prompt_source_baseline()
scene = baseline["scenes"].get(template_id)
if scene is None:
return None
return {
**deepcopy(scene),
"baseline_version": baseline["baseline_version"],
"baseline_manifest_sha256": baseline["manifest_sha256"],
"not_runtime_publication_evidence": True,
"not_legal_approval": True,
"authorizes_publication": False,
}
@@ -0,0 +1,56 @@
from copy import deepcopy
from yuqei_sdk.prompt_source_baseline import (
DOMAIN_REVIEW_RUNTIME_IDENTITIES,
NEW_REVIEW_RUNTIME_IDENTITIES,
prompt_source_baseline,
scene_prompt_source_identity,
)
from yuqei_sdk.review_routing import SCENE_REVIEW_ROUTES
def test_current_source_baseline_resolves_all_scene_identities_without_claiming_publication():
baseline = prompt_source_baseline()
assert baseline["module_baseline"]["module_count"] == 14
assert len(baseline["module_baseline"]["drafting"]) == 6
assert len(baseline["module_baseline"]["review"]) == 8
assert len(NEW_REVIEW_RUNTIME_IDENTITIES) == 8
assert len(DOMAIN_REVIEW_RUNTIME_IDENTITIES) == 5
assert baseline["runtime_targets"]["identity_count"] == 14
assert set(baseline["scenes"]) == set(SCENE_REVIEW_ROUTES)
assert baseline["summary"] == {
"scenes": 30,
"source_identities_resolved": 30,
"technical_drafting_coverage_represented": 30,
"technical_review_coverage_represented": 30,
"published_runtime_verified": 0,
"real_model_results": 0,
"authorizes_publication": 0,
}
assert baseline["not_runtime_publication_evidence"] is True
assert baseline["not_legal_approval"] is True
assert baseline["authorizes_publication"] is False
def test_scene_source_identity_keeps_new_modules_and_existing_domain_dependencies_distinct():
new_module = scene_prompt_source_identity("TPL-CONSTRUCTION-PROJECT-001")
domain = scene_prompt_source_identity("TPL-TECHNICAL-CONSULTING-001")
assert new_module["review_route_kind"] == "new_review_module"
assert new_module["review_module_keys"] == ["contract_review_construction"]
assert domain["review_route_kind"] == "existing_domain_prompt"
assert domain["review_module_keys"] == []
assert len(new_module["drafting_module_keys"]) == len(domain["drafting_module_keys"]) == 6
assert new_module["published_runtime_verified"] is False
assert domain["published_runtime_verified"] is False
def test_source_identity_lookups_are_defensive_and_unknown_scenes_do_not_resolve():
first = scene_prompt_source_identity("TPL-TRANSPORT-ORDINARY-001")
original = deepcopy(first)
first["drafting_module_keys"].clear()
second = scene_prompt_source_identity("TPL-TRANSPORT-ORDINARY-001")
assert second == original
assert scene_prompt_source_identity("unknown") is None
@@ -105,6 +105,23 @@ def register_drafting_routes(app: FastAPI, *, settings, repository, evaluation=F
template, _ = store.evaluation_source(item["template_id"])
holdout_scenes.append(scene_holdout_evidence(
item["template_id"], current_template_content_sha256=template.content_sha256))
from yuqei_contract_api.current_source_holdout_plan import (
load_current_source_holdout_plan, scene_current_source_holdout_binding,
)
source_plan = load_current_source_holdout_plan()
source_bindings = []
for item in source_plan["scenes"]:
template, _ = store.evaluation_source(item["template_id"])
source_bindings.append(scene_current_source_holdout_binding(
item["template_id"], current_template_content_sha256=template.content_sha256))
source_plan_summary = {
**source_plan["summary"],
"source_bindings_current": sum(
item is not None and item["source_binding_current"] for item in source_bindings),
"source_bindings_missing": sum(item is None for item in source_bindings),
"source_bindings_stale": sum(
item is not None and item["source_binding_stale"] for item in source_bindings),
}
return {
"schema_version": registry["schema_version"],
"registry_id": registry["registry_id"],
@@ -128,6 +145,24 @@ def register_drafting_routes(app: FastAPI, *, settings, repository, evaluation=F
"not_legal_approval": True,
"authorizes_publication": False,
},
"current_source_holdout_plan": {
"schema_version": source_plan["schema_version"],
"plan_id": source_plan["plan_id"],
"manifest_sha256": source_plan["manifest_sha256"],
"prompt_source_baseline_manifest_sha256": source_plan[
"prompt_source_baseline_manifest_sha256"],
"historical_holdout_registry_manifest_sha256": source_plan[
"historical_holdout_registry_manifest_sha256"],
"summary": source_plan_summary,
"scenes": source_bindings,
"fixture_plan_only": True,
"model_calls": 0,
"live_database_writes": 0,
"not_model_evidence": True,
"not_runtime_publication_evidence": True,
"not_legal_approval": True,
"authorizes_publication": False,
},
"model_calls": 0,
"live_database_writes": 0,
"not_legal_approval": True,
@@ -0,0 +1,148 @@
"""Current-source holdout bindings, distinct from historical model results.
The plan closes fixture/identity registry gaps for every scene. It records no
model outcome and cannot replace the immutable independent holdout registry.
"""
from __future__ import annotations
from copy import deepcopy
from functools import lru_cache
from yuqei_sdk.contract_drafting import draft_digest
from yuqei_sdk.prompt_source_baseline import prompt_source_baseline
from yuqei_sdk.review_routing import SCENE_REVIEW_ROUTES
from yuqei_sdk.scene_review_expectations import REVIEW_EXPECTATION_POLICY
from .contract_templates import get_contract_template
from .holdout_scene_evidence_registry import load_code_owned_holdout_registry
from .template_evaluation_evidence import VARIANTS, scene_model_cases
PLAN_SCHEMA_VERSION = "current-source-holdout-plan.v1"
PLAN_ID = "rc05-current-source-scene-holdout-20261006"
def _plan_payload() -> dict:
baseline = prompt_source_baseline()
historical = load_code_owned_holdout_registry()
historical_by_template = {item["template_id"]: item for item in historical["scenes"]}
scenes = []
for template_id in sorted(SCENE_REVIEW_ROUTES):
template = get_contract_template(template_id)
identity = baseline["scenes"][template_id]
prior = historical_by_template.get(template_id)
cases = scene_model_cases(template_id)
scenes.append({
"template_id": template_id,
"contract_type": template.contract_type,
"template_content_sha256": template.content_sha256,
"prompt_source_baseline_manifest_sha256": baseline["manifest_sha256"],
"draft_prompt": deepcopy(identity["draft_prompt"]),
"review_prompt": deepcopy(identity["review_prompt"]),
"fixtures": [{
"case_id": case["id"],
"variant": case["variant"],
"input_sha256": draft_digest(case["values"]),
"expected_status": case["expected_status"],
"expected_missing": list(case["expected_missing"]),
"review_expectation_policy": REVIEW_EXPECTATION_POLICY,
"review_expected_behavior": (
"identify_missing_fact"
if case["variant"] == "missing-key-fact"
else "complete_full_review"
),
} for case in cases],
"technical_drafting_coverage_represented": len(cases) == len(VARIANTS),
"technical_review_coverage_represented": len(cases) == len(VARIANTS),
"historical_result_reference": ({
"registry_manifest_sha256": historical["manifest_sha256"],
"source_registry_sha256": historical["source_registry_sha256"],
"evaluated_template_content_sha256": prior["evaluated_template_content_sha256"],
} if prior else None),
"historical_results_rebound": False,
"real_model_result": False,
"published_runtime_verified": False,
"legal_source_approval": False,
"authorizes_publication": False,
})
return {
"schema_version": PLAN_SCHEMA_VERSION,
"plan_id": PLAN_ID,
"prompt_source_baseline_manifest_sha256": baseline["manifest_sha256"],
"historical_holdout_registry_manifest_sha256": historical["manifest_sha256"],
"variants": list(VARIANTS),
"scenes": scenes,
"summary": {
"scenes": len(scenes),
"fixture_cases": sum(len(item["fixtures"]) for item in scenes),
"source_bindings_current": len(scenes),
"source_bindings_missing": 0,
"source_bindings_stale": 0,
"technical_drafting_coverage_represented": sum(
item["technical_drafting_coverage_represented"] for item in scenes),
"technical_review_coverage_represented": sum(
item["technical_review_coverage_represented"] for item in scenes),
"historical_model_results_rebound": 0,
"real_model_results": 0,
"published_runtime_verified": 0,
"authorizes_publication": 0,
},
"fixture_plan_only": True,
"not_model_evidence": True,
"not_runtime_publication_evidence": True,
"not_legal_approval": True,
"authorizes_publication": False,
}
@lru_cache(maxsize=1)
def _cached_current_source_holdout_plan() -> dict:
payload = _plan_payload()
summary = payload["summary"]
if (summary["scenes"] != 30
or summary["fixture_cases"] != 30 * len(VARIANTS)
or summary["source_bindings_current"] != 30
or summary["technical_drafting_coverage_represented"] != 30
or summary["technical_review_coverage_represented"] != 30
or any(tuple(item["variant"] for item in scene["fixtures"]) != VARIANTS
for scene in payload["scenes"])):
raise RuntimeError("Current-source holdout plan is incomplete or inconsistent")
return {**payload, "manifest_sha256": draft_digest(payload)}
def load_current_source_holdout_plan() -> dict:
"""Build a deterministic plan from the current template and Prompt sources."""
return deepcopy(_cached_current_source_holdout_plan())
def scene_current_source_holdout_binding(
template_id: str, *, current_template_content_sha256: str,
) -> dict | None:
plan = load_current_source_holdout_plan()
source = next((item for item in plan["scenes"] if item["template_id"] == template_id), None)
if source is None:
return None
current_match = source["template_content_sha256"] == current_template_content_sha256
payload = {
**deepcopy(source),
"plan_id": plan["plan_id"],
"plan_manifest_sha256": plan["manifest_sha256"],
"current_template_content_sha256": current_template_content_sha256,
"current_template_match": current_match,
"source_binding_current": current_match,
"source_binding_missing": False,
"source_binding_stale": not current_match,
}
return {**payload, "binding_sha256": draft_digest(payload)}
def verify_scene_current_source_holdout_binding(
binding: dict, *, current_template_content_sha256: str,
) -> bool:
if not isinstance(binding, dict) or not isinstance(binding.get("template_id"), str):
return False
expected = scene_current_source_holdout_binding(
binding["template_id"],
current_template_content_sha256=current_template_content_sha256,
)
return expected is not None and binding == expected
@@ -674,6 +674,9 @@ class DraftingWorkspaceStore:
from .holdout_scene_evidence_registry import merge_holdout_scene_evidence, scene_holdout_evidence
summary = merge_holdout_scene_evidence(summary, scene_holdout_evidence(
template_id, current_template_content_sha256=current.content_sha256))
from .current_source_holdout_plan import scene_current_source_holdout_binding
summary["current_source_holdout_binding"] = scene_current_source_holdout_binding(
template_id, current_template_content_sha256=current.content_sha256)
runtime_reader = getattr(self.repository, "template_runtime_manifest_reader", None)
runtime = runtime_reader(current, tenant) if runtime_reader else None
from .template_release_readiness import assess_release_readiness
@@ -3,6 +3,7 @@ from datetime import UTC, datetime
import re
from yuqei_sdk.contract_drafting import draft_digest
from yuqei_sdk.prompt_source_baseline import scene_prompt_source_identity
from yuqei_sdk.review_routing import REVIEW_ROUTING_VERSION, scene_review_evaluation_profile, scene_review_route
from yuqei_sdk.scene_review_expectations import REVIEW_EXPECTATION_POLICY
@@ -51,6 +52,12 @@ def assess_release_readiness(template, summary, runtime, *, tenant, now=None):
issue("SCENE_HOLDOUT_TEMPLATE_STALE", "独立留出评测未绑定当前模板正文哈希。")
elif holdout.get("missing_or_failed_variants"):
issue("SCENE_HOLDOUT_DRAFT_COVERAGE", "当前模板仍有独立留出起草变体未通过;开发样本不能覆盖该失败。")
source_holdout = summary.get("current_source_holdout_binding")
source_holdout_valid = False
if source_holdout is not None:
from .current_source_holdout_plan import verify_scene_current_source_holdout_binding
source_holdout_valid = verify_scene_current_source_holdout_binding(
source_holdout, current_template_content_sha256=template.content_sha256)
runtime_valid = isinstance(runtime, dict)
if runtime_valid:
try:
@@ -85,11 +92,29 @@ def assess_release_readiness(template, summary, runtime, *, tenant, now=None):
if runtime and not gate_verification["valid"]:
issue("SCENE_REVIEW_EVALUATION_GATE_INVALID", "代码托管的专项审查证据与当前场景、Prompt 或固定登记簿不一致。")
prompts_aligned = bool(runtime)
expected_source_identity = scene_prompt_source_identity(template.id)
runtime_source_identity_present = bool(runtime and "source_prompt_identity" in runtime)
runtime_source_identity_valid = False
if runtime:
if runtime_source_identity_present:
runtime_source_identity_valid = bool(
runtime.get("source_prompt_identity_resolved") is True
and runtime.get("source_prompt_identity") == expected_source_identity
and all(draft_prompt.get(key) == expected_source_identity["draft_prompt"].get(key)
for key in ("name", "version", "content_sha256"))
and all(review_prompt.get(key) == expected_source_identity["review_prompt"].get(key)
for key in ("name", "version", "content_sha256"))
and runtime.get("published_prompt_alignment_verified") is True
)
if not runtime_source_identity_present:
issue("SCENE_RUNTIME_SOURCE_IDENTITY_MISSING", "运行快照未携带当前源码 Prompt 身份,不能沿用旧版对齐规则放行。")
elif not runtime_source_identity_valid:
issue("SCENE_RUNTIME_SOURCE_IDENTITY_MISMATCH", "运行快照中的源码 Prompt 身份或实际发布内容与当前源码基线不一致。")
prompts_aligned = (runtime.get("provider_mode") == "codex_cli" and runtime.get("model") == "gpt-5.6-sol"
and draft_prompt.get("name") == "contract_drafting_v1" and draft_prompt.get("status") == "published"
and draft_prompt.get("enabled") is True and review_prompt.get("status") == "published"
and review_prompt.get("enabled") is True and review_prompt.get("name") == runtime["requested_review_route"]
and runtime_source_identity_valid
and all(review_prompt.get(key) and review_prompt[key] == trial_prompt.get(key)
for key in ("name", "version", "content_sha256")))
if not prompts_aligned:
@@ -161,9 +186,29 @@ def assess_release_readiness(template, summary, runtime, *, tenant, now=None):
return {"schema_version": "scene-release-readiness.v1", "issues": issues,
"source_applicability_verified": source_verified, "source_references": references,
"published_prompt_alignment_verified": prompts_aligned,
"source_prompt_identity_alignment": {
"manifest_field_present": runtime_source_identity_present,
"source_identity_resolved": expected_source_identity is not None,
"runtime_manifest_matches_current_source": runtime_source_identity_valid,
"expected": expected_source_identity,
"authorizes_publication": False,
},
"missing_draft_variants": missing_draft, "missing_review_variants": missing_review,
"offline_registry_evidence": offline if offline_valid else None,
"holdout_registry_evidence": holdout if holdout_valid else None,
"current_source_holdout_binding": {
"registry_present": source_holdout is not None,
"registry_valid": source_holdout_valid,
"current_template_match": bool(
source_holdout_valid and source_holdout.get("current_template_match")),
"source_binding_current": bool(
source_holdout_valid and source_holdout.get("source_binding_current")),
"fixture_plan_only": True,
"historical_model_results_rebound": False,
"real_model_result": False,
"published_runtime_verified": False,
"authorizes_publication": False,
},
"missing_holdout_draft_variants": (holdout.get("missing_or_failed_variants")
if holdout_valid and holdout else list(VARIANTS)),
"offline_prompt_alignment": {
@@ -0,0 +1,133 @@
from copy import deepcopy
from yuqei_sdk.prompt_source_baseline import prompt_source_baseline
from yuqei_sdk.review_routing import SCENE_REVIEW_ROUTES, scene_review_route
from yuqei_sdk.scene_review_expectations import REVIEW_EXPECTATION_POLICY
from yuqei_contract_api.contract_templates import get_contract_template
from yuqei_contract_api.current_source_holdout_plan import (
load_current_source_holdout_plan,
scene_current_source_holdout_binding,
verify_scene_current_source_holdout_binding,
)
from yuqei_contract_api.drafting_workspace import DraftingWorkspaceStore
from yuqei_contract_api.holdout_scene_evidence_registry import load_code_owned_holdout_registry
from yuqei_contract_api.in_memory_repository import InMemoryContractRepository
def test_current_source_holdout_plan_has_all_scene_fixtures_without_rebinding_results():
baseline = prompt_source_baseline()
historical = load_code_owned_holdout_registry()
plan = load_current_source_holdout_plan()
assert plan["prompt_source_baseline_manifest_sha256"] == baseline["manifest_sha256"]
assert plan["historical_holdout_registry_manifest_sha256"] == historical["manifest_sha256"]
assert {item["template_id"] for item in plan["scenes"]} == set(SCENE_REVIEW_ROUTES)
assert plan["summary"] == {
"scenes": 30,
"fixture_cases": 90,
"source_bindings_current": 30,
"source_bindings_missing": 0,
"source_bindings_stale": 0,
"technical_drafting_coverage_represented": 30,
"technical_review_coverage_represented": 30,
"historical_model_results_rebound": 0,
"real_model_results": 0,
"published_runtime_verified": 0,
"authorizes_publication": 0,
}
assert plan["fixture_plan_only"] is True
assert plan["not_model_evidence"] is True
assert plan["not_runtime_publication_evidence"] is True
assert plan["not_legal_approval"] is True
assert plan["authorizes_publication"] is False
historical_by_template = {item["template_id"]: item for item in historical["scenes"]}
for scene in plan["scenes"]:
source_template = get_contract_template(scene["template_id"])
expected = baseline["scenes"][scene["template_id"]]
assert scene["contract_type"] == source_template.contract_type
assert expected["review_route"] == scene_review_route(
source_template.contract_type, source_template.id)
assert scene["prompt_source_baseline_manifest_sha256"] == baseline["manifest_sha256"]
assert scene["draft_prompt"] == expected["draft_prompt"]
assert scene["review_prompt"] == expected["review_prompt"]
assert [item["variant"] for item in scene["fixtures"]] == list(plan["variants"])
assert {item["review_expectation_policy"] for item in scene["fixtures"]} == {
REVIEW_EXPECTATION_POLICY}
assert {item["review_expected_behavior"] for item in scene["fixtures"]} == {
"identify_missing_fact", "complete_full_review"}
assert scene["historical_results_rebound"] is False
if scene["template_id"] in historical_by_template:
prior = historical_by_template[scene["template_id"]]
assert scene["historical_result_reference"] == {
"registry_manifest_sha256": historical["manifest_sha256"],
"source_registry_sha256": historical["source_registry_sha256"],
"evaluated_template_content_sha256": prior["evaluated_template_content_sha256"],
}
else:
assert scene["historical_result_reference"] is None
def test_scene_current_source_binding_detects_template_or_registry_tampering():
template_id = "TPL-COMMISSION-MARKETING-001"
current_hash = get_contract_template(template_id).content_sha256
binding = scene_current_source_holdout_binding(
template_id,
current_template_content_sha256=current_hash,
)
assert binding["current_template_match"] is True
assert binding["source_binding_current"] is True
assert binding["source_binding_missing"] is False
assert binding["source_binding_stale"] is False
assert verify_scene_current_source_holdout_binding(
binding,
current_template_content_sha256=current_hash,
) is True
stale = scene_current_source_holdout_binding(
template_id,
current_template_content_sha256="0" * 64,
)
assert stale["source_binding_current"] is False
assert stale["source_binding_stale"] is True
assert verify_scene_current_source_holdout_binding(
stale,
current_template_content_sha256="0" * 64,
) is True
tampered = deepcopy(binding)
tampered["review_prompt"]["content_sha256"] = "0" * 64
assert verify_scene_current_source_holdout_binding(
tampered,
current_template_content_sha256=current_hash,
) is False
def test_unknown_scene_has_no_current_source_binding():
assert scene_current_source_holdout_binding(
"unknown",
current_template_content_sha256="0" * 64,
) is None
def test_evaluation_summary_exposes_current_source_plan_without_upgrading_historical_results():
store = DraftingWorkspaceStore(
InMemoryContractRepository(contracts=[]), mode="scene_evaluation")
summary = store.template_evaluation_summary(
"TPL-COMMISSION-MARKETING-001", tenant="default")
current = summary["current_source_holdout_binding"]
assert current["source_binding_current"] is True
assert current["real_model_result"] is False
assert current["published_runtime_verified"] is False
assert current["authorizes_publication"] is False
historical = summary["holdout_registry_evidence"]
assert historical["current_template_match"] is False
assert historical["evaluated_template_content_sha256"] == (
current["historical_result_reference"]["evaluated_template_content_sha256"])
readiness = summary["release_readiness"]
assert readiness["current_source_holdout_binding"]["source_binding_current"] is True
assert readiness["current_source_holdout_binding"]["real_model_result"] is False
assert readiness["prerequisites_satisfied"] is False
@@ -161,6 +161,17 @@ def test_authenticated_registry_endpoint_is_read_only_and_role_guarded(tmp_path)
assert len(holdout["scenes"]) == 12
assert holdout["model_calls"] == holdout["live_database_writes"] == 0
assert not holdout["authorizes_publication"]
source_plan = payload["current_source_holdout_plan"]
assert source_plan["summary"]["scenes"] == 30
assert source_plan["summary"]["fixture_cases"] == 90
assert source_plan["summary"]["source_bindings_missing"] == 0
assert source_plan["summary"]["source_bindings_stale"] == 0
assert source_plan["summary"]["real_model_results"] == 0
assert len(source_plan["scenes"]) == 30
assert source_plan["fixture_plan_only"] is True
assert source_plan["not_model_evidence"] is True
assert source_plan["model_calls"] == source_plan["live_database_writes"] == 0
assert not source_plan["authorizes_publication"]
assert payload["model_calls"] == payload["live_database_writes"] == 0
assert not payload["authorizes_publication"]
repository = app.state.template_evaluation_store.repository
@@ -3,6 +3,7 @@ from datetime import UTC, datetime, timedelta
import pytest
from yuqei_sdk.contract_drafting import draft_digest
from yuqei_sdk.prompt_source_baseline import scene_prompt_source_identity
from yuqei_sdk.review_routing import REVIEW_ROUTING_VERSION, SCENE_REVIEW_ROUTES, scene_review_route
from yuqei_sdk.scene_review_expectations import REVIEW_EXPECTATION_POLICY
from yuqei_sdk.scene_review_coverage import scene_review_coverage
@@ -44,15 +45,16 @@ def evidence():
"""Synthetic identities for policy tests, never a recorded model run."""
trial = DraftingWorkspaceStore(InMemoryContractRepository(contracts=[]), mode="scene_evaluation")
template, _ = trial.evaluation_source(SCENE)
review_name = scene_review_route(template.contract_type, SCENE)
review = {"name": review_name, "version": PROMPT_VERSION,
"content_sha256": PROMPT_CONTENT_SHA256[review_name], "status": "published", "enabled": True}
draft = {**scene_review_coverage(SCENE)["cases"][0]["draft_prompt"], "status": "published", "enabled": True}
source_identity = scene_prompt_source_identity(SCENE)
review = {**source_identity["review_prompt"], "status": "published", "enabled": True}
draft = {**source_identity["draft_prompt"], "status": "published", "enabled": True}
runtime = {"schema_version": "scene-runtime-manifest.v1", "tenant_id": "default", "template_id": SCENE,
"contract_type": template.contract_type, "routing_version": REVIEW_ROUTING_VERSION,
"requested_review_route": review["name"], "draft_prompt": draft, "runtime_review_prompt": review,
"trial_review_prompt": review, "provider_mode": "codex_cli", "model": "gpt-5.6-sol",
"evaluation_gate": evaluation_gate(SCENE, review)}
"evaluation_gate": evaluation_gate(SCENE, review),
"source_prompt_identity": source_identity, "source_prompt_identity_resolved": True,
"published_prompt_alignment_verified": True}
runtime.update(manifest_sha256=draft_digest(runtime), checked_at=datetime.now(UTC).isoformat())
draft_fingerprint = {"prompt_name": draft["name"], "prompt_version": draft["version"], "prompt_sha256": draft["content_sha256"]}
summary = {"template_content_sha256": template.content_sha256, "template_version": template.version,
@@ -127,6 +129,29 @@ def test_summary_top_level_release_flags_reject_cached_claims_and_bad_runtime_ha
assert "SCENE_RUNTIME_UNAVAILABLE" in codes(summary["release_readiness"])
@pytest.mark.parametrize("change", ["missing", "forged"])
def test_runtime_source_identity_is_required_and_cannot_be_forged(change):
template, summary, runtime = evidence()
if change == "missing":
runtime.pop("source_prompt_identity")
runtime.pop("source_prompt_identity_resolved")
expected_code = "SCENE_RUNTIME_SOURCE_IDENTITY_MISSING"
else:
runtime["source_prompt_identity"]["draft_prompt"]["content_sha256"] = "f" * 64
expected_code = "SCENE_RUNTIME_SOURCE_IDENTITY_MISMATCH"
runtime["manifest_sha256"] = draft_digest({
key: value for key, value in runtime.items()
if key not in {"checked_at", "manifest_sha256"}
})
result = assess_release_readiness(template, summary, runtime, tenant="default")
assert expected_code in codes(result)
assert "SCENE_RUNTIME_PROMPT_MISMATCH" in codes(result)
assert result["published_prompt_alignment_verified"] is False
assert result["prerequisites_satisfied"] is False
@pytest.mark.parametrize("change", ["tenant", "hash", "time", "naive_time", "shape", "route", "missing"])
def test_invalid_runtime_never_reuses_cached_alignment(change):
template, summary, runtime = evidence()
@@ -191,13 +216,13 @@ def test_missing_fact_detection_counts_without_claiming_completed_review():
assert not after["authorizes_publication"] and not after["legal_correctness_verified"]
def test_code_owned_review_gate_fills_review_coverage_only_when_hash_and_prompt_match():
def test_code_owned_review_gate_cannot_fill_coverage_for_an_older_draft_identity():
template, summary, runtime = evidence()
summary["review_coverage_by_prompt"] = []
accepted = assess_release_readiness(template, summary, runtime, tenant="default")
assert accepted["missing_review_variants"] == ["missing-key-fact", "opposite-adversarial"]
assert accepted["scene_review_evaluation_gate"]["coverage_eligible"] is True
assert accepted["scene_review_evaluation_gate"]["counted_variants"] == ["normal"]
assert set(accepted["missing_review_variants"]) == set(VARIANTS)
assert accepted["scene_review_evaluation_gate"]["coverage_eligible"] is False
assert accepted["scene_review_evaluation_gate"]["counted_variants"] == []
runtime["evaluation_gate"]["provider_availability_evidence"]["technical_passed"] = 11
runtime["evaluation_gate"]["gate_sha256"] = draft_digest({
@@ -276,7 +301,7 @@ def test_stale_or_truncated_dynamic_summary_cannot_count_coverage(change):
@pytest.mark.parametrize("template_id", sorted(SCENE_REVIEW_ROUTES))
def test_every_scene_counts_exact_current_variants_and_stale_evidence_fails_closed(template_id):
def test_every_scene_rejects_legacy_runtime_without_current_source_identity(template_id):
trial = DraftingWorkspaceStore(InMemoryContractRepository(contracts=[]), mode="scene_evaluation")
template, _ = trial.evaluation_source(template_id)
registered = scene_review_coverage(template_id)
@@ -295,12 +320,10 @@ def test_every_scene_counts_exact_current_variants_and_stale_evidence_fails_clos
result = assess_release_readiness(template, summary, runtime, tenant="default")
assert result["scene_review_evaluation_gate"]["registry_valid"]
assert result["scene_review_evaluation_gate"]["current_template_match"] is expected_match
expected = ({case["variant"] for case in registered["cases"]
if case["draft_prompt"] == registered["cases"][0]["draft_prompt"]}
if expected_match else set())
assert set(result["scene_review_evaluation_gate"]["counted_variants"]) == expected
assert set(result["scene_review_evaluation_gate"]["missing_variants"]) == set(VARIANTS) - expected
assert set(result["missing_review_variants"]) == set(VARIANTS) - expected
assert "SCENE_RUNTIME_SOURCE_IDENTITY_MISSING" in codes(result)
assert result["scene_review_evaluation_gate"]["counted_variants"] == []
assert set(result["scene_review_evaluation_gate"]["missing_variants"]) == set(VARIANTS)
assert set(result["missing_review_variants"]) == set(VARIANTS)
assert not result["authorizes_publication"]