Files
GEWU/tests/domain/proposal_fixtures.py
T

212 lines
6.5 KiB
Python
Raw Normal View History

"""Golden pilot proposal fixtures for deterministic evidence and policy checks."""
from datetime import UTC, datetime
from gewu.domain.contracts import (
AutoAcceptPolicy,
Claim,
Confidence,
EvidenceReference,
ExtractionBlock,
ExtractionRecord,
KnowledgeNode,
LensFit,
Lifecycle,
Locator,
NodeType,
ProjectRecord,
ProjectStatus,
ProposalOperation,
ProposalRevision,
ReliabilityGrade,
ReviewState,
Scope,
SourceRevisionRecord,
SupportAssessment,
SupportStatus,
)
from gewu.domain.validation import (
assertion_digest,
evidence_digest,
extraction_digest,
proposal_payload_digest,
)
BASE_COMMIT = "1" * 40
NOW = datetime(2026, 10, 13, tzinfo=UTC)
SOURCE_REVISION = SourceRevisionRecord(
source_id="shared:pilot-report",
revision_id="shared:pilot-report:r1",
artifact_sha256="2" * 64,
media_type="text/markdown",
byte_length=100,
captured_at=NOW,
original_url=None,
title="Pilot dome installation report",
authors=("Pilot team",),
publisher="GEWU fixtures",
license="internal",
source_type="internal",
reliability_grade=ReliabilityGrade.MEDIUM,
ingested_for=("dome-performance",),
archive_status="archived",
)
BLOCK_TEXT = "The installation hosted 400 visitors during the 2026 season."
_EXTRACTION_UNHASHED = ExtractionRecord(
extraction_id="0" * 64,
source_revision_id=SOURCE_REVISION.revision_id,
parser_name="gewu-text",
parser_version="0.1.0",
parser_config_sha256="4" * 64,
normalization_profile="unicode-nfc-lf-v1",
status="complete",
blocks=(
ExtractionBlock(
block_id="block-1",
ordinal=0,
original_text=BLOCK_TEXT,
normalized_text=BLOCK_TEXT,
normalization_map=tuple((index, index + 1) for index in range(len(BLOCK_TEXT))),
page=None,
),
),
)
EXTRACTION = _EXTRACTION_UNHASHED.model_copy(
update={"extraction_id": extraction_digest(_EXTRACTION_UNHASHED)}
)
CLAIM_TEXT = "The installation hosted 400 visitors during the 2026 season."
CLAIM_DIGEST = assertion_digest(CLAIM_TEXT)
START = 0
END = len(BLOCK_TEXT)
EVIDENCE = EvidenceReference(
source_revision_id=SOURCE_REVISION.revision_id,
extraction_id=EXTRACTION.extraction_id,
assertion_path="claims[0].text",
assertion_digest=CLAIM_DIGEST,
quote=BLOCK_TEXT,
locator=Locator(kind="text_span", block_id="block-1", start=START, end=END),
normalization_profile="unicode-nfc-lf-v1",
)
CLAIM = Claim(
claim_id="dome:claim-visitors",
text=CLAIM_TEXT,
evidence_type="reported",
evidence=(EVIDENCE,),
assessment=SupportAssessment(
assessment_id="assessment-1",
assertion_digest=CLAIM_DIGEST,
evidence_digests=(evidence_digest(EVIDENCE),),
assessor_id="agent-pilot",
run_id="run-pilot-1",
method="paired source claim check",
status=SupportStatus.SUPPORTED,
rationale="The quoted sentence states the count and period.",
),
)
NODE = KnowledgeNode(
node_id="dome:season-visitors",
project_id="dome-performance",
node_type=NodeType.DATAPOINT,
title="Dome season visitors",
summary="The installation hosted 400 visitors in the 2026 season.",
created=NOW,
updated=NOW,
review_state=ReviewState.DRAFT,
lifecycle=Lifecycle.ACTIVE,
confidence=Confidence.MEDIUM,
claim_support="supported",
tags=("attendance",),
audience=("product",),
domain=("production",),
use_for=("comparison",),
lens_fit={
"dome-performance": LensFit(
score=0.9,
horizon="H1",
key_question="How do audiences engage?",
reason="Reports a representative audience measure.",
),
},
run_id="run-pilot-1",
agent_id="agent-pilot",
model_id="fixture-model",
claims=(CLAIM,),
as_of=NOW,
stale_after=datetime(2027, 1, 1, tzinfo=UTC),
value=400,
unit="visitors",
sample_size=None,
reporting_year=2026,
)
PROJECTS = {
"dome-performance": ProjectRecord(
project_id="dome-performance",
title="Dome interactive content",
status=ProjectStatus.ACTIVE,
north_star="Create compelling interactive experiences for dome audiences.",
key_questions=("How do audiences engage?",),
autonomy_policy_id="dome-policy",
),
"interactive-video": ProjectRecord(
project_id="interactive-video",
title="Interactive video",
status=ProjectStatus.ACTIVE,
north_star="Understand useful interactive video experiences.",
key_questions=("How do teams control branching?",),
autonomy_policy_id="video-policy",
),
}
POLICIES = {
"dome-policy": AutoAcceptPolicy(
policy_id="dome-policy",
policy_version=1,
project_id="dome-performance",
automatic_node_types=("datapoint", "problem", "technique", "case"),
automatic_source_registration=True,
require_supported_assessment=True,
),
"video-policy": AutoAcceptPolicy(
policy_id="video-policy",
policy_version=1,
project_id="interactive-video",
automatic_node_types=("datapoint", "problem", "technique", "case"),
automatic_source_registration=True,
require_supported_assessment=True,
),
"shared": AutoAcceptPolicy(
policy_id="shared",
policy_version=1,
project_id="shared",
automatic_source_registration=True,
require_supported_assessment=True,
),
}
def proposal(
*,
node: KnowledgeNode | None = NODE,
source: SourceRevisionRecord | None = SOURCE_REVISION,
scope: Scope | None = None,
base_commit: str = BASE_COMMIT,
) -> ProposalRevision:
operations = tuple(
operation
for operation in (
ProposalOperation(operation="register_source", source=source) if source else None,
ProposalOperation(operation="upsert_node", node=node) if node else None,
)
if operation is not None
)
candidate = ProposalRevision(
proposal_id="proposal-pilot-1",
revision=1,
initiating_project_id="dome-performance",
scope=scope or Scope(projects=("dome-performance",), include_shared=True),
base_commit=base_commit,
payload_digest="0" * 64,
proposer_id="agent-pilot",
run_id="run-pilot-1",
operations=operations,
)
return candidate.model_copy(update={"payload_digest": proposal_payload_digest(candidate)})