739a477d3f
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>
39 lines
1.1 KiB
Python
39 lines
1.1 KiB
Python
"""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",
|
|
]
|