Three ANONYMIZED reference transition scenarios (no real company names stored) = canonical
regression scenarios that test the KNOWLEDGE, not just the engine. Each pins an Expected
Outcome (expected_likely_covered + expected_delta); every commit must reproduce it (identical
or better).
- RTS-001 automotive supplier (TISAX+ISO27001) -> CRA: mature ISMS, standard CRA delta.
- RTS-002 classic machine builder (ISO9001) -> CRA: only process discipline -> MUCH larger delta
(10 missing vs 3 covered). New TP-ISO9001-CRA-v1 pattern (different shape).
- RTS-003 networked machine builder (ISMS) -> CRA: highlights the Data Act.
Data Act is modelled as UNCERTAIN (a hypothesis), never a fixed gilt/gilt-nicht: the generator
checks the engine SURFACES the uncertainty + the deciding question (generates_usage_data) and
never wrongly ASSERTS applicability. All three RTS PASS.
Non-runtime knowledge + reference harness -> no deploy (ADR-001). Names deliberately absent.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Transition KNOWLEDGE Patterns (renamed term -- curated knowledge, not an algorithm):
- 4 maturity levels: draft -> reviewed -> validated (domain expert) -> proven (field). "approved"
dropped; target is validated. TP-ISO27001-CRA set to reviewed (L2).
- 3 enrichments per pattern: confidence_source: relationship (curated, not an LLM estimate ->
computed-not-stored); why_asked (customer-facing: why the source does not suffice here); dropped_if
(what makes the question unnecessary). Applied to TP-ISO27001-CRA.
- New TP-ISMS-TISAX (draft): different character -- info-security module mostly covered; delta is
automotive-specific (prototype protection, TISAX labels, VDA ISA self-assessment, ENX assessment,
Art. 28 data protection). Proves the architecture is GENERIC, not CRA-tailored.
- Reference scenario 4 generalized to loop over ALL patterns through RS-005: both carried (CRA
17->17, TISAX 13->13) -> a living genericity + regression test for every future pattern.
Non-runtime knowledge + reference harness -> no deploy (ADR-001). Next: ISO9001->IATF16949.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
(1) Harden the first Transition Pattern to the gold-standard template per quality checklist:
versioned transition_goal (ISO27001:2022 -> CRA, applies 2027-12-11), source_state_variants
(certified/isms_introduced/expired/limited_scope), each likely_covered assumption with a typed
relationship (supports|partially_supports, never equivalent) + verification + rationale (the Warum)
+ an auditor-checkable reviewable_claim, delta as missing-capability + needed-info, an explicit
rejected_assumptions section, and a determinism_goal. README schema updated to match.
(2) New Reference-Suite scenario 4 (Transition): the generator READS the pattern YAML and runs it
through the RS-005 Planning Engine + Company 2A -> coverage + question requests. Proves the
architecture fully carries the pattern (17 caps -> 17 coverage + 17 requests; 9 HIGH delta = the
real CRA gaps, 8 probably-covered from the ISMS). Now a living regression test: every future pattern
runs through the same engine.
Non-runtime knowledge + reference harness -> no deploy (ADR-001). Next: ISMS->TISAX once approved.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Reasoning session's new Knowledge Acquisition responsibility (re-charter): build and curate
the Transition Knowledge Base under backend-compliance/knowledge/transition_patterns/ (beside
reasoning/, not under it -- it is knowledge, not an engine).
First professional pattern TP-ISO27001-CRA-v1 (status: draft): separates what a mature ISMS
likely covers at the ORG level (probably_covered, needs product-level confirmation, never
auto-"erfuellt") from the CRA-specific delta with no ISO 27001 analogue (SBOM, support period +
secure signed updates, coordinated vulnerability disclosure, Art. 14 authority reporting,
product cyber risk assessment, CE conformity / technical documentation). Expert draft, not a
normative proof; review_required before customer use.
Non-runtime knowledge -> no deploy (ADR-001). Next: ISMS->TISAX.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Aligns the spec with RS-005 v0: the Transition Planning Engine owns the INFORMATION
GAPS (TransitionQuestionRequest), not the questions. Chain: Planning Engine ->
TransitionQuestionRequest -> Question Renderer (RS-005.1) -> Interview. RS-005.1
(renderer/templates) deliberately deferred; GeneratedQuestion reframed as the renderer's
output (a swappable policy layer), not part of the engine.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Second reasoning mode, scope per user: the engine owns the INFORMATION GAPS, not the
questions. assess_transition(context, target_requirements, company_profile) emits
ranked TransitionQuestionRequest {capability, control, reason, question_intent,
expected_evidence, priority, information_gain} -- NOT rendered question text. Rendering
(intent+subject->sentence) is a separate swappable layer (RS-005.1), not here.
Consumes the Company Capability Profile (2A) as "have" + injected TargetRequirement
(Execution-owned placeholder) as "required" -- no required-capability data in product
code (EMPTY_REQUIREMENTS, mocks only in tests). A certification-derived capability is
probably_covered (Welt 1) -> a confirmation request, never already_covered/"erfuellt".
Deterministic, computed-not-stored, no percentages.
Activates 2A/2C/RCI (first consumer of the Company profile). Freeze-respecting: additive
package, no new graph/base class/meta-model class. 9 tests, mypy --strict clean, LOC ok.
No endpoint/UI/RAG; question rendering deliberately deferred to RS-005.1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v1.1: interview questions are GENERATED from the existing (Master) Controls, not
hand-written. Three building blocks: Control->question_intent (corpus/Execution),
~30-40 Master Question Templates (Reasoning), Transition-Prioritization (certs decide
which generated questions can be skipped; 217->19 funnel, reuses Company 2A + cert map).
v1.2: knowledge production. LLMs produce the first expert DRAFT (the prioritization per
transition); BreakPilot reviews + versions + OWNS the canonical library (in Git, not the
AI; model-independent, MDQ-00127 v4). Offline multi-model workflow, NOT runtime
(deterministic-first: LLM offline-propose, never online-mutate). Hard boundary: the
library is an expert DRAFT, not a normative/legal proof -- "cert probably covers X" is
Welt-1 (ClaimCoverage), never "erfuellt" (anti-fake-evidence).
Reframes the 100 seed questions as validation/template-extraction set. Spec only, no
code; non-runtime docs -> no deploy (ADR-001).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Second reasoning mode (extends, does not replace): BreakPilot answers MIGRATION
questions (start state -> target state -> delta), not regulation Q&A. New package
compliance/transition_reasoning/ (spec only). Transition Reasoning is RCI
generalized; reuses Company 2A (have), Master Capability Registry (MCAP) and RCI.
MDQ Registry = 4th identity-machine instance (after Master Controls/Obligations/
Capabilities): every Master Delta Question is a versioned, identifiable knowledge
unit (verifies MCAP, supports obligations, transition patterns, evidence types,
information gain, confidence impact, follow-up). Transition Patterns hold only MDQ
references -> reuse across transitions. Delta interview = information-gain
optimization, not a sequential questionnaire.
ADR-002: transitions are DATA (patterns + capability/MDQ knowledge), never engine
or metamodel extensions. 100 seed questions captured as v1.
Spec only (no code; freeze-respecting: additive package, no new graph/base class/
meta-model class). Non-runtime docs -> no deploy (ADR-001).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
A dev deploy must always have a verifiable runtime effect. Deploy only on
runtime/API/data-model/reasoning/security changes; docs, reference suites, ADRs,
board and ownership texts are merged to origin/main but NOT pushed to dev (no Orca
build). Keeps the CI/CD history meaningful: every build == a runtime change.
Architecture/release decision (not a developer convention) -> own folder
docs-src/architecture/adr/. Non-runtime: this commit triggers no deploy, per its
own policy.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three real customer scenarios driven through the DEPLOYED engines (scope/map/
interpretation, RCI, company 2A, capability registry). Each scenario emits an
Architecture Coverage table DERIVED from the real run, so cells flip automatically
as domains land (e.g. Sz2/Environmental UNSUPPORTED -> PASS). The roll-up answers
"is BreakPilot better than six months ago" by real customer situations, not LOC.
Gaps captured as epics (NOT implemented): RS-001 Interpretation Pattern Library,
RS-002 Environmental Corpus, RS-003 Capability Linking (cap<->MCAP) + Company-Gap,
RS-004 MaschinenVO/EMV Registry Linking.
reference_scenarios/generate.py = reproducible source (ruff/mypy-exempt, NOT product
code, not imported by the app); reference_scenario_suite_v1.md = generated artifact.
No new product code; CRA patterns deliberately NOT built — the suite is now the measure.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User-Reframe (die eigentliche Reife): nicht „Session X besitzt Knoten Y", sondern jede Session
besitzt KANTEN. Edge-Ownership-Tabelle: Feature/Cert->Cap = S3 · Cap->Obligation/Procedure/
Control/Evidence = S2 · Citation-Span->Legal-Basis = S1. Kein Owner hält alle ein+ausgehenden
Kanten eines Knotens. `cap.*` = kanonische ID auf obligation_id-Niveau. Capability = EINZIGER
Knoten über 3 Welten (Recht/Produkt/Nachweis) = semantischer Mittelpunkt. Künftiger Vertrag:
Confidence/Disambiguierung bei mehreren Capabilities = Domaene 3, Domaene 2 vertraut geliefertem
cap.X. Domaene 2 ruht stabil bis Wake-up.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Third instance of the identity-machine pattern (after Master Controls and Master
Obligations). New compliance/capability/ package: MasterCapability with stable MCAP
ids, CapabilityCandidate minting, seven typed relation types, a VERSIONED derivation
policy, and identity lifecycle (merge/split/deprecate/redirect with provenance).
Stored: identities, sources, relationship types, policy versions, lifecycle events,
provenance. Derived (never stored): confidence/status via evaluate_relation under a
policy version. Hard rule (structurally guarded): a certification alone can never
yield CONFIRMED — only CONFIRMS + concrete artifact (or expert) does.
Built from the Reasoning session per user directive but this IS the Compliance
Execution model (Execution owns Capability) — handed off via the board. Metadata-first:
CapabilityRelation is registry metadata, NOT a new meta-model class (freeze v1.0
untouched). No Company-Gap, no real ISO/cert mappings, no UI/RAG, no generic
canonicalization engine. 11 tests; mypy --strict clean; LOC ok.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HEAD of the spine Company->Capability->Product->Regulation->Obligation->Procedure
->Evidence. New compliance/company/ package: CompanyContext container + a four-state
trust model (declared/inferred/confirmed/unknown).
Hard rule (structural): a certification yields at most an INFERRED candidate and is
never auto-treated as CONFIRMED/"erfuellt". A certification produces evidence-of-
capability; only real ExistingEvidence promotes a capability to CONFIRMED.
Ownership: Reasoning owns the container + trust-state; the Certification->Capability
mapping is Execution's domain, consumed via an injected contract. No mapping data in
product code (tests inject mocks). No endpoint/UI/RAG/new regs/controls; no meta-model
classes (freeze v1.0 untouched). 8 tests; mypy --strict clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
RCI/Delta as a read-/reasoning layer ON TOP of the product-first pipeline. Answers
"what changes relative to my existing Regulatory Map?" — NOT "what does the new
law say in general". No UI, no ingestion (newsletter/mailbox), no RAG, no new
regulations/controls, no legal evaluation outside the stored map.
- 4 core objects (compliance/rci/schemas.py): ComplianceBaseline (snapshot of
profile + map + registry obligations + required/present evidence), RegulatoryChange
(simulated/provided INPUT), ObligationDelta (delta_type NEW|CHANGED|REMOVED|
ALREADY_COVERED|NEEDS_REVIEW|NOT_APPLICABLE), ChangeImpactSummary. delta_type is a
THIRD vocabulary, disjoint from ClaimCoverage (Welt 1) and ComplianceStatus (Welt 2).
- create_baseline() snapshots the existing pipeline once; assess_change() computes
deltas deterministically against the snapshot (no re-evaluation).
- 12 tests = the 5 acceptance questions (affects product? new/changed? already
covered by evidence? needs human review? not relevant?) + repeal/uncertain-reg/
missing-evidence/boundary. Existing pipeline tests stay green; mypy clean; LOC ok.
- App/reasoning types only — no compliance-meta-model classes (freeze v1.0 untouched).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User-Praezisierung: Domaene 2 ruht NICHT unbestimmt. Wake-up-Trigger (EINER reicht):
Feature Graph>=200 Features · Span-Anker verfuegbar · neue Regulierung ingestiert · Runtime
kennt neue Evidence-Typen. Erster Folgeauftrag (gated auf Feature Library v1):
FEATURE COVERAGE REPORT = Wissenslueckenanalyse pro Feature (Feature->cap.*->Obligation->
Procedure->Evidence -> Coverage %; zeigt fehlende Capability/Procedure/Evidence je Feature).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Thin adapter — it judges the customer's reading WITHIN the already-built
RegulatoryMap, it does not assess abstract legal questions and it is not RCI.
- Reuses the existing assess_interpretation (no new legal reasoning); the 6
verdicts (plausible/too_narrow/too_broad/partially_correct/unsupported/uncertain)
pass through unchanged.
- Restricts affected_regulations/affected_obligations to those present in the map
(intersection); links to the map's uncertain regulations.
- Touched unsupported domains (wastewater/chemicals/...) are reported as
future_corpus_domains (future_corpus_needed) — never pseudo-evaluated.
- Customer-readable explanation ("Ihre Interpretation ist wahrscheinlich zu eng. …
Betroffen in Ihrer Map: CRA.").
- POST /reasoning/interpretation-in-map (renders the map, then interprets).
- 7 tests; 63 green (existing reasoning MVP stays green), mypy clean, LOC ok.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Map Renderer explains the engine's state, it does not extend it. Pure
composition of resolve_product_scope (scope verdict) + derive_obligations
(registry-linked obligations + overlaps) into one RegulatoryMap.
- product_summary, trigger_facts, applicable/uncertain/excluded regulations,
unsupported_domains, overlaps (shared_obligations), shared_evidence, and a
customer-readable executive_summary.
- No own legal decisions: applicable/uncertain mirror the scope verdict exactly.
- Obligations shown ONLY when registry-linkable (registry_anchor) — MaschinenVO/
EMV obligations are proposed, so they render empty + a note, never as linked.
Overlaps/shared_evidence likewise filtered to registry-linked members.
- Uncertain regulations link to the navigator question that would resolve them
(RED -> has_radio_module, DataAct -> generates_usage_data).
- Environmental appears only as unsupported_domain; executive_summary has NO
percentage (counts + "no further regulations identified" instead).
- POST /reasoning/regulatory-map (thin handler). Response types are presentation-
level, not meta-model classes (freeze v1.0 untouched).
- 9 tests; 56 green (existing reasoning MVP stays green), mypy clean, LOC ok.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Completes the proposer's four types.
- FindCoverageGaps (proposer_coverage.go): deterministic — which EN ISO 12100
hazard groups A-G did the engine leave with zero hazards for this machine? An
empty group is a structural blind-spot signal (the machine may truly lack it,
or a pattern/GT case is missing). Useful with no model at all.
- ProposeMissingHazards + BuildCoveragePrompt: optional LLM expansion of each gap
into specific expected-but-missing hazards a safety assessor would name
(propose-only, reuses LLMCompleter, degrades to nil on any error).
- Wired into iace-audit propose -> audit-reports/coverage.{md,json}.
On the dishwasher: D. Pneumatik (truly absent — nothing invented), E. Laerm
(borderline), F. Ergonomie (a genuine gap: manual loading the engine did not
produce). P3 (pin an accepted proposal into a GT case) remains as a human-in-the-
loop follow-up.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Extends Method C: for each unknown narrative token that pattern text names, suggest
the keyword_dictionary tag = the RequiredComponentTags shared by the naming
patterns (ranked by frequency, kept only when shared by >=40% of them, top 3).
Surfaces real dictionary gaps like "zwischenkreis" -> stored_energy and
"updates" -> has_software, which close coverage without hand-editing the dict.
Two precision fixes to Method C while here:
- patternsMentioning now matches WHOLE WORDS, not substrings — substring matching
flagged fragments like "stehen" inside "entstehen" and produced nonsensical
tag suggestions.
- a token is only proposed with a tag if one is shared by >=40% of its naming
patterns, so diffuse common verbs (spread across categories) drop out.
Wired into iace-audit propose -> audit-reports/vocab.{md,json}. Residual
common-verb noise is left to the human/LLM filter rather than a hand-grown
stopword list. Type 4 (coverage blind spots) + P3 (pin accepted proposals into a
GT case) remain for slice 6.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Surfaces fired patterns whose zone names terms the machine's narrative never
mentions — foreign framing that leaks through terms not yet in domainGateTerms
(once a term is a gate term, the ghost-pattern invariant already fences it out).
- FindFramingCandidates (proposer_framing.go): per fired pattern, zone terms with
no narrative echo (minus a generic hazard-location stoplist). Echo matching is
bidirectional to survive German compounding (narrative "Steuerung" echoes zone
"Steuerungssystem"). Heuristic verdict foreign (fully orphan) / plausible
(partial). Over-surfaces by design — human/LLM is the precision filter.
- Wired into iace-audit propose -> audit-reports/framing.{md,json}, threshold via
IACE_FRAMING_MIN_ORPHAN (default 0.6).
Honest finding: genuine wrong-MACHINE framing (Walzen, Transportbaender) no longer
fires thanks to the machine-type gate; the residual is mostly cyber/control
patterns with generic-industrial zone vocabulary, candidates for re-framing.
Proposal types 3-4 (vocab->tag, coverage blind spots) remain for slice 5.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Makes the offline proposer runnable end-to-end.
- BuildProposerInput (proposer_input.go): non-test engine->hazards path. The
PatternMatch->Hazard converter is lifted out of the GT test files into
production scope so both the tests and the CLI share one pipeline.
- iace-audit propose <narrative.json> [<ground-truth.json>]: detect candidates ->
GT-screen survivors (when a ground truth is given) -> judge (HeuristicJudge by
default, LLMJudge over ollama when IACE_PROPOSE_LLM=1) -> write the human-review
queue to audit-reports/proposals.{md,json}. Propose-only.
Smoke run on a dishwasher narrative: 32 fired -> 3 candidates -> queue with a
confident duplicate, a confident distinct, and one punted to the LLM judge; GT
wall recall-safe. Live qwen is opt-in via env; the heuristic default keeps the
tool runnable (and CI deterministic) without a model. Proposal types 2-4
(foreign-framing gates, vocab->tag, coverage blind spots) remain for slice 4.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the semantic judgement layer on top of the slice-1 detector + GT wall.
DEV-TIME, propose-only — nothing mutates the library or runtime.
- CandidateJudge interface with two implementations: HeuristicJudge
(deterministic default/fallback, used in tests) and LLMJudge (offline, over the
shared llm.ProviderRegistry via the LLMCompleter adapter). LLMJudge degrades to
"uncertain" on any transport/parse error — it can never break a run.
- BuildJudgePrompt: the ISO 12100 same-vs-distinct prompt, unit-tested
deterministically even though the call is not.
- RenderProposalQueue: markdown human-review queue with a suggested action per
candidate (supersede / keep both / needs review).
On real warewashing output the heuristic punts to "uncertain — needs the LLM
judge" for exactly the two recall-safe near-dupes (HP807/HP033 update,
HP101/HP096 winding-vs-friction), making the LLM's role explicit. All 3 GTs
unaffected (read-only). Live qwen wiring + a CLI/file queue are slice 3.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
First thin slice of the offline library-improvement proposer. DEV-TIME ONLY,
propose-only — it never mutates the pattern library or the runtime.
- FindDedupCandidates (proposer_dedup.go): structural near-duplicate detection
over the fired patterns (category + measure/zone/scenario overlap). Bakes in
the P1 lesson: only same-category pairs compare, and pairs with different
operational states are never proposed (normal-operation vs maintenance are
legitimately distinct, e.g. HP011 vs HP077).
- ScreenSupersession (proposer_screen.go): the wall. A proposal is safe only if
(1) dropping the hazard does not reduce GT recall AND (2) keep/drop do not
credit DIFFERENT GT entries. Check 2 catches distinct hazards that merely share
measures (HP2201 hot surface GT 1.3 vs HP2202 hot ware GT 1.4) which recall
alone would wave through.
On real warewashing output: 3 candidates -> 1 BLOCKED (distinct GT), 2
RECALL-SAFE for human/LLM review (the update + winding/friction near-dupes).
Nothing auto-applied. All 3 GTs unaffected (read-only). The LLM judgement and a
CLI/file queue are slice 2.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HP013 (stored electrical energy) fires for dishwashers via the broad stored_energy
tag but its zone is framed for Batteriefaecher/USV-Anlagen, which a dishwasher does
not have. The precise residual-voltage pattern HP144 (Frequenzumrichter/Zwischenkreis,
Priority 90) already fires and covers the same hazard. Add HP013 to the
warewashing-scoped supersession set so the duplicate is dropped only when
dom_warewashing is present.
Warewashing recall stays 100% (25/25), precision 92.6% -> 96.2%. Kistenhub/Bremse
keep HP013 (no dom_warewashing); 26 Bremse pins + benchmark unaffected.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The generic hot-surface patterns HP016 (high_temperature) and HP018 (actuator
burn) fire for dishwashers via broad tags and duplicate the precise warewashing
pattern HP2201 (Boiler/Tank/Spuelkammer). Suppress HP016/HP018 only when
dom_warewashing is present, so the specific pattern wins and the duplicate is
dropped. Scoped to the domain tag -> Kistenhub/Bremse and every non-warewashing
machine keep the generic patterns unchanged.
Warewashing recall stays 100% (25/25), precision 90% -> 92.6% (2 dupes removed).
Bremse 26 pins and Kistenhub benchmark unaffected.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ListHazards returned hazards in pattern-firing order, which reads as a jumble.
Sort by EN ISO 12100 hazard group (A. Mechanisch, B. Elektrisch, C. Thermisch,
D. Pneumatik/Hydraulik, E. Laerm, F. Ergonomie, G. Stoffe, H. Software/Steuerung,
I. Cyber, J. KI), stable within a group. Matches the frontend CATEGORY_LABELS.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HP1717 was gated on the generic stored_energy tag (carried by a frequency
converter's DC link) + pneumatic_pressure (emitted by "Boiler unter Druck"),
so it leaked into the dishwasher despite the absence of any pneumatics. Require
pneumatic_part instead. The Bremse pin is a static pattern->measure check
(unaffected); full suite incl. Bremse coverage and Kistenhub 97.1% unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HP753 (lithium thermal runaway), HP754 (battery off-gassing) and HP755 (HV
battery shock) were gated on stored_energy, which a frequency converter (C034,
DC-link capacitors) legitimately carries — so they leaked into any machine with
a VFD (surfaced by the dishwasher after the Frequenzumrichter narrative). Now
require the "battery" tag; add lithium/batteriespeicher synonyms so real
battery-storage machines still emit it.
GT #3 100% recall unchanged, battery themes gone from the dishwasher log;
Kistenhub 97.1% and Bremse pinned mappings unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User-Antwort auf „wie verteilen wir die Arbeit": nach BESITZ der Datenmodelle, NICHT nach
Regulierung. 3 Domaenen (Legal Knowledge / Compliance Execution / Product Knowledge), jede
besitzt EIN Modell (andere read-only). 3 Vertraege: Legal->Compliance citation_span->legal_basis ·
Product->Compliance Feature->Capability (WICHTIGSTE Schnittstelle) · Compliance->Legal
obligation_id->legal_basis. Product Knowledge Graph = naechster Meilenstein (Reasoning-Session
umfokussieren, besitzt schon CanonicalProductRegulatoryProfile+Navigator). NIS2 verschoben.
Offene Fragen: Legal-KG-Owner, IACE-4.-Session, Compliance-2-Branch-Split.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Connects the Navigator's fact-gate to the existing reasoning discover_scope —
the Scope Engine decides only once the minimum (P0) facts are released.
- resolve_product_scope(canonical): if not ready_for_scope -> NEEDS_FACTS
(missing_facts + suggested_questions, discover_scope NOT run); else project
canonical->reasoning profile and run the EXISTING discover_scope exactly once
-> RESOLVED with applicable/excluded/uncertain regulations.
- Environmental triggers surface ONLY as unsupported_domains (future_corpus_needed),
never as a legal evaluation — transparency, no false completeness.
- POST /reasoning/product-scope (thin handler) returns case NEEDS_FACTS or RESOLVED.
- No new scope rules, no new regulations, no environmental-law evaluation, no UI,
no Go, no RAG, no percent-compliance. Response types are application-level, not
meta-model classes (freeze v1.0 untouched).
- 6 tests incl. discover_scope spy (0 calls when gated, exactly 1 when ready),
category separation, environmental-as-unsupported-only. 47 tests green (existing
reasoning MVP tests stay green), mypy clean, LOC ok.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 2 of the convergence sequence. The Navigator sits over the
CanonicalProductRegulatoryProfile (prefilled from company-profile / ProductWizard)
and reports ONLY which facts are still missing + prioritized questions to collect
them. It decides which facts are needed, NEVER what applies — that stays with the
Scope Engine (step 3). No regulation logic, no UI, no Go, no RAG.
- NavigatorQuestion (interaction type, NOT a compliance-meta-model class — freeze
v1.0 untouched): question_id, target_field, label, why_needed,
regulatory_domains_unblocked (static metadata), answer_type, options, priority.
- QUESTION_CATALOG: 12 questions over canonical gaps — P0 (markets, role,
lifecycle, machine/component), P1 (radio, usage-data, security-function,
environmental wastewater/air/chemicals triggers), P2 (structured BOM).
- engine: navigate() -> missing_facts + suggested_questions (priority-sorted) +
completeness_summary (ready_for_scope = no P0 missing); apply_answers() ->
updated profile. Pure field-presence; no scope import.
- 8 tests: <=10 questions for a filled company-profile, known facts not re-asked,
environmental = trigger questions only (no law evaluation), apply round-trip,
P0 ordering, ready_for_scope. 41 tests green, mypy clean, LOC ok.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>