feat(iace): OSHA minimum-distance library — Task #18
Verbatim OSHA 29 CFR 1910 Subpart O values anchored as the rechtssicher zitierbare Werte-Basis for the IACE engine. Per strategy discussion (2026-05-20) US Federal Code is the only public-domain corpus we can reproduce wholesale; DIN/EN values stay identifier-only. Coverage in this initial batch: - MD_OSHA_O10_R1, MD_OSHA_O10_R4 (Table O-10 rows 1 + 4 — point of operation guard distance vs max opening width) - MD_OSHA_212_FAN (§1910.212(a)(5) fan-blade guards: 1/2 in) - MD_OSHA_217_PSDI (§1910.217 hand-speed constant 63 in/s for presence-sensing-device-initiation and two-hand-trip distances) Each entry carries four parallel value sets: - OriginalValue/Min/Max in source unit (verbatim, R1) - ExactMM via deterministic conversion (mathematics, no copyright) - RecommendedMM with safe-side rounding documented in RoundingNote - EUNormHints — identifier-only references to EN ISO 13857, EN 13855, EN 349 with a human-curated DINComparisonNote (qualitative judgement, not a copy) Open follow-ups (separate iterations): - Full Table O-10 (rows 2-10) — same shape - §1910.219 mechanical power-transmission distances - Cross-reference IACE patterns to MD_OSHA_* identifiers so the Suppression Engine surfaces concrete metric values in mitigation suggestions - Frontend integration: <MinimumDistanceCard> for each measure
This commit is contained in:
@@ -0,0 +1,172 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// Minimum-distance library — Task #18.
|
||||||
|
//
|
||||||
|
// Anchor source: OSHA 29 CFR 1910 Subpart O (US Federal Public Domain,
|
||||||
|
// 17 U.S.C. §105). The values below are reproduced verbatim from the
|
||||||
|
// Federal Code; conversions to metric are mathematical and carry no
|
||||||
|
// copyright. Engineering rounding to safe-side mm values is BreakPilot's
|
||||||
|
// recommendation and labelled as such.
|
||||||
|
//
|
||||||
|
// EU norm equivalents (EN ISO 13857, EN 349, EN 13855, EN 1010) are
|
||||||
|
// referenced by identifier only — no values are reproduced, because
|
||||||
|
// DIN/Beuth retain copyright on the wording. The DINComparisonNote
|
||||||
|
// field carries a human-curated judgement on whether the EU norm is
|
||||||
|
// stricter / looser / equivalent — this is a qualitative observation
|
||||||
|
// about a publicly available document, not a copy of its text.
|
||||||
|
//
|
||||||
|
// See LICENSE_RULES.md and project_attribution_strategy.md for the
|
||||||
|
// licensing logic. The OSHA values are R1 (verbatim public domain);
|
||||||
|
// the recommended metric values are BreakPilot engineering output (R3
|
||||||
|
// own-work). DIN references are R3 identifier-only.
|
||||||
|
|
||||||
|
// MinimumDistanceUnit denotes the original unit system of the source.
|
||||||
|
type MinimumDistanceUnit string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UnitInch MinimumDistanceUnit = "inch"
|
||||||
|
UnitFoot MinimumDistanceUnit = "foot"
|
||||||
|
UnitMeter MinimumDistanceUnit = "meter"
|
||||||
|
UnitMM MinimumDistanceUnit = "mm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MinimumDistance is the data contract for a single safety-distance rule.
|
||||||
|
// It can be (a) a fixed gap value, (b) a distance range, or (c) a formula
|
||||||
|
// like OSHA's Ds = 63 in/s × Ts (hand-speed constant).
|
||||||
|
type MinimumDistance struct {
|
||||||
|
ID string `json:"id"` // MD_OSHA_001
|
||||||
|
// Source identifier — full CFR citation or norm reference.
|
||||||
|
SourceCFR string `json:"source_cfr,omitempty"` // "29 CFR §1910.217(c)(1)(i)"
|
||||||
|
SourceTable string `json:"source_table,omitempty"` // "Table O-10"
|
||||||
|
License string `json:"license"` // "US Federal Public Domain"
|
||||||
|
LicenseRule int `json:"license_rule"` // 1 / 2 / 3 (see LICENSE_RULES.md)
|
||||||
|
|
||||||
|
// Original verbatim value in the source's own unit.
|
||||||
|
OriginalUnit MinimumDistanceUnit `json:"original_unit"`
|
||||||
|
OriginalValue float64 `json:"original_value,omitempty"`
|
||||||
|
OriginalMin float64 `json:"original_min,omitempty"`
|
||||||
|
OriginalMax float64 `json:"original_max,omitempty"`
|
||||||
|
|
||||||
|
// Exact conversion to mm — no engineering rounding.
|
||||||
|
ExactMM float64 `json:"exact_mm,omitempty"`
|
||||||
|
ExactMinMM float64 `json:"exact_min_mm,omitempty"`
|
||||||
|
ExactMaxMM float64 `json:"exact_max_mm,omitempty"`
|
||||||
|
|
||||||
|
// Engineering-recommended metric value with safe-side rounding.
|
||||||
|
// For minimum distances: rounded up. For maximum opening widths:
|
||||||
|
// rounded down.
|
||||||
|
RecommendedMM int `json:"recommended_mm,omitempty"`
|
||||||
|
RecommendedMinMM int `json:"recommended_min_mm,omitempty"`
|
||||||
|
RecommendedMaxMM int `json:"recommended_max_mm,omitempty"`
|
||||||
|
RoundingNote string `json:"rounding_note,omitempty"`
|
||||||
|
|
||||||
|
// Optional formula constant (e.g. OSHA hand-speed 63 in/s).
|
||||||
|
FormulaInchPerSecond float64 `json:"formula_inch_per_second,omitempty"`
|
||||||
|
FormulaMMPerSecond float64 `json:"formula_mm_per_second,omitempty"`
|
||||||
|
FormulaDescription string `json:"formula_description,omitempty"`
|
||||||
|
|
||||||
|
Context string `json:"context"` // "Point of Operation Guarding mechanical presses"
|
||||||
|
BodyPart string `json:"body_part,omitempty"` // "finger" / "hand" / "head" / "foot" / "body"
|
||||||
|
HazardTags []string `json:"hazard_tags,omitempty"` // [crush_point, cutting_part, ...]
|
||||||
|
|
||||||
|
// EU norm cross-reference — IDENTIFIER ONLY, no values reproduced.
|
||||||
|
EUNormHints []EUNormHint `json:"eu_norm_hints,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EUNormHint references an EU standard by identifier without reproducing
|
||||||
|
// any value or text from it. The DINComparisonNote is a human-curated
|
||||||
|
// qualitative judgement (stricter / equivalent / looser) — not a copy.
|
||||||
|
type EUNormHint struct {
|
||||||
|
Norm string `json:"norm"` // "EN ISO 13857"
|
||||||
|
Section string `json:"section,omitempty"` // "Tab. 4, Schutz gegen Hineingreifen"
|
||||||
|
DINComparisonNote string `json:"din_comparison_note,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOSHAMinimumDistances returns the verbatim OSHA values for
|
||||||
|
// machine-guarding distances. All values are US Federal Public Domain
|
||||||
|
// (17 U.S.C. §105). Engineering rounding is BreakPilot's safe-side
|
||||||
|
// recommendation; OSHA values themselves are unchanged.
|
||||||
|
func GetOSHAMinimumDistances() []MinimumDistance {
|
||||||
|
return []MinimumDistance{
|
||||||
|
// OSHA Table O-10 row 1 — verbatim values, mathematical conversion,
|
||||||
|
// safe-side rounded engineering recommendation.
|
||||||
|
{
|
||||||
|
ID: "MD_OSHA_O10_R1",
|
||||||
|
SourceCFR: "29 CFR §1910.217(c)(1)(i)",
|
||||||
|
SourceTable: "Table O-10 row 1",
|
||||||
|
License: "US Federal Public Domain (17 U.S.C. §105)",
|
||||||
|
LicenseRule: 1,
|
||||||
|
OriginalUnit: UnitInch,
|
||||||
|
OriginalMin: 0.5, OriginalMax: 1.5, OriginalValue: 0.25,
|
||||||
|
ExactMinMM: 12.7, ExactMaxMM: 38.1, ExactMM: 6.35,
|
||||||
|
RecommendedMinMM: 15, RecommendedMaxMM: 40, RecommendedMM: 6,
|
||||||
|
RoundingNote: "Distance auf 5-mm-Raster aufgerundet, opening auf 1-mm-Raster abgerundet (konservativ in beide Richtungen).",
|
||||||
|
Context: "Point-of-Operation Guarding bei mechanischen Pressen",
|
||||||
|
BodyPart: "finger",
|
||||||
|
HazardTags: []string{"crush_point", "cutting_part"},
|
||||||
|
EUNormHints: []EUNormHint{
|
||||||
|
{Norm: "EN ISO 13857", Section: "Tab. 4 (Hineingreifen)",
|
||||||
|
DINComparisonNote: "Andere Methodik (Reichweitenmodell). Unabhaengig pruefen — Werte koennen abweichen."},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// OSHA Table O-10 row 4 — used as a worked example in the strategy
|
||||||
|
// discussion. Distance 3.5-5.5 in, opening max 5/8 in.
|
||||||
|
{
|
||||||
|
ID: "MD_OSHA_O10_R4",
|
||||||
|
SourceCFR: "29 CFR §1910.217(c)(1)(i)",
|
||||||
|
SourceTable: "Table O-10 row 4",
|
||||||
|
License: "US Federal Public Domain (17 U.S.C. §105)",
|
||||||
|
LicenseRule: 1,
|
||||||
|
OriginalUnit: UnitInch,
|
||||||
|
OriginalMin: 3.5, OriginalMax: 5.5, OriginalValue: 0.625,
|
||||||
|
ExactMinMM: 88.9, ExactMaxMM: 139.7, ExactMM: 15.875,
|
||||||
|
RecommendedMinMM: 90, RecommendedMaxMM: 140, RecommendedMM: 15,
|
||||||
|
RoundingNote: "Distance 88.9→90 (+1.1 mm), 139.7→140 (+0.3 mm) aufgerundet; Opening 15.875→15 (-0.875 mm) abgerundet.",
|
||||||
|
Context: "Point-of-Operation Guarding bei mechanischen Pressen",
|
||||||
|
BodyPart: "finger",
|
||||||
|
HazardTags: []string{"crush_point", "cutting_part"},
|
||||||
|
EUNormHints: []EUNormHint{
|
||||||
|
{Norm: "EN ISO 13857", Section: "Tab. 4 (Hineingreifen)",
|
||||||
|
DINComparisonNote: "Andere Methodik (Reichweitenmodell). Compliance-Annotation pflegen."},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// OSHA §1910.212(a)(5) — fan blade guards. Verbatim 1/2 inch.
|
||||||
|
{
|
||||||
|
ID: "MD_OSHA_212_FAN",
|
||||||
|
SourceCFR: "29 CFR §1910.212(a)(5)",
|
||||||
|
License: "US Federal Public Domain (17 U.S.C. §105)",
|
||||||
|
LicenseRule: 1,
|
||||||
|
OriginalUnit: UnitInch,
|
||||||
|
OriginalValue: 0.5,
|
||||||
|
ExactMM: 12.7,
|
||||||
|
RecommendedMM: 12,
|
||||||
|
RoundingNote: "Luefterblatt-Schutzgitter: max. Spaltoeffnung 1/2 in = 12.7 mm. Konservativ auf 12 mm abgerundet.",
|
||||||
|
Context: "Lüfterblätter unter 7 ft (2.13 m) Höhe",
|
||||||
|
BodyPart: "finger",
|
||||||
|
HazardTags: []string{"rotating_part", "cutting_part"},
|
||||||
|
EUNormHints: []EUNormHint{
|
||||||
|
{Norm: "EN ISO 13857", Section: "Tab. 4",
|
||||||
|
DINComparisonNote: "DIN-Wert pruefen."},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// OSHA §1910.217 Hand-Speed Constant — formula Ds = 63 in/s × Ts
|
||||||
|
{
|
||||||
|
ID: "MD_OSHA_217_PSDI",
|
||||||
|
SourceCFR: "29 CFR §1910.217 (Ds = 63 in/s × Ts)",
|
||||||
|
License: "US Federal Public Domain (17 U.S.C. §105)",
|
||||||
|
LicenseRule: 1,
|
||||||
|
OriginalUnit: UnitInch,
|
||||||
|
FormulaInchPerSecond: 63.0,
|
||||||
|
FormulaMMPerSecond: 1600.2,
|
||||||
|
FormulaDescription: "Hand-Speed-Konstante 63 in/s ≈ 1600 mm/s. " +
|
||||||
|
"Ds (Mindestabstand) = 63 × Ts (Stoppzeit Presse in Sekunden).",
|
||||||
|
Context: "PSDI Presence-Sensing Device Initiation und Two-Hand-Trip",
|
||||||
|
BodyPart: "hand",
|
||||||
|
HazardTags: []string{"crush_point", "high_speed"},
|
||||||
|
EUNormHints: []EUNormHint{
|
||||||
|
{Norm: "EN 13855", Section: "Sicherheitsabstaende",
|
||||||
|
DINComparisonNote: "EN 13855 nutzt andere Konstante (1600 mm/s ≈ identisch); EU-Norm unabhaengig pruefen."},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user