api581-engine 0.1.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. api581/__init__.py +80 -0
  2. api581/_amine_tables.py +105 -0
  3. api581/_h2sh2_tables.py +161 -0
  4. api581/_slabx_worker.py +174 -0
  5. api581/_sulfidic_tables.py +517 -0
  6. api581/_sulfuric_tables.py +328 -0
  7. api581/acid_sour_water.py +238 -0
  8. api581/acscc_screening.py +88 -0
  9. api581/alkaline_sour_water.py +267 -0
  10. api581/amine_corrosion.py +277 -0
  11. api581/amine_screening.py +103 -0
  12. api581/api/__init__.py +4 -0
  13. api581/api/api520.py +88 -0
  14. api581/api/bundle.py +121 -0
  15. api581/api/consequence.py +102 -0
  16. api581/api/damage.py +1831 -0
  17. api581/api/dispersion.py +121 -0
  18. api581/api/effects.py +318 -0
  19. api581/api/events.py +96 -0
  20. api581/api/financial.py +115 -0
  21. api581/api/frequency.py +40 -0
  22. api581/api/inspection.py +96 -0
  23. api581/api/level1.py +238 -0
  24. api581/api/level2.py +74 -0
  25. api581/api/planning.py +17 -0
  26. api581/api/prd.py +190 -0
  27. api581/api/properties.py +130 -0
  28. api581/api/release.py +252 -0
  29. api581/api/reliability.py +40 -0
  30. api581/api/risk.py +71 -0
  31. api581/api/tank.py +490 -0
  32. api581/api520.py +205 -0
  33. api581/area_contribution.py +72 -0
  34. api581/blast.py +232 -0
  35. api581/brittle.py +205 -0
  36. api581/bundle.py +300 -0
  37. api581/catalog.py +442 -0
  38. api581/caustic_screening.py +103 -0
  39. api581/clad_thinning.py +146 -0
  40. api581/clscc_screening.py +55 -0
  41. api581/co2_corrosion.py +313 -0
  42. api581/co2_screening.py +205 -0
  43. api581/consequences.py +250 -0
  44. api581/contracts.py +1038 -0
  45. api581/cooling_selection.py +204 -0
  46. api581/cooling_water.py +305 -0
  47. api581/core.py +126 -0
  48. api581/corrosion_rate.py +38 -0
  49. api581/cost_tables.py +175 -0
  50. api581/cracking.py +74 -0
  51. api581/data/coverage.json +21361 -0
  52. api581/data/digital-twin.schema.json +538 -0
  53. api581/data/direct-test-queue.json +7 -0
  54. api581/data/native-engine-evidence.json +44 -0
  55. api581/data/python-api.schema.json +92706 -0
  56. api581/data/reference-fixture-evidence.json +2956 -0
  57. api581/data/scope-boundaries.schema.json +58 -0
  58. api581/data/software-test-evidence.json +4278 -0
  59. api581/data/standard-metadata.json +1328 -0
  60. api581/data/standard.schema.json +233 -0
  61. api581/data/supporting-text-review.json +1319 -0
  62. api581/digital_twin.py +491 -0
  63. api581/dispersion.py +45 -0
  64. api581/effects.py +232 -0
  65. api581/evaporation.py +181 -0
  66. api581/evidence.py +81 -0
  67. api581/external_corrosion.py +148 -0
  68. api581/external_cracking.py +63 -0
  69. api581/fatigue.py +56 -0
  70. api581/fireball.py +163 -0
  71. api581/flash_pool.py +111 -0
  72. api581/flash_solver.py +122 -0
  73. api581/groundwater.py +101 -0
  74. api581/h2sh2_corrosion.py +128 -0
  75. api581/hic_screened.py +89 -0
  76. api581/htha.py +45 -0
  77. api581/hydrochloric_acid.py +272 -0
  78. api581/hydrofluoric_acid.py +236 -0
  79. api581/ignition.py +204 -0
  80. api581/inspection_effectiveness.py +601 -0
  81. api581/jet_handoff.py +60 -0
  82. api581/level1.py +311 -0
  83. api581/level1_summary.py +35 -0
  84. api581/level1_toxic.py +313 -0
  85. api581/level1_type1.py +91 -0
  86. api581/level2_summary.py +237 -0
  87. api581/lining.py +173 -0
  88. api581/native_toxic.py +67 -0
  89. api581/outputs.py +5672 -0
  90. api581/oxidation.py +145 -0
  91. api581/pascc_screening.py +78 -0
  92. api581/physical_explosion.py +190 -0
  93. api581/pof.py +207 -0
  94. api581/pool_fire.py +273 -0
  95. api581/portfolio.py +68 -0
  96. api581/prd.py +204 -0
  97. api581/prd_consequences.py +245 -0
  98. api581/prd_history.py +44 -0
  99. api581/py.typed +0 -0
  100. api581/release.py +307 -0
  101. api581/representative_fluids.py +172 -0
  102. api581/result.py +50 -0
  103. api581/risk.py +191 -0
  104. api581/saturation.py +66 -0
  105. api581/scc_mechanisms.py +242 -0
  106. api581/schema.py +45 -0
  107. api581/slabx_adapter.py +261 -0
  108. api581/soil_corrosion.py +191 -0
  109. api581/source_partition.py +169 -0
  110. api581/spatial.py +87 -0
  111. api581/ssc_screening.py +77 -0
  112. api581/standard.py +281 -0
  113. api581/storage.py +42 -0
  114. api581/sulfidic_corrosion.py +197 -0
  115. api581/sulfuric_acid.py +209 -0
  116. api581/tank.py +260 -0
  117. api581/tank_corrosion.py +256 -0
  118. api581/tank_environment.py +186 -0
  119. api581/tank_financial.py +202 -0
  120. api581/tank_integrated.py +51 -0
  121. api581/tank_shell.py +141 -0
  122. api581/tank_source.py +152 -0
  123. api581/tank_thinning.py +204 -0
  124. api581/temper.py +105 -0
  125. api581/thinning.py +172 -0
  126. api581/thinning_conditions.py +212 -0
  127. api581/thinning_history.py +118 -0
  128. api581/thinning_selection.py +81 -0
  129. api581/thinning_type.py +34 -0
  130. api581/toxic_criteria.py +111 -0
  131. api581/toxic_level2.py +233 -0
  132. api581/two_phase_events.py +120 -0
  133. api581/workflow.py +42 -0
  134. api581_engine-0.1.4.dist-info/METADATA +419 -0
  135. api581_engine-0.1.4.dist-info/RECORD +139 -0
  136. api581_engine-0.1.4.dist-info/WHEEL +5 -0
  137. api581_engine-0.1.4.dist-info/licenses/LICENSE +161 -0
  138. api581_engine-0.1.4.dist-info/licenses/NOTICE.md +18 -0
  139. api581_engine-0.1.4.dist-info/top_level.txt +1 -0
