feat(iace): cross-domain precision overhaul + component review + schema reconcile

Engine precision (stop foreign-machine patterns leaking into a project):
- Wire project.MachineType into the engine machine-type gate (empty input no
  longer fires every machine class — press/cnc/excavator/crane/medical...).
- Capability-domain gating extended by 7 domains (outdoor, ventilation,
  machining, bulk, palletizer, playground, fitness) so domain-specific hazards
  only fire when the narrative names that domain; emitted via keyword_dictionary.
- Relevance backstop moved into iace (single gating contract, testable), and its
  dominant false-anchor class removed (a long pattern word no longer matches a
  short common token; prepositions/leitung added to the generic stoplist).
- New guard tests: TestCrossDomainPrecision (full pipeline, 0 foreign per GT) and
  TestPatternReachability now asserts 0 dead patterns. Both GTs keep coverage 1.0.

Reachability fix: the 51 dead patterns required electrical/pneumatic/hydraulic
tags nothing produced — renamed to the canonical electrical_energy/
pneumatic_pressure/hydraulic_pressure/hydraulic_part.

Component review (negation is best-effort + expert-correctable):
- Parser surfaces negated components (ComponentMatch.Negated) instead of dropping
  them; negated contribute no tags/energy → no phantom hazards.
- presence_status (vorhanden|nicht_vorhanden|geloescht) + ce_marked on components;
  only `vorhanden` feed matching. CE+safety-relevant flags the PL/SIL obligation.
- Force re-seed preserves the expert's component decisions instead of wiping them.
- Tag-based component→hazard assignment (was: all on the first component).
- Negation-aware narrative parsing ("keine Pneumatik" no longer extracts it).

Local-dev DB: ai-sdk sets search_path=compliance,core,public; reconcile migrations
152-156 bring the consolidated local iace tables to the current schema + add the
presence_status/ce_marked columns. Machine-type vocabulary endpoint for the form.

[migration-approved]

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-10 17:15:55 +02:00
parent 3bd4e0aaaf
commit afb3f83f30
47 changed files with 1275 additions and 169 deletions
@@ -37,6 +37,13 @@ type Project struct {
ArchivedAt *time.Time `json:"archived_at,omitempty"`
}
// Component presence states for expert review of auto-detected components.
const (
PresencePresent = "vorhanden"
PresenceAbsent = "nicht_vorhanden"
PresenceDeleted = "geloescht"
)
// Component represents a system component within a project
type Component struct {
ID uuid.UUID `json:"id"`
@@ -48,6 +55,17 @@ type Component struct {
Description string `json:"description,omitempty"`
IsSafetyRelevant bool `json:"is_safety_relevant"`
IsNetworked bool `json:"is_networked"`
// CEMarked: bought component that carries its own CE / Declaration of
// Conformity (finished robot, actuator, drive, safety PLC). SAFE semantics:
// does NOT suppress hazards — only drives provenance/evidence hints and the
// "validate the integrated safety function (PL/SIL)" obligation when also
// safety-relevant.
CEMarked bool `json:"ce_marked"`
// PresenceStatus: vorhanden | nicht_vorhanden | geloescht. Only `vorhanden`
// components feed pattern matching. `nicht_vorhanden` = engine's best-effort
// negation verdict awaiting expert review; `geloescht` = expert removed it
// (kept as a soft-deleted audit row).
PresenceStatus string `json:"presence_status"`
Metadata json.RawMessage `json:"metadata,omitempty"`
SortOrder int `json:"sort_order"`
CreatedAt time.Time `json:"created_at"`