"""Certification Capability Hypotheses — capability-centric, with EMPIRICAL (computed) confidence. Each hypothesis is its own knowledge object: "IF a company holds one of `supported_by` certs, we EXPECT `capability` (verification required)" — Welt-1, never "erfüllt". Written ONCE per capability with a list of supporting certs (reuse, not redundancy), so multi-certification merges AUTOMATICALLY. `confidence` is NOT an expert/LLM score: it is COMPUTED from real-onboarding observations (confirmed / (confirmed+refuted)), `None` until any are seen. This is the empirical learning loop — the long-term moat. The library is DATA, loaded outside this module and injected. Python 3.9 compatible. """ from __future__ import annotations from typing import Dict, List, Sequence from pydantic import BaseModel, Field class CapabilityHypothesis(BaseModel): """Curated knowledge only. Confidence is NOT stored here — it is computed from the reviewed observation stream (see observations.py); a raw answer never changes a hypothesis (review gate).""" id: str capability: str supported_by: List[str] = Field(default_factory=list) # certifications that suggest this capability relationship: str = "supports" # supports / partially_supports verification_required: bool = True # Welt-1: never auto-satisfied question_intent: str = "verify_existence" expected_evidence: List[str] = Field(default_factory=list) kind: str = "shared" # shared / specific def inferred_hypotheses( certifications: Sequence[str], library: Sequence[CapabilityHypothesis] ) -> List[CapabilityHypothesis]: """Every hypothesis whose `supported_by` intersects the company's certs — the auto multi-cert merge.""" certs = set(certifications) return [h for h in library if certs & set(h.supported_by)] def resolve_for_certifications( certifications: Sequence[str], library: Sequence[CapabilityHypothesis] ) -> Dict[str, List[str]]: """Adapt the capability-centric library to the Advisor's `cert -> [capability]` input. For each held certification, the capabilities its hypotheses suggest (deduped, deterministic order). """ certs = set(certifications) out: Dict[str, List[str]] = {} for h in library: for cert in h.supported_by: if cert in certs and h.capability not in out.setdefault(cert, []): out[cert].append(h.capability) return {c: out[c] for c in sorted(out)}