api581/contracts.py ADDED
@@ -0,0 +1,1038 @@
1
+ """Output specifications for generation and runtime Python contracts."""
2
+ from typing import Any, Literal
3
+ from .core import Model, Context, NonNegative, Fraction
4
+
5
+ # Required fields, including required nullable values, are intentional. No silent output-field loss.
6
+ NUMBER = NonNegative
7
+ SPECS = {
8
+ "frequency/generic": {"by_hole_per_year": dict[str, NUMBER], "total_per_year": NUMBER},
9
+ "frequency/management-factor": {"score_percent": NUMBER, "management_factor": NUMBER},
10
+ "frequency/adjusted": {"annual_failure_frequency": NUMBER, "unit": Literal["1/year"]},
11
+ "frequency/pof-method-selection": {
12
+ "method": Literal["structural_reliability", "statistical_generic_data", "expert_judgment", "combined"],
13
+ "qualification_basis": str, "uncertainty_quantified": bool,
14
+ "numeric_pof_route": Literal["gff_df_fms", "external_method_result"]},
15
+ "damage/combine": {k: NUMBER for k in ["governing_thinning", "governing_external", "governing_scc", "governing_brittle", "total_damage_factor"]},
16
+ "damage/measured-corrosion-rate": {
17
+ "metal_loss_m": NUMBER, "corrosion_rate_m_year": NUMBER,
18
+ "initial_thickness_m": NUMBER, "current_thickness_m": NUMBER,
19
+ "elapsed_years": NUMBER, "measurement_basis": str, "rate_basis": str,
20
+ },
21
+ "damage/thinning-type": {
22
+ "thinning_type": Literal["general", "localized"],
23
+ "selection_source": Literal["effective_inspection_results", "applicable_mechanism_conservative_default"],
24
+ "effective_inspection_types": list[str],
25
+ "applicable_mechanism_types": list[str],
26
+ "qualification_basis": str,
27
+ },
28
+ "inspection/equivalent": {k: int for k in "abcd"},
29
+ "inspection/effectiveness-category": {
30
+ "category": Literal["A", "B", "C", "D", "E"],
31
+ "ordinal": int,
32
+ "label": str,
33
+ "inspection_credit_allowed": bool,
34
+ "owner_user_basis": str,
35
+ },
36
+ "inspection/effectiveness-summary": {
37
+ "mechanism": Literal["scc", "external_clscc", "cui_clscc", "htha"],
38
+ "highest_effectiveness_category": Literal["A", "B", "C", "D", "E"],
39
+ "inspection_count": int,
40
+ "creditable_inspection_count": int,
41
+ "counts": dict[str, int],
42
+ "equivalent_counts": dict[str, int],
43
+ "e_inspection_count": int,
44
+ "qualification_status": str,
45
+ },
46
+ "inspection/thinning-effectiveness": {
47
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
48
+ "damage_type": Literal["general", "local"],
49
+ "inspection_mode": Literal["intrusive", "non_intrusive"],
50
+ "qualification_status": Literal["qualified", "failed"],
51
+ "basis": str,
52
+ },
53
+ "inspection/scc-effectiveness": {
54
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
55
+ "mechanism_family": Literal["weld_scc", "clscc_pta"],
56
+ "inspection_mode": Literal["intrusive", "non_intrusive"],
57
+ "qualification_status": Literal["qualified", "failed"],
58
+ "basis": str,
59
+ },
60
+ "inspection/external-effectiveness": {
61
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
62
+ "mechanism_family": Literal["external_corrosion", "external_clscc", "cui", "cui_clscc"],
63
+ "insulation_status": Literal["not_applicable", "removed", "not_removed"],
64
+ "qualification_status": Literal["qualified", "failed"],
65
+ "basis": str,
66
+ },
67
+ "inspection/buried-effectiveness": {
68
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
69
+ "inspection_mode": Literal["intrusive", "non_intrusive"],
70
+ "qualification_status": Literal["qualified", "failed"],
71
+ "basis": str,
72
+ },
73
+ "inspection/prd-effectiveness": {
74
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
75
+ "component_type": Literal["pressure_relief_device", "rupture_disk"],
76
+ "qualification_status": Literal["qualified", "failed"],
77
+ "basis": str,
78
+ },
79
+ "inspection/lining-effectiveness": {
80
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
81
+ "inspection_mode": Literal["intrusive", "non_intrusive"],
82
+ "qualification_status": Literal["qualified", "failed"],
83
+ "basis": str,
84
+ },
85
+ "inspection/tube-bundle-uncertainty": {
86
+ "inspection_effectiveness": Literal["A", "B", "C", "D", "E"],
87
+ "uncertainty_percent": float,
88
+ "uncertainty_fraction": Fraction,
89
+ "baseline_no_history_percent": float,
90
+ "owner_user_basis": str,
91
+ },
92
+ "inspection/ast-effectiveness": {
93
+ "effectiveness_category": Literal["A", "B", "C", "D", "E"],
94
+ "component_type": Literal["shell_internal", "shell_external", "tank_bottom"],
95
+ "inspection_side": Literal["internal", "external", "soil_side", "product_side"],
96
+ "qualification_status": Literal["qualified", "failed"],
97
+ "basis": str,
98
+ },
99
+ "reliability/weibull": {"cumulative_failure_probability": Fraction, "survival_probability": Fraction,
100
+ "hazard_per_year": NUMBER | None, "hazard_singular_at_origin": bool},
101
+ "reliability/weibull-quantile": {"age_years": NUMBER},
102
+ "reliability/weibull-from-mttf": {"characteristic_life_years": NUMBER},
103
+ "reliability/poisson-probability": {"period_failure_probability": Fraction},
104
+ "release/orifice-area": {"area_m2": NUMBER},
105
+ "release/viscosity-factor": {"viscosity_factor": NUMBER},
106
+ "release/liquid": {"mass_rate_kg_s": NUMBER, "area_m2": NUMBER, "regime": Literal["liquid"]},
107
+ "release/gas": {"mass_rate_kg_s": NUMBER, "area_m2": NUMBER, "regime": Literal["sonic", "subsonic"],
108
+ "critical_downstream_upstream_ratio": Fraction, "transition_pressure_pa_abs": NUMBER},
109
+ "api520/critical-pressure-ratio": {"critical_pressure_ratio": Fraction},
110
+ "api520/flow-coefficient-c": {"flow_coefficient_c": NUMBER},
111
+ "api520/relieving-pressure": {"relieving_pressure_psig": NUMBER, "relieving_pressure_kpaa": NUMBER},
112
+ "api520/gas-critical-area": {"required_area_mm2": NUMBER},
113
+ "api520/gas-subcritical-area": {"required_area_mm2": NUMBER, "back_pressure_ratio": Fraction, "subcritical_flow_factor": NUMBER},
114
+ "api520/liquid-area": {"required_area_mm2": NUMBER},
115
+ "api520/liquid-viscosity-factor": {"viscosity_factor": NUMBER},
116
+ "api520/gas-critical-capacity": {"mass_capacity_kg_h": NUMBER},
117
+ "api520/gas-subcritical-capacity": {"mass_capacity_kg_h": NUMBER, "back_pressure_ratio": Fraction, "subcritical_flow_factor": NUMBER},
118
+ "api520/liquid-capacity": {"flow_capacity_l_min": NUMBER},
119
+ "properties/heat-capacity-ratio": {"heat_capacity_ratio": NUMBER},
120
+ "properties/representative-fluid": {
121
+ "fluid": str, "molecular_weight_kg_kmol": NUMBER,
122
+ "liquid_density_kg_m3": NUMBER, "normal_boiling_point_k": float,
123
+ "ambient_state": str, "cp_note": int | None,
124
+ "cp_value_table_units": float | None, "cp_basis": str,
125
+ "autoignition_temperature_k": float | None, "source_table": str},
126
+ "properties/acid-caustic-representative-fluid": {
127
+ "selection": Literal["acid_reference", "not_applicable"],
128
+ "representative_fluid": str | None, "release_phase": Literal["liquid"] | None,
129
+ "consequence_model": Literal["acid_splash"] | None, "selection_basis": str},
130
+ "properties/mixture-representative-fluid": {
131
+ "molecular_weight_kg_kmol": NUMBER, "normal_boiling_point_k": float,
132
+ "liquid_density_kg_m3": NUMBER, "autoignition_temperature_k": float,
133
+ "selected_fluid": str, "relevant_mole_fraction": Fraction,
134
+ "selection_basis": str, "level2_recommended": bool},
135
+ "release/available-inventory": {"added_mass_kg": NUMBER, "available_mass_kg": NUMBER},
136
+ "release/type": {"release_type": Literal["continuous", "instantaneous"], "time_to_4536kg_s": NUMBER | None},
137
+ "release/magnitude": {"adjusted_rate_kg_s": NUMBER, "duration_s": NUMBER, "released_mass_kg": NUMBER},
138
+ "release/detection-isolation": {"release_reduction_fraction": Fraction,
139
+ "adjusted_rate_kg_s": NUMBER, "maximum_leak_duration_s": NUMBER | None,
140
+ "duration_s": NUMBER | None, "released_mass_kg": NUMBER,
141
+ "detection_rating": Literal["A", "B", "C"],
142
+ "isolation_rating": Literal["A", "B", "C"],
143
+ "hole_size": Literal["small", "medium", "large", "rupture"]},
144
+ "release/detection-isolation-rating": {
145
+ "detection_rating": Literal["A", "B", "C"],
146
+ "isolation_rating": Literal["A", "B", "C"],
147
+ "detection_type": str, "isolation_type": str, "qualification_basis": str},
148
+ "release/hole-size-selection": {
149
+ "selected_hole": Literal["small", "medium", "large", "rupture"],
150
+ "representative_diameter_m": NUMBER, "lower_bound_m": NUMBER,
151
+ "upper_bound_m": NUMBER | None, "diameter_basis": str, "source_table": str},
152
+ "release/integrate-profile": {"released_mass_kg": NUMBER, "duration_s": NUMBER},
153
+ "properties/mixture-molecular-weight": {"molecular_weight_kg_kmol": NUMBER, "mass_fractions": list[Fraction]},
154
+ "effects/jet-fire-power": {"radiated_power_w": NUMBER},
155
+ "effects/jet-fire-flux": {"received_flux_w_m2": NUMBER},
156
+ "effects/jet-fire-distance": {"threshold_distance_m": NUMBER, "consequence_area_m2": NUMBER, "transmissivity_at_distance": Fraction | None},
157
+ "effects/flash-fire": {"personnel_area_m2": NUMBER, "equipment_area_m2": NUMBER},
158
+ "effects/pool-fire-area": {k: NUMBER for k in ["burning_area_m2", "inventory_limited_area_m2", "pool_area_m2", "pool_radius_m"]},
159
+ "consequence/power-law-area": {"area_m2": NUMBER, "coefficient_source": str},
160
+ "events/leakage-tree": {"terminal_probabilities": dict[str, Fraction], "probability_sum": NUMBER},
161
+ "effects/toxic-probit": {"probit": float | None, "effect_probability": Fraction},
162
+ "effects/pool-burning-rate": {"burning_rate_kg_m2_s": NUMBER},
163
+ "effects/fireball-geometry": {"diameter_m": NUMBER, "center_height_m": NUMBER, "duration_s": NUMBER},
164
+ "effects/fireball-radiative-fraction": {"radiative_fraction": Fraction},
165
+ "effects/fireball-emissive-power": {"surface_emissive_power_w_m2": NUMBER},
166
+ "effects/vce-tnt-equivalence": {"tnt_equivalent_mass_kg": NUMBER},
167
+ "consequence/expected": {"equipment_area_m2": NUMBER, "personnel_area_m2": NUMBER, "financial_consequence": NUMBER, "currency": str},
168
+ "risk/aggregate": {"annual_failure_frequency": NUMBER, "equipment_area_risk_m2_per_year": NUMBER,
169
+ "personnel_area_risk_m2_per_year": NUMBER, "area_risk_m2_per_year": NUMBER,
170
+ "financial_risk_per_year": NUMBER, "currency": str,
171
+ "frequency_weighted_equipment_area_m2": NUMBER | None, "frequency_weighted_personnel_area_m2": NUMBER | None},
172
+ "risk/portfolio": {"component_count": int, "annual_failure_frequency": NUMBER,
173
+ "equipment_area_risk_m2_per_year": NUMBER,
174
+ "personnel_area_risk_m2_per_year": NUMBER,
175
+ "area_risk_m2_per_year": NUMBER, "financial_risk_per_year": NUMBER,
176
+ "currency": str, "disjointness_basis": str,
177
+ "component_contributions": dict[str, dict[str, NUMBER]]},
178
+ "consequence/financial-total": {"financial_consequence": NUMBER, "currency": str, "cost_basis_year": int},
179
+ "risk/matrix": {"frequency_category": int, "consequence_category": int, "risk_label": str, "policy_id": str},
180
+ "damage/thinning-wall-loss": {"wall_loss_fraction": NUMBER},
181
+ "damage/flow-stress": {"flow_stress_pa": NUMBER},
182
+ "damage/thinning-strength-ratio": {"strength_ratio": NUMBER},
183
+ "damage/thinning-posterior": {"posterior_probabilities": list[Fraction]},
184
+ "damage/thinning-base": {"reliability_indices": list[float], "damage_state_failure_probabilities": list[Fraction],
185
+ "weighted_failure_probability": Fraction, "base_damage_factor": NUMBER},
186
+ "damage/thinning-adjust": {"thinning_damage_factor": NUMBER},
187
+ "damage/scc-base": {"base_damage_factor": NUMBER},
188
+ "damage/caustic-severity": {"severity_index": int},
189
+ "damage/caustic-escalation": {"damage_factor": NUMBER},
190
+ "damage/lining-adjust": {"condition_factor": NUMBER, "monitoring_factor": NUMBER, "lining_damage_factor": NUMBER},
191
+ }
192
+ SPECS["damage/thinning-unclad"] = {**SPECS["damage/thinning-wall-loss"], **SPECS["damage/thinning-strength-ratio"],
193
+ **SPECS["damage/thinning-posterior"], **SPECS["damage/thinning-base"], **SPECS["damage/thinning-adjust"]}
194
+ SPECS.update({
195
+ "level1/flammable-coefficients": {"a": NUMBER,"b":NUMBER,"magnitude_unit":str,"area_unit":str},
196
+ "release/detection-reduction": {"reduction_fraction":Fraction},
197
+ "release/detection-duration": {"maximum_duration_s":NUMBER},
198
+ "level1/release-phase": {"release_phase":Literal["gas","liquid"]},
199
+ "level1/energy-efficiency": {"energy_efficiency_factor":NUMBER},
200
+ "level1/blending-factors": {"instantaneous_weight":Fraction,"autoignition_likely_weight":Fraction},
201
+ "level1/flammable-area": {"equipment_area_m2":NUMBER,"personnel_area_m2":NUMBER,"instantaneous_weight":Fraction,
202
+ "autoignition_likely_weight":Fraction,"energy_efficiency_factor":NUMBER}
203
+ })
204
+ SPECS["level1/release-to-flammable"] = {"theoretical_rate_kg_s":NUMBER,"available_mass_kg":NUMBER,
205
+ "release_type":Literal["continuous","instantaneous"],"reduction_fraction":Fraction,"maximum_duration_s":NUMBER,
206
+ **SPECS["release/magnitude"],**SPECS["level1/flammable-area"]}
207
+ SPECS.update({
208
+ "level1/mitigation":{"mitigation_fraction":Fraction},
209
+ "level1/toxic-source":{"toxic_rate_kg_s":NUMBER,"toxic_mass_kg":NUMBER},
210
+ "level1/toxic-duration":{"duration_s":NUMBER},
211
+ "level1/toxic-area":{"unweighted_personnel_area_m2":NUMBER,"personnel_area_m2":NUMBER},
212
+ "level1/steam-area":{"continuous_area_m2":NUMBER,"instantaneous_area_m2":NUMBER,"instantaneous_weight":Fraction,"personnel_area_m2":NUMBER,"equipment_area_m2":NUMBER},
213
+ "level1/acid-caustic-area":{"personnel_area_m2":NUMBER,"equipment_area_m2":NUMBER,"coefficient_g":NUMBER,"exponent_h":NUMBER},
214
+ "consequence/final-area":{"equipment_area_m2":NUMBER,"personnel_area_m2":NUMBER,"consequence_area_m2":NUMBER},
215
+ "consequence/hole-weighted":{"weighted_value":NUMBER,"value_unit":str},
216
+ **{id:{"cost":NUMBER,"currency":str} for id in ["financial/surrounding-damage","financial/production-loss","financial/injury"]},
217
+ "financial/spill-cleanup":{"remediation_volume_m3":NUMBER,"cost":NUMBER,"currency":str}
218
+ })
219
+ SPECS["level1/consequence-summary"] = {name:NUMBER for name in ["flammable_equipment_area_m2","flammable_personnel_area_m2",
220
+ "toxic_personnel_area_m2","nfnt_personnel_area_m2","equipment_area_m2","personnel_area_m2","consequence_area_m2","generic_frequency_per_year"]}
221
+ SPECS.update({
222
+ "financial/repair-table":{"cost_by_hole_usd_2001":dict[str,NUMBER],"cost_basis_year":int,"currency":str},
223
+ "financial/material-factor":{"material_factor":NUMBER},
224
+ "financial/outage-table":{"days_by_hole":dict[str,NUMBER|None]},
225
+ "financial/component-repair":{"weighted_repair_cost_usd_2001":NUMBER,"cost":NUMBER,"material_factor":NUMBER,"cost_basis_year":int,"currency":str},
226
+ "financial/component-outage":{"component_outage_days":NUMBER,"effective_days_by_hole":dict[str,NUMBER|None]},
227
+ "financial/surrounding-outage":{"surrounding_outage_days":NUMBER},
228
+ "properties/leak-table":{"molecular_weight_kg_kmol":NUMBER,"tabulated_liquid_density_kg_m3":NUMBER,"normal_boiling_point_k":NUMBER,"evaporated_fraction_24h":Fraction},
229
+ "financial/cleanup-eligibility":{"include_cleanup_cost":bool}
230
+ })
231
+ SPECS["financial/hole-total"] = {
232
+ "currency": str,
233
+ "cost_basis_year": int,
234
+ "total_generic_frequency_per_year": NUMBER,
235
+ "per_hole": list[dict[str, NUMBER | str]],
236
+ "frequency_weighted_financial_consequence": NUMBER,
237
+ "annual_financial_risk": NUMBER,
238
+ }
239
+ SPECS["financial/level1-consequence"] = {**{name:NUMBER for name in ["component_repair_cost","surrounding_equipment_cost",
240
+ "business_interruption_cost","injury_cost","environmental_cost","component_outage_days","surrounding_outage_days",
241
+ "surrounding_cost_reference_usd_2001","financial_consequence"]},"currency":str,"cost_basis_year":int}
242
+ SPECS["damage/scc-severity"]={"severity_index":int}
243
+ SPECS["damage/hic-monitoring-factor"]={"monitoring_factor":NUMBER}
244
+ for _id in ["caustic","amine","ssc","hic-sohic-h2s","acscc","pascc","clscc","hsc-hf","hic-sohic-hf"]:
245
+ SPECS["damage/"+_id]={"effective_susceptibility":str,"severity_index":int,"equivalent_inspection_grade":str,
246
+ "equivalent_inspection_count":int,"base_damage_factor":NUMBER,"age_factor":NUMBER,"monitoring_factor":NUMBER,"damage_factor":NUMBER}
247
+ for _id in ["hsc-hf","ssc","hic-hf","hic-h2s","clscc"]:
248
+ SPECS["damage/"+_id+"-susceptibility"]={"susceptibility":Literal["none","low","medium","high"]}
249
+ SPECS["damage/acscc-susceptibility"]={"susceptibility":Literal["none","low","medium","high"]}
250
+ SPECS["damage/pascc-susceptibility"]={"susceptibility":Literal["none","low","medium","high"]}
251
+ SPECS["damage/wet-h2s-environment"]={"environmental_severity":Literal["low","moderate","high"],"susceptibility_upgrade_required":bool}
252
+ for _id in ["external-base-rate","cui-base-rate"]:
253
+ SPECS["damage/"+_id]={"base_corrosion_rate_m_year":NUMBER}
254
+ SPECS["damage/external-time-weighted-rate"]={"base_corrosion_rate_m_year":NUMBER,"period_rates_m_year":list[NUMBER]}
255
+ SPECS["damage/external-rate-adjust"]={"design_interface_factor":NUMBER,"corrosion_rate_m_year":NUMBER}
256
+ SPECS["damage/cui-rate-adjust"]={name:NUMBER for name in ["design_interface_factor","corrosion_rate_m_year","insulation_factor","complexity_factor","condition_factor"]}
257
+ SPECS["damage/coating-exposure"]={"coating_credit_years":NUMBER,"corrosion_exposure_years":NUMBER}
258
+ for _id in ["external-corrosion","cui"]:
259
+ SPECS["damage/"+_id]={**{name:NUMBER for name in ["corrosion_rate_m_year","coating_credit_years","corrosion_exposure_years","wall_loss_fraction","strength_ratio","weighted_failure_probability","damage_factor"]},
260
+ "posterior_probabilities":list[Fraction],"reliability_indices":list[float]}
261
+ SPECS["damage/external-clscc-base-susceptibility"]={"base_susceptibility":Literal["none","low","medium","high"]}
262
+ for _id in ["external-clscc","cui-clscc"]:
263
+ SPECS["damage/"+_id]={"effective_susceptibility":str,"severity_index":int,"equivalent_inspection_grade":str,
264
+ "equivalent_inspection_count":int,**{name:NUMBER for name in ["base_damage_factor","age_factor","coating_credit_years","cracking_exposure_years","damage_factor"]}}
265
+ SPECS["damage/fatigue-base"]={name:NUMBER for name in ["previous_failure_factor","shaking_factor","shaking_duration_factor","cyclic_loading_factor","base_damage_factor"]}
266
+ SPECS["damage/fatigue-adjustments"]={name:NUMBER for name in ["corrective_action_factor","complexity_factor","pipe_condition_factor","joint_branch_factor","branch_diameter_factor","combined_adjustment_factor"]}
267
+ SPECS["damage/mechanical-fatigue"]={**SPECS["damage/fatigue-base"],**SPECS["damage/fatigue-adjustments"],"damage_factor":NUMBER}
268
+ SPECS["properties/hydrogen-partial-pressure"]={"hydrogen_partial_pressure_pa_abs":NUMBER}
269
+ SPECS["damage/htha-factor"]={"damage_factor":NUMBER}
270
+ SPECS["damage/htha-carbon-screen"]={"susceptibility":str,"damage_factor":NUMBER}
271
+
272
+ SPECS["damage/brittle-reference-temperature"] = {"reference_temperature_k": NUMBER, "table_basis": str}
273
+ SPECS["damage/brittle-service-factor"] = {"service_experience_factor": NUMBER, "thin_component_credit": bool, "service_criteria": dict[str, bool]}
274
+ SPECS["damage/brittle-base"] = {"base_damage_factor": NUMBER, "table": Literal["20.4M", "20.5M"]}
275
+ SPECS["damage/brittle-fracture"] = {**SPECS["damage/brittle-reference-temperature"], **SPECS["damage/brittle-service-factor"],
276
+ **SPECS["damage/brittle-base"], "cet_minus_reference_k": float, "damage_factor": NUMBER}
277
+ SPECS["damage/embrittlement-885f"] = {"reference_temperature_k": NUMBER, "minimum_minus_reference_k": float, "damage_factor": NUMBER}
278
+ SPECS["damage/sigma-content"] = {"sigma_category": Literal["low", "medium", "high"]}
279
+ SPECS["damage/sigma-embrittlement"] = {"damage_factor": NUMBER, "sigma_category": Literal["low", "medium", "high"]}
280
+
281
+ SPECS["damage/temper-j-factor"] = {"j_factor": NUMBER}
282
+ SPECS["damage/temper-xbar"] = {"xbar_factor": NUMBER}
283
+ SPECS["damage/temper-xbar-shift"] = {"delta_fatt_k": NUMBER}
284
+ SPECS["damage/temper-generation-shift"] = {"generation": int, "delta_fatt_k": NUMBER, "source_basis": Literal["printed_C", "printed_F_difference_converted"]}
285
+ SPECS["damage/temper-embrittlement"] = {**SPECS["damage/brittle-reference-temperature"],
286
+ "shifted_reference_temperature_k": NUMBER, "minimum_minus_shifted_reference_k": float,
287
+ "delta_fatt_k": NUMBER, "damage_factor": NUMBER, "table": Literal["20.4M", "20.5M"]}
288
+
289
+ SPECS["bundle/weibayes-history"] = {"shape": NUMBER, "characteristic_life_years": NUMBER, "failure_count": int, "record_count": int}
290
+ SPECS["bundle/condition-update"] = SPECS["bundle/weibayes-history"]
291
+ SPECS["bundle/thickness-life"] = {"thinning_rate_m_year": NUMBER, "predicted_bundle_life_years": NUMBER | None,
292
+ "remaining_life_years": NUMBER | None, "remaining_wall_threshold_reached": bool,
293
+ "formula_basis": Literal["printed_eq_1_72", "remaining_wall_threshold"]}
294
+ SPECS["bundle/estimated-life"] = {"predicted_bundle_life_years": NUMBER}
295
+ SPECS["bundle/life-extension"] = {"adjusted_age_at_action_years": NUMBER, "effective_age_years": NUMBER, "installation_shift_years": NUMBER}
296
+ SPECS["bundle/consequence"] = {"production_loss_cost": NUMBER, "financial_consequence": NUMBER, "currency": str, "cost_basis_year": int}
297
+ SPECS["bundle/risk"] = {"cumulative_failure_probability": Fraction, "probability_weighted_consequence": NUMBER, "currency": str}
298
+ SPECS["bundle/target-age"] = {"target_failure_probability": Fraction, "target_age_years": NUMBER | None, "status": Literal["finite_crossing", "no_finite_crossing"]}
299
+ SPECS["bundle/deferral-decision"] = {"conditional_failure_probability": Fraction, "expected_incremental_risk": NUMBER,
300
+ "inspection_hurdle_cost": NUMBER, "replacement_hurdle_cost": NUMBER,
301
+ "inspection_economically_justified": bool, "replacement_economically_justified": bool, "currency": str}
302
+ SPECS["bundle/replacement-optimization"] = {"optimal_grid_age_years": NUMBER, "minimum_cost_per_day": NUMBER,
303
+ "minimum_at_grid_boundary": bool, "grid_points": int, "samples": list[dict[str, NUMBER]], "currency": str}
304
+ SPECS["prd/default-weibull"] = {"shape": NUMBER, "default_characteristic_life_years": NUMBER, "design_factor": NUMBER, "design_adjusted_characteristic_life_years": NUMBER}
305
+ SPECS["prd/environment-factor"] = {"environment_factor": Fraction, "individual_factors": dict[str, Fraction]}
306
+ SPECS["prd/set-pressure-factor"] = {"set_pressure_factor": Fraction}
307
+ SPECS["prd/overpressure-factor"] = {"overpressure_factor": Fraction}
308
+ SPECS["prd/demand-rate"] = {"case_demand_rates_per_year": list[NUMBER], "total_demand_rate_per_year": NUMBER}
309
+ SPECS["prd/inspection-update"] = {"prior_failure_probability": Fraction, "conditional_failure_probability": Fraction | None,
310
+ "weighted_failure_probability": Fraction, "updated_characteristic_life_years": NUMBER, "update_applied": bool, "effective_failed_result": bool}
311
+ SPECS["prd/protected-equipment"] = {"normal_failure_frequency_per_year": NUMBER, "source_model_loc_probability": Fraction, "by_hole_loc_probability": dict[str, Fraction]}
312
+ SPECS["prd/fail-frequency"] = {"annual_failure_frequency": NUMBER}
313
+ SPECS["prd/base-reliability"] = {"shape": NUMBER, "modified_characteristic_life_years": NUMBER, "environment_factor": Fraction,
314
+ "scenario_probability_factor": Fraction, "unadjusted_cumulative_probability": Fraction, "scenario_adjusted_probability": Fraction}
315
+ SPECS["bundle/material-factor"] = {"material_factor": NUMBER}
316
+ SPECS["bundle/replacement-cost"] = {"bundle_volume_m3": NUMBER, "reference_basis_cost_usd": NUMBER, "replacement_cost": NUMBER, "currency": str, "cost_basis_year": int}
317
+ SPECS["bundle/life-extension-factor"] = {"life_extension_factor": Fraction}
318
+ SPECS["bundle/categories"] = {"probability_category": int, "consequence_category": Literal["A", "B", "C", "D", "E"]}
319
+
320
+ SPECS["prd/leakage-rates"] = {name: NUMBER for name in ["minor_rate_kg_s", "moderate_table_rate_kg_s", "mild_moderate_equation_rate_kg_s", "stuck_open_rate_kg_s"]}
321
+ SPECS["prd/leakage-duration"] = {"mild_moderate_duration_s": NUMBER, "stuck_open_duration_s": NUMBER}
322
+ SPECS["prd/inventory-loss-factor"] = {"inventory_loss_factor": Fraction}
323
+ _MONEY = {"currency": str, "cost_basis_year": int}
324
+ SPECS["prd/inventory-loss"] = {"leaked_mass_kg": NUMBER, "inventory_loss_equivalent_mass_kg": NUMBER, "inventory_loss_cost": NUMBER, **_MONEY}
325
+ SPECS["prd/repair-cost"] = {"reference_cost_usd": NUMBER, "repair_cost": NUMBER, **_MONEY}
326
+ SPECS["prd/production-loss"] = {"production_loss_cost": NUMBER, "shutdown_loss_applied": bool, **_MONEY}
327
+ SPECS["prd/leakage-consequence"] = {"financial_consequence": NUMBER, "case_weights": dict[str, Fraction],
328
+ "costs_by_case": dict[str, dict[str, NUMBER]], "inventory_loss_factor": Fraction,
329
+ "model_basis": Literal["two_case_equations", "three_case_table_7_15"], **_MONEY}
330
+ SPECS["prd/multiple-device-pressure"] = {"multiple_device_factor": Fraction,
331
+ "protected_equipment_pressure_pa_gauge": NUMBER, "unreduced_pressure_for_fop_pa_gauge": NUMBER}
332
+ SPECS["prd/fail-risk"] = {"protected_equipment_risks_per_year": dict[str, NUMBER], "maximum_fail_risk_per_year": NUMBER,
333
+ "governing_equipment_ids": list[str], **_MONEY}
334
+ _LEAK_BASIS = Literal["annual_frequency", "source_cumulative_probability"]
335
+ SPECS["prd/leakage-risk"] = {"leakage_risk_value": NUMBER, "measure_basis": _LEAK_BASIS, "risk_unit": Literal["currency", "currency/year"], **_MONEY}
336
+ SPECS["prd/total-risk"] = {"annual_financial_risk": NUMBER | None, "source_total_risk_index": NUMBER | None,
337
+ "leakage_measure_basis": _LEAK_BASIS, **_MONEY}
338
+ SPECS["prd/risk-assessment"] = {**SPECS["prd/fail-risk"], **SPECS["prd/total-risk"],
339
+ "leakage_risk_value": NUMBER, "leakage_risk_unit": Literal["currency", "currency/year"]}
340
+ SPECS["prd/service-age"] = {"effective_age_years": NUMBER, "elapsed_since_original_installation_years": NUMBER,
341
+ "last_age_reset_date": str, "last_age_reset_type": Literal["installation", "overhaul", "replacement"],
342
+ "parameter_history_valid_from_date": str, "inspection_update_start_date": str, "last_test_date": str | None, "days_per_year": NUMBER}
343
+
344
+ SPECS["release/controlled-scenario"] = {"theoretical_rate_kg_s": NUMBER, "available_mass_kg": NUMBER,
345
+ "release_type": Literal["continuous", "instantaneous"], "reduction_fraction": Fraction,
346
+ "maximum_duration_s": NUMBER, "adjusted_rate_kg_s": NUMBER, "duration_s": NUMBER, "released_mass_kg": NUMBER}
347
+ SPECS["level1/type1-flammable-area"] = {"area_m2": NUMBER, "coefficient_a": NUMBER, "coefficient_b": NUMBER, "energy_efficiency_factor": NUMBER}
348
+ SPECS["level1/type1-flammable-consequence"] = {"equipment_area_m2": NUMBER, "personnel_area_m2": NUMBER, "energy_efficiency_factor": NUMBER, "fluid_type": Literal[1]}
349
+ SPECS["level1/release-to-type1-flammable"] = {**SPECS["release/controlled-scenario"], **SPECS["level1/type1-flammable-consequence"]}
350
+ SPECS["level1/release-to-acid"] = {**SPECS["release/controlled-scenario"],
351
+ "personnel_area_m2": NUMBER, "equipment_area_m2": NUMBER,
352
+ "coefficient_g": NUMBER, "exponent_h": NUMBER,
353
+ "representative_fluid": Literal["Acid"], "release_phase": Literal["liquid"]}
354
+ SPECS["level1/release-to-steam"] = {**SPECS["release/controlled-scenario"],
355
+ "continuous_area_m2": NUMBER, "instantaneous_area_m2": NUMBER,
356
+ "instantaneous_weight": Fraction, "personnel_area_m2": NUMBER,
357
+ "equipment_area_m2": NUMBER, "representative_fluid": Literal["Steam"],
358
+ "release_phase": Literal["gas"]}
359
+ SPECS["level1/hf-h2s-toxic-coefficients"] = {"c": NUMBER, "d": float, "native_magnitude_unit": Literal["lb/s", "lb"],
360
+ "native_area_unit": Literal["ft2"], "si_mass_multiplier": NUMBER, "si_area_multiplier": NUMBER,
361
+ "source_cell_status": Literal["clear", "ambiguous_print", "qualified_override"]}
362
+ SPECS["level1/hf-h2s-toxic-area"] = {"unweighted_personnel_area_m2": NUMBER, "personnel_area_m2": NUMBER}
363
+ SPECS["level1/misc-toxic-coefficients"] = {"e": NUMBER, "f": NUMBER, "native_rate_unit": Literal["kg/s"],
364
+ "native_area_unit": Literal["m2"], "si_mass_multiplier": NUMBER, "si_area_multiplier": NUMBER}
365
+ SPECS["level1/misc-toxic-area"] = SPECS["level1/hf-h2s-toxic-area"]
366
+ SPECS["level1/toxic-cutoff"] = {"idlh_ppm": NUMBER, "requires_toxic_evaluation": bool}
367
+ SPECS["level1/toxic-mitigation"] = {"toxic_rate_kg_s": NUMBER, "toxic_mass_kg": NUMBER, "duration_s": NUMBER}
368
+ SPECS["level1/toxic-component-consequence"] = {**SPECS["level1/toxic-mitigation"], **SPECS["level1/hf-h2s-toxic-area"],
369
+ "unmitigated_duration_s": NUMBER, "screening_applied": bool, "requires_toxic_evaluation": bool}
370
+ SPECS["level1/release-to-toxic"] = {**SPECS["release/controlled-scenario"],
371
+ **SPECS["level1/toxic-component-consequence"]}
372
+ SPECS["level1/toxic-mixture-consequence"] = {
373
+ "personnel_area_m2": NUMBER, "critical_component_id": str,
374
+ "component_areas_m2": dict[str, NUMBER], "component_count": int}
375
+ SPECS["level1/toxic-hole-summary"] = {
376
+ "personnel_area_m2": NUMBER, "total_generic_frequency_per_year": NUMBER,
377
+ "by_hole_personnel_area_m2": dict[str, NUMBER]}
378
+
379
+ SPECS["properties/water-partial-pressure"] = {"water_partial_pressure_pa": NUMBER}
380
+ SPECS["effects/atmospheric-transmissivity"] = {"transmissivity": Fraction, "uncapped_transmissivity": NUMBER | None, "dry_air_limit": bool}
381
+ SPECS["effects/pool-mixture-burning-rate"] = {"burning_rate_kg_m2_s": NUMBER}
382
+ SPECS["effects/pool-flame-geometry"] = {"nondimensional_wind_speed": NUMBER, "flame_length_m": NUMBER,
383
+ "flame_tilt_rad": NUMBER, "vertical_flame_height_m": NUMBER, "downwind_axis_extension_m": NUMBER}
384
+ SPECS["effects/pool-surface-emissive-power"] = {"burning_mass_rate_kg_s": NUMBER, "radiated_power_w": NUMBER,
385
+ "emitting_surface_area_m2": NUMBER, "surface_emissive_power_w_m2": NUMBER}
386
+ _POOL_BASIS = Literal["api581_printed", "geometry_checked"]
387
+ _POOL_DISTANCE = Literal["printed_surface_ratio", "surface_to_axis"]
388
+ _POOL_STATUS = Literal["threshold_solved", "below_limit_at_domain_boundary"]
389
+ SPECS["effects/pool-cylinder-view-factor"] = {"vertical_view_factor": float, "horizontal_view_factor": float,
390
+ "maximum_view_factor": NUMBER, "physical_range": bool, "equation_basis": _POOL_BASIS}
391
+ SPECS["effects/pool-radiation-flux"] = {"received_flux_w_m2": NUMBER, "transmissivity": Fraction,
392
+ "maximum_view_factor": NUMBER, "view_factor_distance_m": NUMBER, "equation_basis": _POOL_BASIS, "distance_convention": _POOL_DISTANCE}
393
+ SPECS["effects/pool-fire-distance"] = {"safe_surface_distance_m": NUMBER, "consequence_radius_m": NUMBER,
394
+ "consequence_area_m2": NUMBER, "status": _POOL_STATUS, "iterations": int, "flux_residual_w_m2": float | None,
395
+ "minimum_surface_domain_m": NUMBER, "equation_basis": _POOL_BASIS, "distance_convention": _POOL_DISTANCE}
396
+ SPECS["effects/pool-fire-consequence"] = {"burning_rate_kg_m2_s": NUMBER, **SPECS["effects/pool-fire-area"],
397
+ "flame_length_m": NUMBER, "flame_tilt_rad": NUMBER, "surface_emissive_power_w_m2": NUMBER,
398
+ "personnel_area_m2": NUMBER, "equipment_area_m2": NUMBER,
399
+ "personnel_safe_surface_distance_m": NUMBER, "equipment_safe_surface_distance_m": NUMBER,
400
+ "personnel_status": Literal["no_pool", "threshold_solved", "below_limit_at_domain_boundary"],
401
+ "equipment_status": Literal["no_pool", "threshold_solved", "below_limit_at_domain_boundary"],
402
+ "equation_basis": _POOL_BASIS, "distance_convention": _POOL_DISTANCE}
403
+
404
+ _FIREBALL_BASIS = Literal["api581_printed", "elevated_sphere_maximum"]
405
+ _FIREBALL_STATUS = Literal["threshold_solved", "below_limit_at_origin"]
406
+ SPECS["effects/fireball-mass"] = {"flammable_mass_kg": NUMBER}
407
+ SPECS["effects/fireball-view-factor"] = {"view_factor": Fraction, "model_center_distance_m": NUMBER,
408
+ "attenuation_path_m": NUMBER, "geometry_basis": _FIREBALL_BASIS}
409
+ SPECS["effects/fireball-radiation-flux"] = {**SPECS["effects/fireball-view-factor"],
410
+ "transmissivity": Fraction, "received_flux_w_m2": NUMBER}
411
+ SPECS["effects/fireball-distance"] = {"safe_distance_m": NUMBER, "consequence_area_m2": NUMBER,
412
+ "status": _FIREBALL_STATUS, "iterations": int, "flux_residual_w_m2": float | None, "geometry_basis": _FIREBALL_BASIS}
413
+ SPECS["effects/fireball-consequence"] = {**SPECS["effects/fireball-mass"], **SPECS["effects/fireball-geometry"],
414
+ **SPECS["effects/fireball-radiative-fraction"], **SPECS["effects/fireball-emissive-power"],
415
+ "personnel_area_m2": NUMBER, "equipment_area_m2": NUMBER, "personnel_safe_distance_m": NUMBER,
416
+ "equipment_safe_distance_m": NUMBER, "personnel_status": Literal["no_flammable_mass", "threshold_solved", "below_limit_at_origin"],
417
+ "equipment_status": Literal["no_flammable_mass", "threshold_solved", "below_limit_at_origin"], "geometry_basis": _FIREBALL_BASIS}
418
+
419
+ SPECS["effects/vce-scaled-distance"] = {"scaled_distance_m_kg13": NUMBER}
420
+ SPECS["effects/vce-scaled-overpressure"] = {"side_on_overpressure_pa": NUMBER, "slope_pa_per_scaled_distance": float}
421
+ SPECS["effects/vce-blast-overpressure"] = {**SPECS["effects/vce-scaled-distance"], **SPECS["effects/vce-scaled-overpressure"]}
422
+ SPECS["effects/blast-building-probit"] = {"probit": float, "building_collapse_probability": Fraction}
423
+ SPECS["effects/blast-building-pressure-threshold"] = {"probit": float, "side_on_overpressure_pa": NUMBER}
424
+ _BLAST_STATUS = Literal["threshold_solved", "no_explosion"]
425
+ SPECS["effects/vce-blast-distance"] = {"safe_distance_m": NUMBER, "consequence_area_m2": NUMBER,
426
+ "scaled_distance_m_kg13": NUMBER | None, "status": _BLAST_STATUS, "iterations": int, "pressure_residual_pa": float | None}
427
+ SPECS["effects/vce-blast-consequence"] = {"tnt_equivalent_mass_kg": NUMBER,
428
+ "personnel_threshold_overpressure_pa": NUMBER, "personnel_building_collapse_probability": Fraction,
429
+ "equipment_threshold_overpressure_pa": NUMBER, "personnel_safe_distance_m": NUMBER, "equipment_safe_distance_m": NUMBER,
430
+ "personnel_area_m2": NUMBER, "equipment_area_m2": NUMBER, "personnel_status": _BLAST_STATUS, "equipment_status": _BLAST_STATUS,
431
+ "mass_basis": Literal["between_flammability_limits", "total_released_flammable"]}
432
+
433
+ SPECS["effects/physical-explosion-tnt"] = {"vapor_stored_energy_j": NUMBER, "tnt_equivalent_mass_kg": NUMBER}
434
+ SPECS["release/bleve-flashed-amount"] = {"flashed_liquid_mass_kg": NUMBER, "flashed_amount_kmol": NUMBER}
435
+ SPECS["effects/bleve-liquid-tnt"] = {"liquid_expansion_energy_j": NUMBER, "tnt_equivalent_mass_kg": NUMBER}
436
+ _RUPTURE_STATUS = Literal["threshold_solved", "no_explosion", "not_rupture"]
437
+ _RUPTURE_AREAS = {"potential_tnt_equivalent_mass_kg": NUMBER, "event_tnt_equivalent_mass_kg": NUMBER,
438
+ "personnel_threshold_overpressure_pa": NUMBER, "equipment_threshold_overpressure_pa": NUMBER,
439
+ "personnel_building_collapse_probability": Fraction, "personnel_safe_distance_m": NUMBER, "equipment_safe_distance_m": NUMBER,
440
+ "personnel_area_m2": NUMBER, "equipment_area_m2": NUMBER, "personnel_status": _RUPTURE_STATUS, "equipment_status": _RUPTURE_STATUS,
441
+ "hole": Literal["small", "medium", "large", "rupture"]}
442
+ SPECS["effects/physical-explosion-consequence"] = {"vapor_stored_energy_j": NUMBER, **_RUPTURE_AREAS}
443
+ SPECS["effects/bleve-consequence"] = {"liquid_expansion_energy_j": NUMBER, "vapor_stored_energy_j": NUMBER,
444
+ "liquid_tnt_equivalent_mass_kg": NUMBER, "vapor_tnt_equivalent_mass_kg": NUMBER, **_RUPTURE_AREAS}
445
+ SPECS["consequence/level2-nfnt-case"] = {"equipment_area_m2": NUMBER, "personnel_area_m2": NUMBER}
446
+ SPECS["consequence/level2-nfnt-summary"] = {**SPECS["consequence/level2-nfnt-case"], "total_generic_frequency_per_year": NUMBER,
447
+ "by_hole_equipment_area_m2": dict[str, NUMBER], "by_hole_personnel_area_m2": dict[str, NUMBER]}
448
+
449
+ SPECS["properties/toxic-impact-table"] = {"probit_intercept": float | None, "probit_slope": NUMBER | None,
450
+ "concentration_exponent": NUMBER | None, "probit_available": bool, "probit_concentration_unit": Literal["ppm"],
451
+ "probit_duration_unit": Literal["s"], "idlh_ppm": NUMBER | None, "aegl3_ppm": dict[str, NUMBER],
452
+ "epa_toxic_endpoint_mg_l": NUMBER | None, "erpg3_ppm": NUMBER | None}
453
+ SPECS["effects/toxic-species-probit"] = {"probit": float | None, "fatality_probability": Fraction}
454
+ SPECS["effects/toxic-species-threshold"] = {"concentration_ppm": NUMBER, "probit": float, "within_pure_species_limit": bool}
455
+ SPECS["effects/toxic-dose-profile"] = {**SPECS["effects/toxic-species-probit"], "dose_ppm_power_n_s": NUMBER | None,
456
+ "log_dose": float | None, "dose_representable": bool, "duration_s": NUMBER, "equivalent_constant_concentration_ppm": NUMBER}
457
+ SPECS["release/level2-toxic-duration"] = {"release_duration_s": NUMBER,
458
+ "governing_limit": Literal["no_release","no_inventory","one_hour","inventory","detection_isolation"]}
459
+ SPECS["consequence/toxic-mixture-limit"] = {"modified_mixture_limit_ppm": NUMBER | None, "component_present": bool, "attainable_in_mixture": bool}
460
+ SPECS["consequence/level2-toxic-case"] = {"equipment_area_m2": NUMBER, "personnel_area_m2": NUMBER,
461
+ "unweighted_cloud_area_m2": NUMBER, "critical_component_id": str, "component_cloud_areas_m2": dict[str, NUMBER]}
462
+ SPECS["consequence/level2-toxic-summary"] = {"equipment_area_m2": NUMBER, "personnel_area_m2": NUMBER,
463
+ "total_generic_frequency_per_year": NUMBER, "by_hole_personnel_area_m2": dict[str, NUMBER]}
464
+
465
+ SPECS["level2/flammable-case"] = {"flammable_equipment_area_m2": NUMBER,"flammable_personnel_area_m2": NUMBER,
466
+ "non_ignition_probability": Fraction,"terminal_probability_sum": NUMBER}
467
+ SPECS["level2/final-area"] = {"equipment_area_m2": NUMBER,"personnel_area_m2": NUMBER,"consequence_area_m2": NUMBER,
468
+ "non_ignition_personnel_area_m2": NUMBER,"governing_non_ignition_personnel_mechanism": Literal["toxic","nfnt","equal"]}
469
+ SPECS["level2/consequence-summary"] = {**{name:NUMBER for name in ["flammable_equipment_area_m2","flammable_personnel_area_m2",
470
+ "toxic_personnel_area_m2","nfnt_equipment_area_m2","nfnt_personnel_area_m2","generic_frequency_per_year"]}, **SPECS["level2/final-area"]}
471
+ SPECS["level2/scenario-consequence"] = {**SPECS["level2/flammable-case"],"toxic_personnel_area_m2": NUMBER,
472
+ "nfnt_equipment_area_m2": NUMBER,"nfnt_personnel_area_m2": NUMBER,"hole": Literal["small","medium","large","rupture"]}
473
+ SPECS["level2/scenario-summary"] = SPECS["level2/consequence-summary"]
474
+ SPECS["level2/assessment"] = {"integration_scope": Literal["supplied_level2_event_probabilities_areas_and_damage"],
475
+ "management_factor": NUMBER, **SPECS["level2/consequence-summary"], **SPECS["financial/level1-consequence"], **SPECS["risk/aggregate"]}
476
+
477
+ SPECS["properties/pool-surface-interaction"] = {"thermal_conductivity_w_m_k": NUMBER,"thermal_diffusivity_m2_s": NUMBER,"roughness_factor": NUMBER}
478
+ SPECS["release/pool-evaporation-regime"] = {"regime": Literal["boiling","non_boiling","boundary_requires_qualification"]}
479
+ SPECS["release/boiling-pool-evaporation"] = {"evaporation_rate_kg_s": NUMBER,"latent_heat_rate_w": NUMBER}
480
+ SPECS["release/boiling-pool-radius"] = {"pool_radius_m": NUMBER,"pool_area_m2": NUMBER}
481
+ SPECS["release/boiling-pool-steady-source"] = {"equilibrium_evaporation_rate_kg_s": NUMBER,"vapor_volumetric_rate_m3_s": NUMBER,
482
+ "time_to_steady_s": NUMBER | None,"pool_radius_m": NUMBER,"pool_area_m2": NUMBER,"vapor_source_rate_kg_s": NUMBER | None,
483
+ "support_status": Literal["supported","duration_limited","area_limited","duration_and_area_limited","no_feed"]}
484
+ SPECS["release/nonboiling-pool-evaporation"] = {"evaporation_rate_kg_s": NUMBER}
485
+ SPECS["release/nonboiling-pool-steady-source"] = {"equilibrium_evaporation_rate_kg_s": NUMBER | None,
486
+ "pool_radius_m": NUMBER | None,"pool_area_m2": NUMBER | None,"vapor_source_rate_kg_s": NUMBER | None,
487
+ "support_status": Literal["supported","area_limited","no_feed","no_finite_steady_state"]}
488
+
489
+ _RELEASE_PHASE = Literal["vapor","liquid","two_phase"] | None
490
+ SPECS["release/level2-release-phase"] = {"release_phase": _RELEASE_PHASE,
491
+ "status": Literal["classified","no_driving_pressure","saturation_storage_boundary","saturation_ambient_boundary"]}
492
+ SPECS["release/level2-orifice-rate"] = {"mass_rate_kg_s": NUMBER,"area_m2": NUMBER,"release_phase": _RELEASE_PHASE,
493
+ "rate_method": Literal["ideal_gas","liquid","liquid_conservative_two_phase","no_driving_pressure"],
494
+ "phase_basis": Literal["pressure_screen","qualified_boundary"]}
495
+ SPECS["release/kletz-rainout-fraction"] = {"rainout_mass_fraction": Fraction}
496
+ SPECS["release/rainout-rate-split"] = {"pool_liquid_rate_kg_s": NUMBER,"jet_total_rate_kg_s": NUMBER}
497
+ SPECS["release/jet-liquid-entrainment"] = {"entrained_liquid_mass_fraction": float | None,"jet_vapor_mass_fraction": Fraction | None,
498
+ "physical_range": bool,"jet_fraction_nonzero": bool,"equation_basis": Literal["api581_printed","post_flash_mass_balance"]}
499
+ SPECS["release/level2-source-partition"] = {**SPECS["release/jet-liquid-entrainment"], **SPECS["release/rainout-rate-split"],
500
+ **{name:NUMBER for name in ["pool_liquid_mass_kg","jet_total_mass_kg","jet_liquid_rate_kg_s","jet_vapor_rate_kg_s","jet_liquid_mass_kg","jet_vapor_mass_kg"]}}
501
+
502
+ SPECS["release/flammable-phase-rates"] = {"flammable_rate_kg_s": NUMBER,"flammable_vapor_rate_kg_s": NUMBER,"flammable_liquid_rate_kg_s": NUMBER}
503
+ SPECS["events/ambient-ignition"] = {"ambient_ignition_probability": Fraction,"evaluated_rate_kg_s": NUMBER,"rate_capped": bool}
504
+ SPECS["events/ait-ignition-maximum"] = {"maximum_ignition_probability": Fraction}
505
+ SPECS["events/probability-temperature"] = {"probability": Fraction,"temperature_weight": Fraction,"reference_temperature_k": NUMBER}
506
+ SPECS["events/conditional-table"] = {"immediate_at_reference": Fraction,"immediate_at_ait": Fraction,"vce_given_delayed": Fraction,"flash_given_delayed": Fraction}
507
+ SPECS["events/two-phase-probability"] = {"probability": Fraction,"mixing_basis": Literal["api581_printed_liquid_weight","qualified_vapor_weight"]}
508
+ SPECS["events/single-phase-tree"] = {"terminal_probabilities": dict[str,Fraction],"non_ignition_probability": Fraction,
509
+ "probability_sum": NUMBER,"fireball_applicability_basis": Literal["rupture_only_text","figure53_instantaneous"]}
510
+ SPECS["events/single-phase-ignition"] = {**SPECS["events/ambient-ignition"],**SPECS["events/ait-ignition-maximum"],**SPECS["events/single-phase-tree"],
511
+ "ignition_probability": Fraction,"immediate_given_ignition": Fraction,"vce_given_delayed": Fraction,"flash_given_delayed": Fraction,
512
+ "reference_temperature_k": NUMBER,"temperature_weight": Fraction}
513
+
514
+ SPECS["level2/correlated-jet-pool"] = {"equipment_area_m2": NUMBER,"personnel_area_m2": NUMBER,
515
+ "maximum_equipment_area_m2": NUMBER,"maximum_personnel_area_m2": NUMBER,
516
+ "governing_equipment": Literal["jet","pool","equal"],"governing_personnel": Literal["jet","pool","equal"]}
517
+ SPECS["events/fireball-given-immediate"] = {"fireball_given_immediate": Fraction}
518
+ SPECS["events/two-phase-tree"] = {**SPECS["events/single-phase-tree"],"fireball_given_immediate": Fraction,
519
+ "fireball_probability_basis": Literal["api581_eq3_123_124","qualified_figure54_branch"]}
520
+ SPECS["events/two-phase-ignition"] = {**SPECS["events/two-phase-tree"],**SPECS["release/flammable-phase-rates"],
521
+ **{name:Fraction for name in ["ignition_probability","immediate_given_ignition","vce_given_delayed","flash_given_delayed",
522
+ "liquid_ignition_probability","vapor_ignition_probability","liquid_immediate_given_ignition","vapor_immediate_given_ignition","temperature_weight"]},
523
+ "reference_temperature_k": NUMBER,"mixing_basis": Literal["api581_printed_liquid_weight","qualified_vapor_weight"]}
524
+
525
+ SPECS["tank/fluid-table"] = {"molecular_weight_kg_kmol":NUMBER,"liquid_density_kg_m3":NUMBER,"dynamic_viscosity_pa_s":NUMBER}
526
+ SPECS["tank/soil-table"] = {"printed_lower_bound_cm_s":NUMBER,"printed_upper_bound_cm_s":NUMBER,"porosity":Fraction}
527
+ SPECS["tank/soil-water-conductivity"] = {"water_hydraulic_conductivity_m_day":NUMBER}
528
+ SPECS["tank/fluid-conductivity"] = {"product_hydraulic_conductivity_m_day":NUMBER}
529
+ SPECS["tank/seepage-velocity"] = {"seepage_velocity_m_day":NUMBER}
530
+ SPECS["tank/bottom-hole-count"] = {"small_hole_count":int,"medium_hole_count":int,"large_hole_count":int,"outside_tabulated_diameter_range":bool}
531
+ SPECS["tank/bottom-inventory"] = {"available_volume_m3":NUMBER,"available_volume_bbl":NUMBER,"available_mass_kg":NUMBER}
532
+ SPECS["tank/shell-course-inventory"] = {**SPECS["tank/bottom-inventory"],"course_bottom_elevation_m":NUMBER,"available_liquid_head_m":NUMBER,"course_wet":bool}
533
+ _TANK_FLOW = {"native_rate_bbl_day":NUMBER,"volume_rate_m3_s":NUMBER,"mass_rate_kg_s":NUMBER}
534
+ SPECS["tank/shell-flow"] = {**_TANK_FLOW,"hole_area_m2":NUMBER}
535
+ SPECS["tank/bottom-flow"] = {**_TANK_FLOW,"per_hole_native_rate_bbl_day":NUMBER,"equation":Literal["3.210","3.211","3.212","zero_flow"],
536
+ "liquid_head_used_m":NUMBER,"lower_conductivity_threshold_m_day":NUMBER | None,"upper_conductivity_threshold_m_day":NUMBER | None,
537
+ "applied_hole_multiplier":int,"transition_hole_basis":Literal["api581_printed","per_hole_scaled"]}
538
+ SPECS["tank/shell-detection-time"] = {"detection_time_days":NUMBER,"diameter_boundary_m":NUMBER}
539
+ SPECS["tank/bottom-detection-time"] = {"detection_time_days":NUMBER,"selected_basis":Literal["concrete_asphalt","barrier","unprotected"]}
540
+ SPECS["tank/release-volume"] = {"release_duration_days":NUMBER | None,"released_volume_bbl":NUMBER,"released_volume_m3":NUMBER,
541
+ "released_mass_kg":NUMBER,"printed_mass_index":NUMBER,"release_type":Literal["continuous"]}
542
+
543
+ SPECS["tank/environment-cost-table"] = {"cost_by_location_usd_per_bbl":dict[str,NUMBER]}
544
+ _SURFACE_VOLUMES = {k+"_bbl":NUMBER for k in ["in_dike","surface_on_site","surface_off_site","surface_water"]}
545
+ SPECS["tank/surface-spill-partition"] = _SURFACE_VOLUMES
546
+ SPECS["tank/groundwater-arrival"] = {"arrival_time_days":NUMBER | None,"arrival_status":Literal["already_at_groundwater","no_finite_arrival","finite_travel"]}
547
+ SPECS["tank/subsurface-spill-partition"] = {"groundwater_bbl":NUMBER,"subsoil_bbl":NUMBER,"groundwater_fraction":Fraction}
548
+ _ENV_COST_OUTPUT = {"leak_environment_cost":NUMBER,"rupture_environment_cost":NUMBER,"environment_cost":NUMBER,"currency":str,"cost_basis":str}
549
+ SPECS["tank/shell-environment-cost"] = {**_ENV_COST_OUTPUT,"weighted_leak_volume_bbl":NUMBER,"weighted_rupture_volume_bbl":NUMBER,
550
+ "weighted_leak_surface_volumes_bbl":dict[str,NUMBER],"weighted_rupture_surface_volumes_bbl":dict[str,NUMBER]}
551
+ SPECS["tank/bottom-environment-cost"] = {**_ENV_COST_OUTPUT,"weighted_groundwater_volume_bbl":NUMBER,"weighted_subsoil_volume_bbl":NUMBER,
552
+ "weighted_rupture_volume_bbl":NUMBER,"weighted_rupture_surface_volumes_bbl":dict[str,NUMBER]}
553
+ SPECS["tank/bottom-repair-cost"] = {"component_repair_cost":NUMBER,"currency":str,"cost_basis":str}
554
+
555
+ SPECS["tank/generic-frequency"] = {"by_hole_per_year":dict[str,NUMBER],"total_per_year":NUMBER,"printed_total_per_year":NUMBER,
556
+ "sum_minus_printed_per_year":float,"total_basis":Literal["hole_sum_eq3_208"]}
557
+ SPECS["tank/component-outage"] = {"component_outage_days":NUMBER,"effective_days_by_hole":dict[str,NUMBER | None]}
558
+ _TANK_FINANCIAL = {**{k:NUMBER for k in ["component_repair_cost","surrounding_equipment_cost","business_interruption_cost",
559
+ "injury_cost","environmental_cost","component_outage_days","surrounding_outage_days","surrounding_cost_reference_usd_2001",
560
+ "leak_environment_cost","rupture_environment_cost","financial_consequence"]},"currency":str,"cost_basis_year":int,"cost_basis":str}
561
+ SPECS["tank/bottom-financial-consequence"] = _TANK_FINANCIAL
562
+ SPECS["tank/shell-financial-consequence"] = _TANK_FINANCIAL
563
+ _TANK_RISK = {**_TANK_FINANCIAL,**{k:NUMBER for k in ["generic_frequency_per_year","management_factor","annual_failure_frequency","financial_risk_per_year"]},
564
+ "annual_frequency_by_hole":dict[str,NUMBER],"integration_scope":Literal["supplied_uniform_df_and_tank_release_consequences"]}
565
+ SPECS["tank/bottom-risk-assessment"] = _TANK_RISK
566
+ SPECS["tank/shell-risk-assessment"] = {**_TANK_RISK,"equipment_area_risk_m2_per_year":NUMBER,"personnel_area_risk_m2_per_year":NUMBER}
567
+
568
+ _TANK_HOLES = {"diameter_by_hole_m":dict[str,NUMBER],"area_by_hole_m2":dict[str,NUMBER]}
569
+ SPECS["tank/shell-hole-sizes"] = _TANK_HOLES
570
+ SPECS["tank/bottom-hole-sizes"] = _TANK_HOLES
571
+ _TANK_SOURCE = {**_TANK_HOLES,**SPECS["tank/bottom-inventory"],"generic_frequency_by_hole_per_year":dict[str,NUMBER],
572
+ "generic_total_per_year":NUMBER,"printed_generic_total_per_year":NUMBER,"generic_total_basis":Literal["hole_sum_eq3_208"],
573
+ **{k:dict[str,NUMBER | None] for k in ["native_rate_by_hole_bbl_day","mass_rate_by_hole_kg_s","detection_time_by_hole_days","release_duration_by_hole_days"]},
574
+ **{k:dict[str,NUMBER] for k in ["released_volume_by_hole_bbl","released_volume_by_hole_m3","released_mass_by_hole_kg"]},
575
+ "release_type":Literal["continuous"],"liquid_density_kg_m3":NUMBER}
576
+ SPECS["tank/shell-source-assessment"] = {**_TANK_SOURCE,**SPECS["tank/shell-course-inventory"],"source_scope":Literal["single_shell_course"]}
577
+ SPECS["tank/bottom-source-assessment"] = {**_TANK_SOURCE,**SPECS["tank/bottom-hole-count"],
578
+ "product_hydraulic_conductivity_m_day":NUMBER,"seepage_velocity_m_day":NUMBER,
579
+ "bottom_flow_equation":Literal["3.210","3.211","3.212","zero_flow"],"applied_small_hole_multiplier":int,
580
+ "detection_time_days":NUMBER,"detection_selected_basis":Literal["concrete_asphalt","barrier","unprotected"],"source_scope":Literal["single_tank_bottom"]}
581
+
582
+ SPECS["tank/bottom-integrated-assessment"] = {**SPECS["tank/bottom-source-assessment"],**_TANK_RISK,
583
+ "groundwater_arrival_time_days":NUMBER | None,
584
+ "integration_scope":Literal["bottom_geometry_soil_source_financial_risk_with_supplied_df"]}
585
+
586
+ _DIKED_POOL = dict(SPECS["effects/pool-fire-consequence"])
587
+ for _name in ("personnel_safe_surface_distance_m","equipment_safe_surface_distance_m"):
588
+ _DIKED_POOL["unclipped_"+_name] = _DIKED_POOL.pop(_name)
589
+ SPECS["tank/diked-pool-consequence"] = {**_DIKED_POOL,
590
+ **{k:NUMBER for k in ["unclipped_equipment_area_m2","unclipped_personnel_area_m2","effective_pool_area_limit_m2","dike_area_m2"]},
591
+ "equipment_area_clipped":bool,"personnel_area_clipped":bool,"dike_limit_basis":Literal["burning_pool_area","burning_and_consequence_area"]}
592
+ SPECS["tank/shell-level2-case"] = {**SPECS["level2/flammable-case"],"toxic_personnel_area_m2":NUMBER,"nfnt_status":Literal["not_determined_for_ast"]}
593
+ _AST_MECHANISMS = ["flammable_equipment_area_m2","flammable_personnel_area_m2","toxic_personnel_area_m2"]
594
+ SPECS["tank/shell-level2-summary"] = {**{k:NUMBER for k in [*_AST_MECHANISMS,"equipment_area_m2","personnel_area_m2","consequence_area_m2","generic_frequency_per_year"]},
595
+ **{"by_hole_"+k:dict[str,NUMBER] for k in _AST_MECHANISMS},"nfnt_status":Literal["not_determined_for_ast"]}
596
+ SPECS["tank/shell-integrated-assessment"] = {**SPECS["tank/shell-source-assessment"],**SPECS["tank/shell-level2-summary"],
597
+ **SPECS["tank/shell-risk-assessment"],"integration_scope":Literal["shell_geometry_source_supplied_event_footprints_financial_risk"]}
598
+
599
+ SPECS["dispersion/native-engine-capabilities"] = {"requested_engines":list[Literal["slabx","slabx-lh2"]],
600
+ "required_versions":dict[str,str],"installed_versions":dict[str,str | None],
601
+ "engine_status":dict[str,Literal["missing","available","version_mismatch","not_importable"]],
602
+ "module_import_status":dict[str,Literal["not_installed","importable","not_importable"]],
603
+ "worker_isolation":Literal["subprocess"],
604
+ "supported_operations":list[str],"probe_scope":Literal["package_presence_version_and_importability"]}
605
+ SPECS["dispersion/native-pool-centreline"] = {"engine":Literal["slabx","slabx-lh2"],"engine_versions":dict[str,str],
606
+ "engine_source_fingerprints":dict[str,str],"downwind_distance_m":list[float],"centreline_volume_fraction":list[Fraction],
607
+ "native_grid_maximum_downwind_distance_m":NUMBER,
608
+ "native_threshold_distance_m":NUMBER | None,"threshold_distance_m":NUMBER | None,
609
+ "threshold_status":Literal["premise_violated","boundary_censored","interpolated","not_reached"],
610
+ "premise_status":Literal["not_evaluated","violated","within_premise"],
611
+ "maximum_vertical_to_horizontal_velocity_ratio":NUMBER | None,
612
+ "used_source_area_m2":NUMBER,"effective_source_half_width_m":NUMBER,"native_messages":str,"averaging_time_s":NUMBER,"receptor_height_m":NUMBER,
613
+ "spatial_output_scope":Literal["centreline_only_no_footprint_area"]}
614
+
615
+ _GRID_AREA = {"sampled_exceedance_area_m2":NUMBER,"threshold_area_m2":NUMBER | None,
616
+ "footprint_status":Literal["boundary_censored","closed_on_supplied_grid","not_reached"],
617
+ "boundary_sides":list[Literal["upwind","downwind","negative_crosswind","positive_crosswind"]],
618
+ "positive_area_cell_count":int,"downwind_node_count":int,"crosswind_node_count":int,
619
+ "interpolation_basis":Literal["piecewise_linear_main_diagonal_triangles"]}
620
+ SPECS["dispersion/threshold-grid-area"] = _GRID_AREA
621
+ SPECS["dispersion/native-pool-footprint"] = {**SPECS["dispersion/native-pool-centreline"],**_GRID_AREA,
622
+ "footprint_status":Literal["boundary_censored","closed_on_supplied_grid","not_reached","premise_violated"],
623
+ "crosswind_distance_m":list[float],"volume_fraction_by_crosswind_then_downwind":list[list[Fraction]],
624
+ "spatial_output_scope":Literal["planar_sampled_threshold_field"]}
625
+ SPECS["dispersion/native-pool-flash-fire"] = {**SPECS["dispersion/native-pool-footprint"],**SPECS["effects/flash-fire"],
626
+ "criterion_role":Literal["qualified_lfl"],"receptor_height_m":Literal[0.0]}
627
+ _NATIVE_JET = {k:v for k,v in SPECS["dispersion/native-pool-centreline"].items() if k != "effective_source_half_width_m"}
628
+ _NATIVE_JET.update(orientation=Literal["horizontal_downwind","vertical_up"],jet_exit_area_m2=NUMBER,
629
+ geometric_exit_half_width_m=NUMBER,native_exit_velocity_m_s=NUMBER,requested_source_temperature_k=NUMBER,
630
+ used_source_temperature_k=NUMBER,source_temperature_clamped=bool,native_jet_liquid_mass_fraction=Fraction)
631
+ _NATIVE_JET.update(native_initial_downwind_distance_m=NUMBER,
632
+ native_near_field_status=Literal["not_reconstructed_before_native_handoff","briggs_buoyant_effective_horizontal_source"])
633
+ SPECS["dispersion/native-jet-centreline"] = _NATIVE_JET
634
+ SPECS["dispersion/native-jet-footprint"] = {**_NATIVE_JET,**_GRID_AREA,
635
+ "footprint_status":Literal["boundary_censored","closed_on_supplied_grid","not_reached","premise_violated"],
636
+ "crosswind_distance_m":list[float],"volume_fraction_by_crosswind_then_downwind":list[list[Fraction]],
637
+ "spatial_output_scope":Literal["planar_sampled_threshold_field"]}
638
+ _JET_HANDOFF = {**SPECS["release/level2-source-partition"],"release_duration_s":NUMBER,
639
+ "integration_scope":Literal["qualified_partition_to_native_jet"]}
640
+ SPECS["dispersion/partitioned-jet-centreline"] = {**SPECS["dispersion/native-jet-centreline"],**_JET_HANDOFF}
641
+ SPECS["dispersion/partitioned-jet-footprint"] = {**SPECS["dispersion/native-jet-footprint"],**_JET_HANDOFF}
642
+
643
+ SPECS["consequence/select-toxic-criterion"] = {"fluid_id":str,"selected_criterion_id":str,
644
+ "selected_kind":Literal["probit50","lc50","erpg3","aegl3","teel3","idlh","epa_endpoint"],"priority_tier":Literal[1,2,3],
645
+ "pure_component_limit_ppm":NUMBER,"modified_mixture_limit_ppm":NUMBER | None,"threshold_volume_fraction":Fraction | None,
646
+ "component_present":bool,"attainable_in_mixture":bool,"exposure_duration_s":NUMBER,"criterion_source":str,
647
+ "eligible_candidate_ids":list[str],"excluded_candidate_ids":dict[str,str],"unavailable_candidate_reasons":dict[str,str]}
648
+ SPECS["dispersion/native-pool-toxic-consequence"] = {**SPECS["dispersion/native-pool-footprint"],
649
+ **SPECS["consequence/select-toxic-criterion"],**SPECS["consequence/level2-toxic-case"],"release_duration_s":NUMBER,
650
+ "release_duration_governing_limit":Literal["one_hour","inventory","detection_isolation","no_release","no_inventory"],
651
+ "exposure_model_basis":Literal["constant_exposure_equivalent_native_time_average"],"receptor_height_m":Literal[0.0],"equipment_area_m2":Literal[0.0]}
652
+
653
+ SPECS["damage/soil-base-rate-table"] = {"corrosion_rate_m_year":NUMBER,"printed_si_rate_mm_year":NUMBER,
654
+ "printed_us_rate_mpy":NUMBER,"selected_unit_basis":Literal["printed_si","printed_us_mpy"],"condition_description":str}
655
+ SPECS["damage/soil-resistivity-factor"] = {"resistivity_factor":NUMBER,"source_row":int}
656
+ SPECS["damage/soil-temperature-factor"] = {"temperature_factor":NUMBER,"lower_boundary_k":NUMBER,"upper_boundary_k":NUMBER,
657
+ "threshold_basis":Literal["printed_si","printed_us_converted"]}
658
+ SPECS["damage/soil-cp-factor"] = {"cathodic_protection_factor":NUMBER}
659
+ SPECS["damage/soil-coating-factor"] = {**{k:NUMBER for k in ["coating_effectiveness_factor","base_factor","age_factor","temperature_abuse_factor","maintenance_factor"]},
660
+ "calculation_basis":Literal["table_factor_product"],"printed_example_discrepancy_applies":bool,"printed_example_reported_factor":NUMBER | None}
661
+ SPECS["damage/soil-rate-equation"] = {"corrosion_rate_m_year":NUMBER}
662
+ SPECS["damage/soil-corrosion-rate"] = {**SPECS["damage/soil-rate-equation"],**{k:NUMBER for k in ["resistivity_factor","temperature_factor","cathodic_protection_factor","coating_effectiveness_factor","base_corrosion_rate_m_year"]},
663
+ "thinning_type":Literal["local"],"resistivity_application":Literal["apply","already_in_base","omitted_by_qualification"],
664
+ "coating_calculation_basis":Literal["table_factor_product"],"coating_example_discrepancy_applies":bool}
665
+ SPECS["damage/soil-thinning-assessment"] = {**SPECS["damage/soil-corrosion-rate"],**SPECS["damage/thinning-unclad"],
666
+ "assessment_scope":Literal["unclad_internal_pressure_governed_non_ast"]}
667
+
668
+ SPECS["tank/bottom-base-corrosion-rate"] = {"base_corrosion_rate_m_year":NUMBER,"printed_si_rate_mm_year":NUMBER,"printed_us_rate_mpy":NUMBER,
669
+ "side":Literal["soil","product"],"unit_basis":Literal["printed_si","printed_us_mpy"]}
670
+ SPECS["tank/bottom-soil-rate-equation"] = {"soil_corrosion_rate_m_year":NUMBER}
671
+ SPECS["tank/bottom-product-rate-equation"] = {"product_corrosion_rate_m_year":NUMBER}
672
+ SPECS["tank/bottom-soil-resistivity-factor"] = {"resistivity_factor":NUMBER,"selection_reason":Literal["rpb","unknown_assume_moderate","resistivity_table"]}
673
+ for identifier, field in [("pad","pad_factor"),("drainage","drainage_factor"),("type","bottom_type_factor"),
674
+ ("product-condition","product_condition_factor"),("steam-coil","steam_coil_factor"),("water-draw","water_draw_factor")]:
675
+ SPECS[f"tank/bottom-{identifier}-factor"] = {field:NUMBER}
676
+ SPECS["tank/bottom-cp-factor"] = {"nominal_table_factor":NUMBER,"cathodic_protection_factor":NUMBER,"credit_applied":bool}
677
+ SPECS["tank/bottom-temperature-factor"] = {"temperature_factor":NUMBER,"source_row":int,"threshold_basis":Literal["printed_si","printed_us_converted"]}
678
+ SPECS["tank/bottom-corrosion-rate-combine"] = {"raw_combined_rate_m_year":NUMBER,"combined_corrosion_rate_m_year":NUMBER,
679
+ "recommended_minimum_rate_m_year":NUMBER,"minimum_applied":bool,"combination_rule":Literal["sum","maximum"]}
680
+ SPECS["tank/bottom-corrosion-assessment"] = {**SPECS["tank/bottom-corrosion-rate-combine"], **{k:NUMBER for k in [
681
+ "soil_corrosion_rate_m_year","product_corrosion_rate_m_year","resistivity_factor","pad_factor","drainage_factor",
682
+ "cathodic_protection_factor","bottom_type_factor","temperature_factor","product_condition_factor","steam_coil_factor","water_draw_factor"]},"cp_credit_applied":bool}
683
+
684
+ SPECS["tank/bottom-minimum-thickness"] = {"minimum_thickness_m":NUMBER,"thickness_basis":Literal["api581_2016_default","documented_owner_method"]}
685
+ SPECS["tank/bottom-wall-parameter"] = {"art_parameter":NUMBER,"predicted_remaining_thickness_m":float,"predicted_wall_loss_m":NUMBER,
686
+ "reference_thickness_m":NUMBER,"at_or_below_minimum_thickness":bool,"predicted_penetration":bool}
687
+ SPECS["tank/bottom-inspection-selection"] = {"selected_inspection_grade":Literal["a","b","c","d","e"],"credited_inspection_count":int,"eligible_inspection_count":int}
688
+ SPECS["tank/bottom-thinning-base"] = {"base_damage_factor":NUMBER,"lower_art_row":NUMBER,"upper_art_row":NUMBER,"interpolation_weight":NUMBER,
689
+ "lookup_policy":Literal["exact_rows_only","linear_between_rows","conservative_upper_row"]}
690
+ SPECS["tank/bottom-thinning-adjustment-factors"] = {"welded_construction_factor":NUMBER,"maintenance_factor":NUMBER,"settlement_factor":NUMBER}
691
+ SPECS["tank/bottom-thinning-assessment"] = {**SPECS["tank/bottom-minimum-thickness"],**SPECS["tank/bottom-wall-parameter"],
692
+ **SPECS["tank/bottom-inspection-selection"],**SPECS["tank/bottom-thinning-base"],**SPECS["tank/bottom-thinning-adjustment-factors"],
693
+ "thinning_damage_factor":NUMBER,"online_monitoring_factor":Literal[1.0]}
694
+ SPECS["tank/bottom-corrosion-thinning-assessment"] = {**SPECS["tank/bottom-corrosion-assessment"],**SPECS["tank/bottom-thinning-assessment"]}
695
+ SPECS["tank/bottom-corrosion-risk-assessment"] = {**SPECS["tank/bottom-corrosion-thinning-assessment"],**SPECS["tank/bottom-integrated-assessment"],
696
+ "total_damage_factor":NUMBER,"integration_scope":Literal["bottom_corrosion_thinning_source_financial_risk_qualified_thinning_only"]}
697
+
698
+ SPECS["damage/cladding-remaining-life"] = {"remaining_cladding_at_baseline_m":NUMBER,"cladding_depletion_age_years":NUMBER | None,
699
+ "cladding_baseline_state":Literal["already_depleted","noncorroding_present","finite_depletion"]}
700
+ SPECS["damage/thinning-clad-wall-loss"] = {**SPECS["damage/cladding-remaining-life"],"wall_loss_fraction":NUMBER,
701
+ "cladding_wall_loss_m":NUMBER,"base_material_wall_loss_m":NUMBER,"base_material_exposure_years":NUMBER,
702
+ "predicted_remaining_thickness_m":float,"predicted_penetration":bool,
703
+ "wall_loss_branch":Literal["base_only_eq2_13","noncorroding_cladding_extension","cladding_only_eq2_14","cladding_then_base_eq2_15"]}
704
+ SPECS["damage/thinning-design-strength-ratio"] = {"strength_ratio":NUMBER,"governing_minimum_thickness_m":NUMBER,
705
+ "governing_thickness_source":Literal["equal_minima","structural_minimum","required_minimum"]}
706
+ SPECS["damage/thinning-clad"] = {**SPECS["damage/thinning-clad-wall-loss"],**SPECS["damage/thinning-posterior"],
707
+ **SPECS["damage/thinning-base"],**SPECS["damage/thinning-adjust"],"strength_ratio":NUMBER,
708
+ "strength_method":Literal["internal_pressure_eq2_18","design_thickness_eq2_17"]}
709
+ SPECS["damage/thinning-unclad-design"] = {**SPECS["damage/thinning-wall-loss"],**SPECS["damage/thinning-design-strength-ratio"],
710
+ **SPECS["damage/thinning-posterior"],**SPECS["damage/thinning-base"],**SPECS["damage/thinning-adjust"]}
711
+
712
+ from .thinning_conditions import Row as MonitoringRow
713
+ SPECS["damage/thinning-monitoring-row"] = {"monitoring_row":MonitoringRow,"velocity_threshold_m_s":NUMBER | None}
714
+ SPECS["damage/thinning-monitoring-table-factor"] = {"table_monitoring_factor":NUMBER}
715
+ SPECS["damage/thinning-online-monitoring-factor"] = {**SPECS["damage/thinning-monitoring-row"],"online_monitoring_factor":NUMBER,
716
+ "candidate_method_factors":dict[str,NUMBER],"monitoring_credit_basis":Literal["no_organized_plan","qualified_experience_replacement","maximum_table_method","no_monitoring_methods"],"joint_exception_applied":bool}
717
+ SPECS["damage/thinning-injection-point-factor"] = {"injection_point_factor":NUMBER}
718
+ SPECS["damage/thinning-deadleg-factor"] = {"deadleg_factor":NUMBER}
719
+ _THINNING_CONDITIONS = {**SPECS["damage/thinning-online-monitoring-factor"],**SPECS["damage/thinning-injection-point-factor"],**SPECS["damage/thinning-deadleg-factor"]}
720
+ SPECS["damage/thinning-conditional-adjustment"] = {**_THINNING_CONDITIONS,"base_damage_factor":NUMBER,"thinning_damage_factor":NUMBER}
721
+ SPECS["damage/thinning-unclad-qualified"] = {**SPECS["damage/thinning-unclad"],**_THINNING_CONDITIONS,
722
+ "strength_method":Literal["internal_pressure_eq2_18","design_thickness_eq2_17"]}
723
+ SPECS["damage/thinning-clad-qualified"] = {**SPECS["damage/thinning-clad"],**_THINNING_CONDITIONS}
724
+
725
+ SPECS["damage/lining-effective-age"] = {"effective_age_years":NUMBER,"elapsed_service_years":NUMBER,"age_baseline_date":str,
726
+ "age_baseline_source":Literal["qualified_ab_inspection","installation"],"reset_inspection_id":str | None,
727
+ "qualified_ab_inspection_count":int,"age_basis_policy":Literal["step1_installation_or_last_ab","figure51_organic_service_only"]}
728
+ SPECS["damage/lining-base-factor"] = {"base_damage_factor":NUMBER,"lower_age_row_years":NUMBER,"upper_age_row_years":NUMBER,
729
+ "age_interpolation_weight":NUMBER,"first_year_value_used":bool,"source_table":Literal["5.4","5.5"]}
730
+ SPECS["damage/lining-condition-factor"] = {"condition_factor":NUMBER}
731
+ SPECS["damage/lining-monitoring-factor"] = {"monitoring_factor":NUMBER}
732
+ SPECS["damage/lining-governing-thinning"] = {"governing_thinning_damage_factor":NUMBER,"governing_source":Literal["equal","lining","base_material_thinning"]}
733
+ SPECS["damage/lining-assessment"] = {**SPECS["damage/lining-effective-age"],**SPECS["damage/lining-base-factor"],
734
+ **SPECS["damage/lining-adjust"],**SPECS["damage/lining-governing-thinning"],"base_material_thinning_damage_factor":NUMBER}
735
+
736
+ SPECS["damage/cooling-water-ph-coefficients"] = {"c1":NUMBER,"c2":NUMBER,"c3":NUMBER,"c4":NUMBER,"c4_printed_literal_used":bool}
737
+ SPECS["damage/cooling-water-rate-factors"] = {"scale_potential":bool,"deposit_risk":bool,
738
+ "biological_or_mic_risk":bool,"underdeposit_risk":bool,"factor_flags":list[str]}
739
+ SPECS["damage/cooling-water-saturation-ph"] = {"saturation_ph":float}
740
+ SPECS["damage/cooling-water-stability-indices"] = {"langelier_saturation_index":float,"ryznar_stability_index":float}
741
+ SPECS["damage/cooling-water-base-rate"] = {"base_corrosion_rate_m_year":NUMBER,"base_column":Literal["unprotected_high","scaling_low"],"base_velocity_threshold_m_s":NUMBER}
742
+ SPECS["damage/cooling-water-temperature-factor"] = {"temperature_factor":NUMBER,"temperature_table_argument":float,"misordered_row_ignored":bool}
743
+ SPECS["damage/cooling-water-velocity-factor"] = {"velocity_factor":NUMBER}
744
+ SPECS["damage/cooling-water-rate-equation"] = {"corrosion_rate_m_year":NUMBER}
745
+ SPECS["damage/cooling-water-seawater-rate"] = {"corrosion_rate_m_year":NUMBER}
746
+ SPECS["damage/cooling-water-coupon-pitting-rate"] = {"pitting_corrosion_rate_m_year":NUMBER}
747
+ SPECS["damage/cooling-water-fresh-assessment"] = {**SPECS["damage/cooling-water-stability-indices"],**SPECS["damage/cooling-water-base-rate"],
748
+ **SPECS["damage/cooling-water-temperature-factor"],**SPECS["damage/cooling-water-velocity-factor"],**SPECS["damage/cooling-water-rate-equation"]}
749
+ SPECS["damage/cooling-water-thinning-assessment"] = {**SPECS["damage/cooling-water-fresh-assessment"],**SPECS["damage/thinning-unclad-qualified"],"thinning_type":Literal["general","local"]}
750
+
751
+ SPECS["damage/cooling-water-treatment-bounds"] = {"general_upper_bound_m_year":NUMBER,"pitting_upper_bound_m_year":NUMBER,"source_rate_relation":Literal["strictly_less_than"]}
752
+ SPECS["damage/cooling-water-system-type"] = {"system":Literal["once_through","closed_recirculated","open_recirculated"],
753
+ "water_source":Literal["fresh","seawater","brackish","unknown"],"requires_continual_makeup":bool,
754
+ "has_evaporation_or_blowdown_loss":bool,"classification_basis":Literal["supplied_operating_premise"]}
755
+ SPECS["damage/cooling-water-other-material-estimate"] = {"nominal_corrosion_rate_m_year":NUMBER}
756
+ SPECS["damage/cooling-water-measured-rate"] = {"corrosion_rate_m_year":NUMBER,"selection_source":Literal["component_measurement","coupon_general","coupon_pitting_rule"]}
757
+ SPECS["damage/cooling-water-rate-selection"] = {"corrosion_rate_m_year":NUMBER,
758
+ "selection_source":Literal["component_measurement","coupon_general","coupon_pitting_rule","freshwater_model","seawater_model","treated_screening_bound","treated_owner_rate","other_material_nominal"],
759
+ "assessment_distribution":Literal["general","local"],"source_strict_upper_bound_m_year":NUMBER | None,
760
+ "selected_rate_is_screening_bound":bool,"fallback_ignored_due_to_measurement":bool}
761
+ SPECS["damage/cooling-water-selected-thinning"] = {**SPECS["damage/cooling-water-rate-selection"],**SPECS["damage/thinning-unclad-qualified"]}
762
+
763
+ SPECS["damage/co2-relative-humidity"] = {"water_dry_gas_mass_ratio":NUMBER,"relative_humidity_fraction":NUMBER,"supersaturated":bool,"saturated":bool}
764
+ SPECS["damage/co2-dew-point"] = {"dew_point_temperature_k":NUMBER}
765
+ SPECS["damage/co2-temperature-ph-factor"] = {"temperature_ph_factor":NUMBER,"sharp_temperature_interval_interpolated":bool}
766
+ SPECS["damage/co2-ph-estimate"] = {"estimated_ph":float}
767
+ SPECS["damage/co2-fugacity"] = {"fugacity_pa":NUMBER,"fugacity_coefficient":NUMBER}
768
+ SPECS["damage/co2-reynolds"] = {"reynolds_number":NUMBER}
769
+ SPECS["damage/co2-friction-factor"] = {"friction_factor":NUMBER}
770
+ SPECS["damage/co2-shear-stress"] = {"shear_stress_pa":NUMBER}
771
+ SPECS["damage/co2-base-rate"] = {"base_corrosion_rate_m_year":NUMBER,"applied_shear_stress_pa":NUMBER,"shear_cap_applied":bool}
772
+ SPECS["damage/co2-glycol-factor"] = {"glycol_factor":NUMBER,"glycol_floor_applied":bool}
773
+ SPECS["damage/co2-rate-adjustment"] = {"glycol_factor":NUMBER,"inhibitor_factor":NUMBER,"applied_reduction_factor":NUMBER,"corrosion_rate_m_year":NUMBER}
774
+ SPECS["damage/co2-corrosion-assessment"] = {**SPECS["damage/co2-rate-adjustment"],"base_corrosion_rate_m_year":NUMBER,
775
+ "calculation_branch":Literal["no_free_water","no_co2","wet_carbonic_acid_model"],"model_ph":float | None,
776
+ "temperature_ph_factor":NUMBER | None,"fugacity_pa":NUMBER | None,"requested_shear_stress_pa":NUMBER | None,
777
+ "applied_shear_stress_pa":NUMBER | None,"shear_cap_applied":bool,"sharp_temperature_interval_interpolated":bool}
778
+ SPECS["damage/co2-thinning-assessment"] = {**SPECS["damage/co2-corrosion-assessment"],**SPECS["damage/thinning-unclad-qualified"]}
779
+
780
+ SPECS["properties/co2-partial-pressure"] = {"co2_partial_pressure_pa_abs":NUMBER}
781
+ SPECS["damage/co2-reynolds-mass-flow"] = {"mass_flux_kg_m2_s":NUMBER,"reynolds_number":NUMBER}
782
+ SPECS["damage/co2-material-screen"] = {"material_screen_decision":Literal["evaluate_co2","source_assumed_resistant","not_covered"],"source_material_resistance_assumed":bool}
783
+ SPECS["damage/co2-hydrocarbon-wetting-screen"] = {"wetting_screen_decision":Literal["figure_low_water_high_velocity_exemption","proceed_to_water_check"],
784
+ "water_content_percent_used":NUMBER | None,"source_water_default_used":bool}
785
+ SPECS["damage/co2-moisture-screen"] = {"free_water_screen_state":Literal["present","absent","indeterminate"],"free_water_assumed_from_missing_data":bool}
786
+ SPECS["damage/co2-screened-assessment"] = {**{k:v for k,v in SPECS["damage/co2-corrosion-assessment"].items() if k != "calculation_branch"},
787
+ **SPECS["properties/co2-partial-pressure"],**SPECS["damage/co2-material-screen"],
788
+ "wetting_screen_decision":Literal["figure_low_water_high_velocity_exemption","proceed_to_water_check"] | None,
789
+ "water_content_percent_used":NUMBER | None,"source_water_default_used":bool,
790
+ "free_water_screen_state":Literal["present","absent","indeterminate"] | None,"free_water_assumed_from_missing_data":bool,
791
+ "screened_calculation_branch":Literal["source_material_resistance","no_co2","figure_hydrocarbon_exemption","qualified_no_free_water","wet_carbonic_acid_model"]}
792
+ SPECS["damage/co2-screened-thinning"] = {**SPECS["damage/co2-screened-assessment"],**SPECS["damage/thinning-unclad-qualified"]}
793
+
794
+ SPECS["damage/oxidation-screen"] = {"screen_temperature_threshold_k":NUMBER,"temperature_screen_met":bool,"evaluate_high_temperature_oxidation":bool}
795
+ SPECS["damage/oxidation-table-row"] = {"temperature_nodes_k":list[NUMBER],"corrosion_rates_m_year":list[NUMBER | None],
796
+ "native_rates":list[NUMBER | None],"native_rate_unit":Literal["mm/year","mpy"],"source_table_ids":list[str]}
797
+ SPECS["damage/oxidation-rate"] = {"corrosion_rate_m_year":NUMBER,"lower_temperature_node_k":NUMBER,"upper_temperature_node_k":NUMBER,
798
+ "interpolation_weight":NUMBER,"rate_calculation_basis":Literal["qualified_first_node","exact_cell","upper_temperature_node","linear_between_nodes"],"first_node_value_used":bool}
799
+ SPECS["damage/oxidation-assessment"] = {**SPECS["damage/oxidation-screen"],**SPECS["damage/oxidation-rate"],"thinning_type":Literal["general"]}
800
+ SPECS["damage/oxidation-thinning-assessment"] = {**SPECS["damage/oxidation-assessment"],**SPECS["damage/thinning-unclad-qualified"]}
801
+
802
+ SPECS["damage/acid-sour-water-route"] = {"corrosion_route":Literal["no_free_water","hydrochloric_acid","alkaline_sour_water","neutral_boundary_unclassified","acid_sour_water"]}
803
+ SPECS["damage/acid-sour-water-base-rate"] = {"base_corrosion_rate_m_year":NUMBER,"ph_for_lookup":NUMBER,"ph_edge_row_used":bool}
804
+ SPECS["damage/acid-sour-water-oxygen-factor"] = {"oxygen_factor":NUMBER,"high_oxygen_localized_review":bool}
805
+ SPECS["damage/acid-sour-water-velocity-factor"] = {"velocity_factor":NUMBER,"high_velocity_localized_review":bool}
806
+ SPECS["damage/acid-sour-water-rate-equation"] = {"corrosion_rate_m_year":NUMBER}
807
+ SPECS["damage/acid-sour-water-other-material-rate"] = {"corrosion_rate_m_year":NUMBER,"selected_rate_is_screening_bound":bool}
808
+ SPECS["damage/acid-sour-water-assessment"] = {**SPECS["damage/acid-sour-water-route"],"corrosion_rate_m_year":NUMBER,
809
+ "base_corrosion_rate_m_year":NUMBER | None,"ph_for_lookup":NUMBER | None,"ph_edge_row_used":bool,
810
+ "oxygen_factor":NUMBER | None,"velocity_factor":NUMBER | None,"localized_attack_review_required":bool,
811
+ "selected_rate_is_screening_bound":bool,"default_thinning_type":Literal["general"]}
812
+ SPECS["damage/acid-sour-water-thinning-assessment"] = {**SPECS["damage/acid-sour-water-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
813
+
814
+ SPECS["properties/h2s-partial-pressure"] = {"h2s_partial_pressure_pa_abs":NUMBER}
815
+ SPECS["damage/alkaline-sour-water-nh4hs-estimate"] = {"estimated_nh4hs_mass_fraction":NUMBER,
816
+ "concentration_estimate_branch":Literal["printed_excess_h2s","printed_lower_h2s","qualified_equality_upper","qualified_equality_lower"],"estimated_fraction_exceeds_one":bool}
817
+ SPECS["damage/alkaline-sour-water-velocity-selection"] = {"selected_velocity_m_s":NUMBER,"selected_velocity_phase":Literal["vapor","liquid"]}
818
+ SPECS["damage/alkaline-sour-water-base-rate"] = {"baseline_corrosion_rate_m_year":NUMBER}
819
+ SPECS["damage/alkaline-sour-water-pressure-adjustment"] = {"corrosion_rate_m_year":NUMBER,"unclamped_pressure_factor":float,
820
+ "pressure_correction_factor":NUMBER,"negative_pressure_factor_clamped":bool,"pressure_correction_branch":Literal["at_reference","below_reference","above_reference"]}
821
+ SPECS["damage/alkaline-sour-water-assessment"] = {"corrosion_rate_m_year":NUMBER,"baseline_corrosion_rate_m_year":NUMBER | None,
822
+ "nh4hs_mass_fraction_used":NUMBER | None,"concentration_source":Literal["supplied","source_approximation"] | None,
823
+ "selected_velocity_m_s":NUMBER | None,"selected_velocity_phase":Literal["vapor","liquid"] | None,
824
+ "unclamped_pressure_factor":float | None,"pressure_correction_factor":NUMBER | None,"negative_pressure_factor_clamped":bool,
825
+ "pressure_correction_branch":Literal["at_reference","below_reference","above_reference"] | None,
826
+ "source_thinning_type":Literal["general","local"] | None,"calculation_branch":Literal["no_free_water","wet_nh4hs_model"]}
827
+ SPECS["damage/alkaline-sour-water-thinning-assessment"] = {**SPECS["damage/alkaline-sour-water-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
828
+ SPECS["damage/sour-water-assessment"] = {**SPECS["damage/acid-sour-water-route"],"corrosion_rate_m_year":NUMBER,
829
+ "selected_model_base_rate_m_year":NUMBER | None,"selected_rate_is_screening_bound":bool,"localized_attack_review_required":bool}
830
+
831
+ SPECS["damage/hcl-ph-from-chloride"] = {"estimated_ph":NUMBER,"chloride_band_lower_wppm":NUMBER,"chloride_band_upper_wppm":NUMBER,"chloride_band_upper_inclusive":bool}
832
+ SPECS["damage/hcl-chloride-interval-from-ph"] = {k:v for k,v in SPECS["damage/hcl-ph-from-chloride"].items() if k != "estimated_ph"}
833
+ SPECS["damage/hcl-ph-rate"] = {"corrosion_rate_m_year":NUMBER,"source_999_corner_used":bool,"localized_pitting_already_included":bool,"source_table_id":str}
834
+ SPECS["damage/hcl-alloy-rate"] = SPECS["damage/hcl-ph-rate"].copy()
835
+ SPECS["damage/hcl-assessment"] = {"corrosion_rate_m_year":NUMBER,"source_999_corner_used":bool,"localized_pitting_already_included":bool,"source_table_id":str | None,
836
+ "ph_used":NUMBER | None,"chloride_mass_fraction_used":Fraction | None,
837
+ "chemistry_method":Literal["supplied_ph","chloride_table","supplied_chloride","ph_interval_selection"] | None,
838
+ "source_thinning_type":Literal["local"] | None,"calculation_branch":Literal["no_free_water","wet_dilute_hcl_model"]}
839
+ SPECS["damage/hcl-thinning-assessment"] = {**SPECS["damage/hcl-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
840
+
841
+ SPECS["damage/hf-concentration-selection"] = {"hf_mass_fraction_for_lookup":Fraction,"concentrated_81_node_extension_used":bool}
842
+ SPECS["damage/hf-carbon-velocity-band"] = {"velocity_band":Literal["low","high"],"velocity_threshold_m_s":NUMBER}
843
+ SPECS["damage/hf-carbon-rate"] = {**SPECS["damage/hf-concentration-selection"],**SPECS["damage/hf-carbon-velocity-band"],
844
+ "corrosion_rate_m_year":NUMBER,"source_999_corner_used":bool,"residual_column_used":Literal["low","high"] | None,"source_table_id":str}
845
+ SPECS["damage/hf-alloy400-rate"] = {**SPECS["damage/hf-concentration-selection"],"corrosion_rate_m_year":NUMBER,"source_999_corner_used":bool,"source_table_id":str}
846
+ SPECS["damage/hf-assessment"] = {"corrosion_rate_m_year":NUMBER,"source_table_id":str | None,
847
+ "rate_source":Literal["carbon_steel_table","alloy400_table","qualified_published_rate"] | None,"source_999_corner_used":bool,
848
+ "hf_mass_fraction_for_lookup":Fraction | None,"concentrated_81_node_extension_used":bool,"velocity_band":Literal["low","high"] | None,
849
+ "velocity_threshold_m_s":NUMBER | None,"residual_column_used":Literal["low","high"] | None,
850
+ "source_thinning_type":Literal["general","local"] | None,"calculation_branch":Literal["no_hf_exposure","qualified_hf_service"]}
851
+ SPECS["damage/hf-thinning-assessment"] = {**SPECS["damage/hf-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
852
+
853
+ SPECS["damage/amine-acid-gas-loading"] = {"acid_gas_loading_mol_mol":NUMBER}
854
+ SPECS["damage/amine-loading-selection"] = {"lower_loading_row_index":int,"upper_loading_row_index":int,"loading_interpolation_weight":Fraction,
855
+ "table_loading_regime":Literal["lean","rich"],"loading_gap_mapping_used":bool}
856
+ SPECS["damage/amine-contaminant-row"] = {"contaminant_row":Literal["low","middle","high"],"printed_hsas_row_mass_fraction":Fraction}
857
+ SPECS["damage/amine-strength-factor"] = {"amine_strength_factor":NUMBER}
858
+ SPECS["damage/amine-carbon-base-rate"] = {**SPECS["damage/amine-loading-selection"],"base_corrosion_rate_m_year":NUMBER,
859
+ "velocity_band":Literal["low","high"],"velocity_threshold_m_s":NUMBER,"source_table_id":str}
860
+ SPECS["damage/amine-stainless-rate"] = {"corrosion_rate_m_year":NUMBER,"low_loading_first_row_used":bool,"source_table_id":str}
861
+ SPECS["damage/amine-corrosion-assessment"] = {"corrosion_rate_m_year":NUMBER,"base_corrosion_rate_m_year":NUMBER | None,
862
+ "amine_strength_factor":NUMBER | None,"contaminant_row":Literal["low","middle","high"] | None,"printed_hsas_row_mass_fraction":Fraction | None,
863
+ "table_loading_regime":Literal["lean","rich"] | None,"loading_gap_mapping_used":bool,"velocity_band":Literal["low","high"] | None,
864
+ "velocity_threshold_m_s":NUMBER | None,"low_loading_first_row_used":bool,"source_table_id":str | None,
865
+ "source_thinning_type":Literal["general","local"] | None,"calculation_branch":Literal["no_amine_service","carbon_amine_model","type300_stainless_model"]}
866
+ SPECS["damage/amine-thinning-assessment"] = {**SPECS["damage/amine-corrosion-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
867
+
868
+ SPECS["damage/sulfuric-table-axes"] = {"acid_mass_fraction_nodes":list[Fraction],"temperature_nodes_k":list[NUMBER],"velocity_nodes_m_s":list[NUMBER],"source_table_id":str,
869
+ "carbon_si_velocity_interpretation":Literal["not_applicable","qualified_printed_m_s","qualified_us_ft_s_header"]}
870
+ SPECS["damage/sulfuric-table-rate"] = {"corrosion_rate_m_year":NUMBER,"source_table_id":str,
871
+ "carbon_si_velocity_interpretation":Literal["not_applicable","qualified_printed_m_s","qualified_us_ft_s_header"],"source_999_corner_used":bool,
872
+ "disputed_304_cell_used":bool,"source_localized_enhancement_already_included":bool}
873
+ SPECS["damage/sulfuric-thinning-classification"] = {"source_thinning_type":Literal["general","local"],"thinning_velocity_threshold_m_s":NUMBER,"thinning_velocity_boundary_resolved":bool}
874
+ SPECS["damage/sulfuric-corrosion-assessment"] = {**SPECS["damage/sulfuric-table-rate"],"source_table_id":str | None,
875
+ "source_thinning_type":Literal["general","local"] | None,"thinning_velocity_threshold_m_s":NUMBER | None,"thinning_velocity_boundary_resolved":bool,
876
+ "rate_source":Literal["source_maximum_estimate","qualified_specialist_estimate"] | None,
877
+ "calculation_branch":Literal["no_sulfuric_service","qualified_sulfuric_service"]}
878
+ SPECS["damage/sulfuric-thinning-assessment"] = {**SPECS["damage/sulfuric-corrosion-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
879
+
880
+ SPECS["damage/h2sh2-table-axes"] = {"h2s_mole_fraction_nodes":list[Fraction],"temperature_nodes_k":list[NUMBER],
881
+ "table_group":Literal["carbon_low_alloy","cr5","cr7","cr9","cr12","stainless"],"hydrocarbon_curve_required":bool,"source_table_id":str}
882
+ SPECS["damage/h2sh2-table-rate"] = {"corrosion_rate_m_year":NUMBER,"source_table_id":str,
883
+ "selected_hydrocarbon_curve":Literal["naphtha","gas_oil"] | None,"hydrocarbon_free_curve_selection_used":bool,"source_thinning_type":Literal["general"]}
884
+ SPECS["damage/h2sh2-corrosion-assessment"] = {**SPECS["damage/h2sh2-table-rate"],"source_table_id":str | None,"source_thinning_type":Literal["general"] | None,
885
+ "calculation_branch":Literal["no_h2s_h2_service","qualified_high_temperature_h2s_h2"]}
886
+ SPECS["damage/h2sh2-thinning-assessment"] = {**SPECS["damage/h2sh2-corrosion-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
887
+
888
+ _SULFIDIC_GROUP = Literal["carbon_steel","low_alloy","cr5","cr7","cr9","cr12","stainless_no_mo","stainless_low_mo","stainless_high_mo"]
889
+ SPECS["damage/sulfidic-material-selection"] = {"table_group":_SULFIDIC_GROUP,"unknown_molybdenum_low_assumed":bool}
890
+ SPECS["damage/sulfidic-table-axes"] = {**SPECS["damage/sulfidic-material-selection"],"sulfur_mass_fraction_nodes":list[Fraction],"tan_nodes_mg_koh_g":list[NUMBER],
891
+ "lower_temperature_bin_upper_k":NUMBER,"interior_temperature_nodes_k":list[NUMBER],"upper_temperature_bin_lower_exclusive_k":NUMBER,"source_table_id":str}
892
+ SPECS["damage/sulfidic-table-rate"] = {"base_corrosion_rate_m_year":NUMBER,"source_table_id":str,**SPECS["damage/sulfidic-material-selection"],
893
+ "source_temperature_bin_used":Literal["lower","upper"] | None,"first_temperature_threshold_anchor_used":bool,"below_first_tan_row_used":bool}
894
+ SPECS["damage/sulfidic-velocity-factor"] = {"velocity_factor":NUMBER,"velocity_boundary_conflict_encountered":bool}
895
+ SPECS["damage/sulfidic-thinning-classification"] = {"source_thinning_type":Literal["general","local"]}
896
+ SPECS["damage/sulfidic-corrosion-assessment"] = {**SPECS["damage/sulfidic-table-rate"],**SPECS["damage/sulfidic-velocity-factor"],
897
+ "base_corrosion_rate_m_year":NUMBER | None,"source_table_id":str | None,"table_group":_SULFIDIC_GROUP | None,
898
+ "velocity_factor":NUMBER | None,"source_thinning_type":Literal["general","local"] | None,"corrosion_rate_m_year":NUMBER,
899
+ "calculation_branch":Literal["no_sulfidic_service","qualified_sulfidic_naphthenic_service"]}
900
+ SPECS["damage/sulfidic-thinning-assessment"] = {**SPECS["damage/sulfidic-corrosion-assessment"],**SPECS["damage/thinning-unclad-qualified"],"assessment_distribution":Literal["general","local"]}
901
+
902
+ SPECS["properties/pure-fluid-flash"] = {"flashed_temperature_k":NUMBER,"vapor_mass_fraction":Fraction,
903
+ "flashed_phase":Literal["twophase","liquid","supercritical_liquid","gas","supercritical_gas"],"bulk_density_kg_m3":NUMBER,
904
+ "conserved_property":Literal["Smass","Hmass"],"conserved_value_si":float,"engine_version":str,
905
+ "storage_phase":Literal["liquid","supercritical_liquid","gas","supercritical_gas","twophase"],"storage_vapor_mass_fraction":Fraction,"vapor_mass_fraction_change":float,
906
+ "storage_temperature_k":NUMBER,"storage_state_basis":Literal["pressure_temperature","pressure_quality"]}
907
+
908
+ SPECS['release/pure-liquid-flash-partition'] = {**SPECS['properties/pure-fluid-flash'],
909
+ **SPECS['release/level2-source-partition'],'rainout_mass_fraction':Fraction}
910
+
911
+ _PURE_SATURATION = {name:NUMBER for name in ('saturation_pressure_pa_abs','bubble_temperature_k','dew_temperature_k',
912
+ 'liquid_density_kg_m3','vapor_density_kg_m3','liquid_specific_heat_j_kg_k','vapor_specific_heat_j_kg_k','latent_heat_j_kg','molecular_weight_kg_kmol')}
913
+ SPECS['properties/pure-fluid-saturation-pressure'] = {**_PURE_SATURATION,'engine_version':str}
914
+ SPECS['properties/pure-fluid-saturation-temperature'] = {**_PURE_SATURATION,'engine_version':str}
915
+
916
+ SPECS['dispersion/flashed-boiling-pool-centreline'] = {**SPECS['release/pure-liquid-flash-partition'],
917
+ **SPECS['properties/pure-fluid-saturation-pressure'],**SPECS['release/boiling-pool-steady-source'],
918
+ **SPECS['dispersion/native-pool-centreline'],
919
+ **{name:NUMBER for name in ('steady_window_start_s','steady_window_duration_s','steady_evaporated_mass_kg','startup_unmodeled_pool_mass_kg')},
920
+ 'integration_scope':Literal['flashed_pure_liquid_boiling_pool_steady_window_centreline']}
921
+ SPECS['dispersion/flashed-boiling-pool-footprint'] = {**SPECS['dispersion/flashed-boiling-pool-centreline'],
922
+ **SPECS['dispersion/native-pool-footprint'],
923
+ 'integration_scope':Literal['flashed_pure_liquid_boiling_pool_steady_window_footprint']}
924
+ SPECS['dispersion/flashed-boiling-pool-flash-fire'] = {**SPECS['dispersion/flashed-boiling-pool-footprint'],
925
+ **SPECS['dispersion/native-pool-flash-fire'],
926
+ 'integration_scope':Literal['flashed_pure_liquid_boiling_pool_steady_window_flash_fire']}
927
+
928
+ SPECS['risk/area-event-contribution'] = {**{name:NUMBER for name in (
929
+ 'annual_release_frequency_per_year','annual_selected_event_frequency_per_year',
930
+ 'event_weighted_equipment_area_m2','event_weighted_personnel_area_m2',
931
+ 'equipment_area_risk_contribution_m2_per_year','personnel_area_risk_contribution_m2_per_year','area_risk_contribution_m2_per_year')},
932
+ 'conditional_joint_probability':Fraction,'contribution_scope':Literal['selected_event_weather_case']}
933
+ SPECS['risk/flashed-pool-flash-fire-contribution'] = {**SPECS['dispersion/flashed-boiling-pool-flash-fire'],
934
+ **SPECS['risk/area-event-contribution'],'generic_hole_frequency_per_year':NUMBER,'management_factor':NUMBER,'total_damage_factor':NUMBER,
935
+ 'selected_hole':Literal['small','medium','large','rupture'],
936
+ 'contribution_scope':Literal['selected_hole_weather_steady_pool_flash_fire'],
937
+ 'integration_scope':Literal['selected_hole_weather_steady_pool_flash_fire_risk_contribution']}
938
+
939
+ SPECS['damage/groundwater-tks'] = {'total_key_species_mg_l':NUMBER}
940
+ SPECS['damage/groundwater-rate-classification'] = {'corrosion_rate_m_year':NUMBER,
941
+ 'corrosivity_category':Literal['low','medium','high','very_high'],'selected_unit_basis':Literal['printed_si','printed_us_converted'],
942
+ 'category_lower_bound_m_year':NUMBER,'category_upper_bound_m_year':NUMBER | None,
943
+ 'lower_bound_relation':Literal['inclusive','exclusive'],'upper_bound_relation':Literal['inclusive','exclusive','unbounded'],
944
+ 'shared_boundary_encountered':bool}
945
+ SPECS['damage/groundwater-assessment'] = {**SPECS['damage/groundwater-tks'],**SPECS['damage/groundwater-rate-classification'],
946
+ 'rate_source':Literal['qualified_external_groundwater_rate'],'tks_to_rate_model_available':Literal[False]}
947
+ SPECS['damage/groundwater-thinning-assessment'] = {**SPECS['damage/groundwater-assessment'],
948
+ **SPECS['damage/thinning-unclad-qualified'],'assessment_distribution':Literal['general','local']}
949
+
950
+ SPECS['damage/thinning-prior-selection'] = {'prior_probabilities':list[Fraction],
951
+ 'prior_source':Literal['table4_5','qualified_custom'],'confidence':Literal['low','medium','high'] | None,
952
+ 'zero_prior_state_indices':list[int]}
953
+
954
+ SPECS['damage/thinning-rate-selection'] = {'corrosion_rate_m_year':NUMBER,'assessment_distribution':Literal['general','local'],
955
+ 'governing_rate_mechanism_ids':list[str],'governing_type_mechanism_ids':list[str],
956
+ 'rate_by_mechanism_m_year':dict[str,NUMBER],
957
+ 'selection_source_by_mechanism':dict[str,Literal['measured','calculated','estimated']],
958
+ 'fallback_ignored_by_mechanism':dict[str,bool]}
959
+ SPECS['damage/thinning-selected-mechanisms'] = {**SPECS['damage/thinning-rate-selection'],**SPECS['damage/thinning-unclad-qualified']}
960
+
961
+ SPECS['damage/thinning-assessment-period'] = {'baseline_type':Literal['furnished','measured'],
962
+ 'baseline_at':str,'assessment_at':str,'baseline_thickness_m':NUMBER,'baseline_inspection_id':str | None,
963
+ 'elapsed_days':NUMBER,'elapsed_years':NUMBER,'days_per_year':NUMBER}
964
+ SPECS['damage/thinning-inspection-history'] = {**SPECS['damage/thinning-assessment-period'],
965
+ **{'inspections_'+grade:int for grade in 'abcd'},'eligible_inspection_ids':list[str],
966
+ 'excluded_inspection_reasons':dict[str,Literal['before_baseline','after_assessment','baseline_boundary','unqualified','ineffective_e']],
967
+ 'baseline_boundary_policy':Literal['include_baseline_time','exclude_baseline_time']}
968
+ SPECS['damage/thinning-history-assessment'] = {**SPECS['damage/thinning-inspection-history'],**SPECS['damage/thinning-selected-mechanisms']}
969
+
970
+ SPECS['damage/caustic-screening'] = {'evaluate_caustic_cracking':bool,
971
+ 'screening_reason':Literal['evaluate','outside_material_scope','caustic_absent']}
972
+ SPECS['damage/caustic-figure-susceptibility'] = {'susceptibility':Literal['none','low','medium','high'],
973
+ 'decision_branch':str,'plot_evidence_used':bool,'historical_high_retained':bool}
974
+ SPECS['damage/caustic-screened-assessment'] = {**SPECS['damage/caustic-screening'],
975
+ **SPECS['damage/caustic-figure-susceptibility'],**SPECS['damage/caustic']}
976
+
977
+ SPECS['damage/amine-cracking-screening'] = {'evaluate_amine_cracking':bool,
978
+ 'screening_reason':Literal['evaluate','outside_material_scope','treating_amine_absent']}
979
+ SPECS['damage/amine-cracking-screened-assessment'] = {**SPECS['damage/amine-cracking-screening'],**SPECS['damage/amine']}
980
+
981
+ SPECS['damage/amine-figure-susceptibility'] = {'susceptibility':Literal['none','low','medium','high'],
982
+ 'decision_branch':str,'lean_exposure_selected':bool}
983
+ SPECS['damage/amine-figure-assessment'] = {**SPECS['damage/amine-cracking-screening'],
984
+ **SPECS['damage/amine-figure-susceptibility'],**SPECS['damage/amine']}
985
+
986
+ SPECS['damage/ssc-screening'] = {'evaluate_ssc':bool,
987
+ 'screening_reason':Literal['outside_material_scope','water_absent','h2s_absent','evaluate']}
988
+
989
+ SPECS['damage/ssc-qualified-susceptibility'] = {**SPECS['damage/wet-h2s-environment'],
990
+ 'unadjusted_susceptibility':Literal['none','low','medium','high'],
991
+ 'susceptibility':Literal['none','low','medium','high'],'cyanide_upgrade_applied':bool}
992
+ SPECS['damage/ssc-qualified-assessment'] = {**SPECS['damage/ssc-screening'],
993
+ **SPECS['damage/ssc-qualified-susceptibility'],**SPECS['damage/ssc']}
994
+
995
+ SPECS['damage/hic-h2s-screening'] = {'evaluate_hic_sohic_h2s':bool,
996
+ 'screening_reason':Literal['outside_material_scope','water_absent','h2s_absent','evaluate']}
997
+
998
+ SPECS['damage/hic-h2s-qualified-susceptibility'] = {**SPECS['damage/wet-h2s-environment'],
999
+ 'effective_environmental_severity':Literal['low','moderate','high'],
1000
+ **{name:Literal['none','low','medium','high'] for name in ('unadjusted_susceptibility','cyanide_adjusted_susceptibility','susceptibility')}}
1001
+ SPECS['damage/hic-h2s-qualified-assessment'] = {**SPECS['damage/hic-h2s-screening'],
1002
+ **SPECS['damage/hic-h2s-qualified-susceptibility'],**SPECS['damage/hic-sohic-h2s'],
1003
+ 'ffs_disposition':Literal['not_required','repaired','qualified_ffs_basis']}
1004
+
1005
+ SPECS['damage/hic-h2s-monitoring-selection'] = {'table_monitoring_factor':NUMBER,'monitoring_factor':NUMBER,
1006
+ 'monitoring_factor_source':Literal['table9_5','qualified_experience_replacement']}
1007
+ SPECS['damage/hic-h2s-qualified-assessment'].update(SPECS['damage/hic-h2s-monitoring-selection'])
1008
+
1009
+ SPECS['damage/acscc-screening'] = {'evaluate_acscc':bool,'material_in_scope':bool,
1010
+ 'evaluation_triggers':list[Literal['alkaline_water_ph_above_7_5','fccu_feed_sulfur_reduced','fccu_feed_nitrogen_increased']]}
1011
+
1012
+ SPECS['damage/acscc-water-susceptibility'] = {'susceptibility':Literal['none','low','medium','high'],
1013
+ 'selected_ph_band':Literal['below_7.5','7.5_to_8','8_to_9','at_least_9'],'shared_ph_boundary_encountered':bool}
1014
+
1015
+ SPECS['damage/acscc-qualified-assessment'] = {**SPECS['damage/acscc-screening'],
1016
+ **SPECS['damage/acscc-water-susceptibility'],**SPECS['damage/acscc']}
1017
+
1018
+ SPECS['damage/pascc-screening'] = {'evaluate_pascc':bool,
1019
+ 'screening_reason':Literal['outside_material_scope','sulfur_exposure_absent','evaluate']}
1020
+
1021
+ SPECS['damage/pascc-figure-susceptibility'] = {'table_or_override_susceptibility':Literal['none','low','medium','high'],
1022
+ 'susceptibility':Literal['none','low','medium','high'],'downtime_reduction_applied':bool}
1023
+ SPECS['damage/pascc-qualified-assessment'] = {**SPECS['damage/pascc-screening'],
1024
+ **SPECS['damage/pascc-figure-susceptibility'],**SPECS['damage/pascc']}
1025
+
1026
+ SPECS['damage/clscc-screening'] = {'evaluate_clscc':bool,'material_in_scope':bool,'temperature_screen_passed':bool,
1027
+ 'screening_temperature_threshold_k':NUMBER,'selected_temperature_basis':Literal['printed_si','printed_us_converted']}
1028
+
1029
+ SPECS['damage/clscc-qualified-assessment'] = {**SPECS['damage/clscc-screening'],
1030
+ 'susceptibility':Literal['none','low','medium','high'],**SPECS['damage/clscc']}
1031
+
1032
+ # Runtime validation uses the same static output models exposed by the Python API.
1033
+ from .outputs import OUTPUT_MODELS
1034
+ from .result import CalculationResult
1035
+
1036
+ CrossingOutput = OUTPUT_MODELS["planning/target-crossing"]
1037
+ AssessmentOutput = OUTPUT_MODELS["risk/assessment"]
1038
+ RESPONSE_MODELS = {identifier: CalculationResult[model] for identifier, model in OUTPUT_MODELS.items()}