feat(profile): CanonicalProductRegulatoryProfile convergence layer (types + mappers + tests)
ONE canonical product profile so the Go gap engine and the Python reasoning
engine stop diverging ("SPS mit Remote Access" means the same everywhere).
gap.ProductProfile LEADS; the reasoning ProductProfile becomes an adapter/DTO.
Types + mappers only — no regulation logic, no Go changes, no UI, no new questions.
- CanonicalProductRegulatoryProfile mirrors gap.ProductProfile + the Navigator
gaps the audit found: economic-operator role, radio_module, generates_usage_data,
lifecycle_phase, structured BOM (ProductComponent), safety-vs-security split,
machine-vs-component + a forward-looking EnvironmentalImpact domain (wastewater/
air/chemicals triggers — fields only, no rules yet).
- Mappers: from_product_wizard (lossless), from_company_profile (prefill incl.
the machineBuilder block), to_gap_profile (emits the unchanged gap JSON shape),
to_reasoning_profile (projects into the reasoning ProductProfile; AI stays
delegated to ai-act/ucca). Only profile->reasoning is coupled; reasoning stays
hermetic.
- 10 tests = the 10 acceptance criteria incl. ProductWizard round-trip lossless,
markets no longer forced ['EU'], and canonical->reasoning->discover_scope
proving one semantic profile drives the engine. 33 tests green, mypy clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
"""Product profile convergence layer.
|
||||
|
||||
ONE canonical product profile (`CanonicalProductRegulatoryProfile`) that the Go
|
||||
gap engine and the Python reasoning engine both project from — so "SPS mit
|
||||
Remote Access" means the same thing everywhere. gap.ProductProfile leads; the
|
||||
reasoning ProductProfile is an adapter/DTO. Types + mappers only — no regulation
|
||||
logic, no UI, no new questions.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .canonical import (
|
||||
CanonicalLifecyclePhase,
|
||||
CanonicalProductRegulatoryProfile,
|
||||
CanonicalProductType,
|
||||
ComponentKind,
|
||||
EconomicOperatorRole,
|
||||
EnvironmentalImpact,
|
||||
ProductComponent,
|
||||
)
|
||||
from .from_company_profile import from_company_profile
|
||||
from .from_product_wizard import from_product_wizard
|
||||
from .to_gap import to_gap_profile
|
||||
from .to_reasoning import to_reasoning_profile
|
||||
|
||||
__all__ = [
|
||||
"CanonicalProductRegulatoryProfile",
|
||||
"CanonicalProductType",
|
||||
"EconomicOperatorRole",
|
||||
"CanonicalLifecyclePhase",
|
||||
"ComponentKind",
|
||||
"ProductComponent",
|
||||
"EnvironmentalImpact",
|
||||
"from_product_wizard",
|
||||
"from_company_profile",
|
||||
"to_gap_profile",
|
||||
"to_reasoning_profile",
|
||||
]
|
||||
Reference in New Issue
Block a user