aero-agent-roles 1.0.0

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 (170) hide show
  1. package/NOTICE +18 -0
  2. package/README.md +49 -0
  3. package/bin/aero-agent-roles.js +127 -0
  4. package/lib/catalog.js +97 -0
  5. package/lib/install.js +48 -0
  6. package/lib/mcp.js +199 -0
  7. package/manifest.json +516 -0
  8. package/package.json +44 -0
  9. package/roles/aerodynamics-engineer/ROLE.md +153 -0
  10. package/roles/aerodynamics-engineer/SOURCES.md +12 -0
  11. package/roles/aerodynamics-engineer/cli.py +143 -0
  12. package/roles/aerodynamics-engineer/core/aerodynamics_core.py +1218 -0
  13. package/roles/aerodynamics-engineer/templates/aero-design-report-template.md +72 -0
  14. package/roles/aerodynamics-engineer/tests/test_aerodynamics_core.py +227 -0
  15. package/roles/aerodynamics-engineer/tests/test_role_aerodynamics.py +94 -0
  16. package/roles/aircraft-design-engineer/ROLE.md +138 -0
  17. package/roles/aircraft-design-engineer/SOURCES.md +12 -0
  18. package/roles/aircraft-design-engineer/cli.py +152 -0
  19. package/roles/aircraft-design-engineer/core/aircraft_design_core.py +1278 -0
  20. package/roles/aircraft-design-engineer/templates/concept-design-template.md +99 -0
  21. package/roles/aircraft-design-engineer/tests/test_aircraft_design_core.py +269 -0
  22. package/roles/aircraft-design-engineer/tests/test_role_aircraft_design_engineer.py +106 -0
  23. package/roles/airworthiness-compliance-engineer/ROLE.md +122 -0
  24. package/roles/airworthiness-compliance-engineer/SOURCES.md +16 -0
  25. package/roles/airworthiness-compliance-engineer/cli.py +146 -0
  26. package/roles/airworthiness-compliance-engineer/core/airworthiness_core.py +894 -0
  27. package/roles/airworthiness-compliance-engineer/templates/compliance-matrix-template.md +46 -0
  28. package/roles/airworthiness-compliance-engineer/tests/test_airworthiness_core.py +224 -0
  29. package/roles/airworthiness-compliance-engineer/tests/test_role_airworthiness.py +85 -0
  30. package/roles/as9100-quality-auditor/ROLE.md +128 -0
  31. package/roles/as9100-quality-auditor/SOURCES.md +16 -0
  32. package/roles/as9100-quality-auditor/cli.py +136 -0
  33. package/roles/as9100-quality-auditor/core/as9100_core.py +857 -0
  34. package/roles/as9100-quality-auditor/templates/findings-report-template.md +119 -0
  35. package/roles/as9100-quality-auditor/tests/test_as9100_cli_profile.py +105 -0
  36. package/roles/as9100-quality-auditor/tests/test_as9100_core.py +204 -0
  37. package/roles/as9100-quality-auditor/tests/test_role_as9100.py +90 -0
  38. package/roles/data-bus-avionics-engineer/ROLE.md +146 -0
  39. package/roles/data-bus-avionics-engineer/SOURCES.md +23 -0
  40. package/roles/data-bus-avionics-engineer/cli.py +311 -0
  41. package/roles/data-bus-avionics-engineer/core/data_bus_avionics_core.py +1121 -0
  42. package/roles/data-bus-avionics-engineer/templates/bus-assessment-template.md +134 -0
  43. package/roles/data-bus-avionics-engineer/tests/test_bundle_protocol.py +137 -0
  44. package/roles/data-bus-avionics-engineer/tests/test_data_bus_avionics_core.py +261 -0
  45. package/roles/data-bus-avionics-engineer/tests/test_role_data_bus_avionics_engineer.py +121 -0
  46. package/roles/do160-environmental-engineer/ROLE.md +136 -0
  47. package/roles/do160-environmental-engineer/SOURCES.md +30 -0
  48. package/roles/do160-environmental-engineer/cli.py +147 -0
  49. package/roles/do160-environmental-engineer/core/do160_environmental_core.py +1246 -0
  50. package/roles/do160-environmental-engineer/templates/environmental-qualification-plan-template.md +114 -0
  51. package/roles/do160-environmental-engineer/tests/test_do160_environmental_core.py +312 -0
  52. package/roles/do160-environmental-engineer/tests/test_role_do160_environmental_engineer.py +281 -0
  53. package/roles/do178c-cert-engineer/ROLE.md +120 -0
  54. package/roles/do178c-cert-engineer/SOURCES.md +16 -0
  55. package/roles/do178c-cert-engineer/cli.py +129 -0
  56. package/roles/do178c-cert-engineer/core/do178c_core.py +411 -0
  57. package/roles/do178c-cert-engineer/templates/psac-template.md +74 -0
  58. package/roles/do178c-cert-engineer/tests/test_do178c_cert_engineer_core.py +91 -0
  59. package/roles/do178c-cert-engineer/tests/test_role_do178c.py +109 -0
  60. package/roles/do254-hardware-engineer/ROLE.md +127 -0
  61. package/roles/do254-hardware-engineer/SOURCES.md +19 -0
  62. package/roles/do254-hardware-engineer/cli.py +308 -0
  63. package/roles/do254-hardware-engineer/core/do254_hardware_core.py +761 -0
  64. package/roles/do254-hardware-engineer/templates/phac-template.md +87 -0
  65. package/roles/do254-hardware-engineer/tests/test_do254_bundle_profile.py +152 -0
  66. package/roles/do254-hardware-engineer/tests/test_do254_hardware_core.py +200 -0
  67. package/roles/do254-hardware-engineer/tests/test_role_do254_hardware.py +108 -0
  68. package/roles/engineering-analysis-engineer/ROLE.md +154 -0
  69. package/roles/engineering-analysis-engineer/SOURCES.md +15 -0
  70. package/roles/engineering-analysis-engineer/cli.py +151 -0
  71. package/roles/engineering-analysis-engineer/core/engineering_analysis_engineer_core.py +866 -0
  72. package/roles/engineering-analysis-engineer/templates/analysis-memo-template.md +73 -0
  73. package/roles/engineering-analysis-engineer/tests/test_engineering_analysis_engineer_core.py +367 -0
  74. package/roles/engineering-analysis-engineer/tests/test_role_engineering_analysis_engineer.py +113 -0
  75. package/roles/flight-management-engineer/ROLE.md +160 -0
  76. package/roles/flight-management-engineer/SOURCES.md +30 -0
  77. package/roles/flight-management-engineer/cli.py +258 -0
  78. package/roles/flight-management-engineer/core/flight_management_core.py +1473 -0
  79. package/roles/flight-management-engineer/templates/route-assessment-template.md +94 -0
  80. package/roles/flight-management-engineer/tests/test_flight_management_core.py +437 -0
  81. package/roles/flight-management-engineer/tests/test_role_flight_management_engineer.py +123 -0
  82. package/roles/flight-mechanics-engineer/ROLE.md +162 -0
  83. package/roles/flight-mechanics-engineer/SOURCES.md +51 -0
  84. package/roles/flight-mechanics-engineer/cli.py +149 -0
  85. package/roles/flight-mechanics-engineer/core/flight_mechanics_core.py +1507 -0
  86. package/roles/flight-mechanics-engineer/templates/perf-sc-report-template.md +82 -0
  87. package/roles/flight-mechanics-engineer/tests/test_flight_mechanics_core.py +277 -0
  88. package/roles/flight-mechanics-engineer/tests/test_role_flight_mechanics_engineer.py +141 -0
  89. package/roles/flight-test-engineer/ROLE.md +137 -0
  90. package/roles/flight-test-engineer/SOURCES.md +24 -0
  91. package/roles/flight-test-engineer/cli.py +135 -0
  92. package/roles/flight-test-engineer/core/flight_test_core.py +931 -0
  93. package/roles/flight-test-engineer/templates/flight-test-template.md +143 -0
  94. package/roles/flight-test-engineer/tests/test_flight_test_engineer_core.py +227 -0
  95. package/roles/flight-test-engineer/tests/test_role_flight_test_engineer.py +150 -0
  96. package/roles/flight-test-performance-engineer/ROLE.md +165 -0
  97. package/roles/flight-test-performance-engineer/SOURCES.md +20 -0
  98. package/roles/flight-test-performance-engineer/cli.py +319 -0
  99. package/roles/flight-test-performance-engineer/core/flight_test_performance_core.py +1398 -0
  100. package/roles/flight-test-performance-engineer/templates/performance-report-template.md +105 -0
  101. package/roles/flight-test-performance-engineer/tests/test_flight_test_performance_engineer_core.py +308 -0
  102. package/roles/flight-test-performance-engineer/tests/test_role_flight_test_performance_engineer.py +165 -0
  103. package/roles/gnc-engineer/ROLE.md +141 -0
  104. package/roles/gnc-engineer/SOURCES.md +35 -0
  105. package/roles/gnc-engineer/cli.py +141 -0
  106. package/roles/gnc-engineer/core/gnc_core.py +1074 -0
  107. package/roles/gnc-engineer/templates/gnc-report-template.md +105 -0
  108. package/roles/gnc-engineer/tests/test_gnc_engineer_core.py +238 -0
  109. package/roles/gnc-engineer/tests/test_role_gnc_engineer.py +142 -0
  110. package/roles/guidance-engineer/ROLE.md +156 -0
  111. package/roles/guidance-engineer/SOURCES.md +43 -0
  112. package/roles/guidance-engineer/cli.py +280 -0
  113. package/roles/guidance-engineer/core/guidance_core.py +820 -0
  114. package/roles/guidance-engineer/templates/guidance-report-template.md +70 -0
  115. package/roles/guidance-engineer/tests/test_guidance_engineer_core.py +269 -0
  116. package/roles/guidance-engineer/tests/test_role_guidance_engineer.py +146 -0
  117. package/roles/high-speed-aerodynamics-engineer/ROLE.md +161 -0
  118. package/roles/high-speed-aerodynamics-engineer/SOURCES.md +18 -0
  119. package/roles/high-speed-aerodynamics-engineer/cli.py +282 -0
  120. package/roles/high-speed-aerodynamics-engineer/core/high_speed_aero_core.py +1566 -0
  121. package/roles/high-speed-aerodynamics-engineer/templates/high-speed-memo-template.md +75 -0
  122. package/roles/high-speed-aerodynamics-engineer/tests/test_bundle_protocol.py +103 -0
  123. package/roles/high-speed-aerodynamics-engineer/tests/test_high_speed_aero_core.py +280 -0
  124. package/roles/high-speed-aerodynamics-engineer/tests/test_role_high_speed_aerodynamics.py +125 -0
  125. package/roles/ndt-engineer/ROLE.md +157 -0
  126. package/roles/ndt-engineer/SOURCES.md +18 -0
  127. package/roles/ndt-engineer/cli.py +316 -0
  128. package/roles/ndt-engineer/core/ndt_core.py +1590 -0
  129. package/roles/ndt-engineer/templates/ndt-plan-template.md +109 -0
  130. package/roles/ndt-engineer/tests/test_ndt_cli_bundle.py +183 -0
  131. package/roles/ndt-engineer/tests/test_ndt_core.py +437 -0
  132. package/roles/ndt-engineer/tests/test_role_ndt_engineer.py +148 -0
  133. package/roles/numerical-analysis-engineer/ROLE.md +158 -0
  134. package/roles/numerical-analysis-engineer/SOURCES.md +19 -0
  135. package/roles/numerical-analysis-engineer/cli.py +414 -0
  136. package/roles/numerical-analysis-engineer/core/numerical_analysis_core.py +1220 -0
  137. package/roles/numerical-analysis-engineer/templates/verification-memo-template.md +120 -0
  138. package/roles/numerical-analysis-engineer/tests/test_bundle_protocol.py +157 -0
  139. package/roles/numerical-analysis-engineer/tests/test_numerical_analysis_core.py +337 -0
  140. package/roles/numerical-analysis-engineer/tests/test_role_numerical_analysis_engineer.py +117 -0
  141. package/roles/propulsion-engineer/ROLE.md +163 -0
  142. package/roles/propulsion-engineer/SOURCES.md +15 -0
  143. package/roles/propulsion-engineer/cli.py +168 -0
  144. package/roles/propulsion-engineer/core/propulsion_core.py +1291 -0
  145. package/roles/propulsion-engineer/templates/propulsion-report-template.md +92 -0
  146. package/roles/propulsion-engineer/tests/test_propulsion_engineer_core.py +294 -0
  147. package/roles/propulsion-engineer/tests/test_role_propulsion_engineer.py +106 -0
  148. package/roles/space-systems-engineer/ROLE.md +161 -0
  149. package/roles/space-systems-engineer/SOURCES.md +49 -0
  150. package/roles/space-systems-engineer/cli.py +173 -0
  151. package/roles/space-systems-engineer/core/space_systems_core.py +980 -0
  152. package/roles/space-systems-engineer/templates/space-systems-template.md +88 -0
  153. package/roles/space-systems-engineer/tests/test_role_space_systems_engineer.py +117 -0
  154. package/roles/space-systems-engineer/tests/test_space_systems_engineer_core.py +247 -0
  155. package/roles/state-estimation-engineer/ROLE.md +154 -0
  156. package/roles/state-estimation-engineer/SOURCES.md +27 -0
  157. package/roles/state-estimation-engineer/cli.py +326 -0
  158. package/roles/state-estimation-engineer/core/state_estimation_core.py +958 -0
  159. package/roles/state-estimation-engineer/templates/nav-state-estimator-design-template.md +76 -0
  160. package/roles/state-estimation-engineer/tests/test_bundle_protocol.py +110 -0
  161. package/roles/state-estimation-engineer/tests/test_role_state_estimation_engineer.py +127 -0
  162. package/roles/state-estimation-engineer/tests/test_state_estimation_engineer_core.py +231 -0
  163. package/roles/structures-loads-engineer/ROLE.md +171 -0
  164. package/roles/structures-loads-engineer/SOURCES.md +44 -0
  165. package/roles/structures-loads-engineer/cli.py +219 -0
  166. package/roles/structures-loads-engineer/core/structures_loads_core.py +1112 -0
  167. package/roles/structures-loads-engineer/templates/loads-strength-report-template.md +96 -0
  168. package/roles/structures-loads-engineer/tests/test_bundle_protocol.py +101 -0
  169. package/roles/structures-loads-engineer/tests/test_role_structures_loads_engineer.py +147 -0
  170. package/roles/structures-loads-engineer/tests/test_structures_loads_core.py +261 -0
@@ -0,0 +1,171 @@
1
+ ---
2
+ type: role
3
+ name: structures-loads-engineer
4
+ title: "Structures and Loads Engineer"
5
+ status: draft
6
+ domain: structures
7
+ deliverable_type: "loads + strength/stability analysis report"
8
+ standards_bound:
9
+ - id: far-25
10
+ tier: TIER-1
11
+ reference-only: false
12
+ - id: mmpsd
13
+ tier: TIER-2
14
+ reference-only: true
15
+ skills_bound:
16
+ - structures/loads/gust-maneuver-loads
17
+ - structures/loads/landing-ground-loads
18
+ - structures/loads/random-vibration-analysis
19
+ - structures/loads/shock-response-spectrum
20
+ - structures/fem/beam-frame-analysis
21
+ - structures/fem/truss-analysis
22
+ - structures/fem/calculix-linear
23
+ - structures/fem/calculix-nonlinear
24
+ - structures/fem/buckling-analysis
25
+ - structures/fem/plate-buckling
26
+ - structures/fem/cylindrical-shell-buckling
27
+ - structures/fem/modal-analysis
28
+ - structures/fem/beam-vibration
29
+ - structures/fem/lug-joint-analysis
30
+ - structures/fem/contact-analysis
31
+ - structures/fem/pressure-bulkhead
32
+ - structures/materials/material-selection
33
+ - structures/materials/mmpsd-allowables
34
+ - structures/materials/ramberg-osgood
35
+ - structures/materials/creep-rupture
36
+ - structures/materials/fracture-toughness
37
+ - structures/fatigue/goodman-diagram
38
+ - structures/fatigue/stress-life-curve
39
+ - structures/fatigue/strain-life-fatigue
40
+ - structures/fatigue/miner-damage
41
+ - structures/fatigue/notch-sensitivity
42
+ - structures/fatigue/load-spectrum-counting
43
+ - structures/damage-tolerance/crack-growth
44
+ - structures/damage-tolerance/residual-strength
45
+ - structures/damage-tolerance/bird-strike
46
+ - structures/damage-tolerance/widespread-fatigue-damage
47
+ - structures/composites/laminate-stiffness
48
+ - structures/composites/laminate-first-ply-failure
49
+ - structures/composites/failure-criteria
50
+ - structures/composites/sandwich-panels
51
+ - structures/composites/composite-repair
52
+ - structures/thermal-structures/thermal-stress-analysis
53
+ - structures/thermal-structures/thermal-buckling
54
+ tools_allowed: [stdlib, offline-file-processing, calculix-cli]
55
+ forbidden:
56
+ - "claim certification approval"
57
+ - "declare a compliance finding"
58
+ - "reproduce proprietary standard text"
59
+ sign_off_required: true
60
+ license: Apache-2.0
61
+ compatibility: "agentskills.io ROLE.md; any SKILL.md host"
62
+ metadata:
63
+ version: 0.1.0
64
+ author: Aero Agent Roles
65
+ skills_release: "v1.3.0+"
66
+ ---
67
+
68
+ # Structures and Loads Engineer
69
+
70
+ ## Role identity
71
+
72
+ Owns structural loads and strength/stability analysis: derive design
73
+ loads (gust, maneuver, landing, ground), build the internal load path
74
+ (FEM), check strength/stability against allowables, assess fatigue and
75
+ damage tolerance, and screen composite/thermal behavior. Use when a
76
+ structure must show margin against its limit/ultimate loads. Do NOT use
77
+ for aerodynamic shape (aero role) or certification plan workflow.
78
+
79
+ ## Deliverable contract
80
+
81
+ 1. **Loads + strength report** - limit/ultimate loads, V-n envelope,
82
+ FEM stress results, margins of safety per critical component,
83
+ fatigue life, damage tolerance conclusions, composite/thermal notes.
84
+ 2. **Analysis evidence set** - the models, load cases, and allowable
85
+ sources behind every margin.
86
+
87
+ ## Workflow (stages -> bound skills)
88
+
89
+ | Stage | Loads skill | Produces |
90
+ |---|---|---|
91
+ | 1. Design loads | gust-maneuver-loads + landing-ground-loads + random-vibration-analysis + shock-response-spectrum | V-n envelope, limit loads, spectra |
92
+ | 2. Global FEM | beam-frame-analysis + truss-analysis + calculix-linear | internal loads, deflections |
93
+ | 3. Nonlinear/buckling | calculix-nonlinear + buckling-analysis + plate-buckling + cylindrical-shell-buckling | stability margins |
94
+ | 4. Detail joints | lug-joint-analysis + contact-analysis + pressure-bulkhead | joint/bulkhead margins |
95
+ | 5. Dynamics | modal-analysis + beam-vibration | natural frequencies, dynamic response |
96
+ | 6. Materials | material-selection + mmpsd-allowables + ramberg-osgood + creep-rupture + fracture-toughness | allowables (Ftu/Fty/Fcy, fracture) |
97
+ | 7. Fatigue | goodman-diagram + stress-life-curve + strain-life-fatigue + miner-damage + notch-sensitivity + load-spectrum-counting | fatigue life |
98
+ | 8. Damage tolerance | crack-growth + residual-strength + bird-strike + widespread-fatigue-damage | inspection intervals, residual strength |
99
+ | 9. Composites | laminate-stiffness + laminate-first-ply-failure + failure-criteria + sandwich-panels + composite-repair | composite margins |
100
+ | 10. Thermal | thermal-stress-analysis + thermal-buckling | thermal stresses |
101
+ | 11. Report | (all above) | the loads + strength report |
102
+
103
+ ## Evidence gates
104
+
105
+ - Stage 1 done = limit loads from the envelope + spectra with FAR
106
+ context; units and load factors stated.
107
+ - Stage 3 done = every compression-critical component has a buckling
108
+ margin; mesh/BC documented.
109
+ - Stage 7 done = fatigue life stated with the S-N/Gaertner basis + Miner
110
+ sum.
111
+ - FINAL = every margin of safety has a load, an allowable, and a source.
112
+
113
+ ## Boundary / forbidden
114
+
115
+ - NEVER claim certification approval or declare compliance findings.
116
+ - Allowables: use MMPDS values with citation or a stated test basis;
117
+ never invent allowables.
118
+ - FEM results are as-good-as-the-model; state idealizations.
119
+ - Output is a DRAFT for human stress-lead review - mark it draft; the
120
+ report is not an approval document and never claims certification
121
+ approval or a compliance finding.
122
+
123
+ ## Verification
124
+
125
+ The role runs STANDALONE: `core/structures_loads_core.py` is an
126
+ executable engine that derives the FAR 25 gust + maneuver envelope
127
+ (FAR 25.341/25.337), converts the design limit condition to ultimate
128
+ loads (FAR 25.303), resolves root internal loads, computes margins of
129
+ safety per critical component from real allowables, runs the fatigue
130
+ screening (S-N basis + Miner sum) and the first-bending-frequency
131
+ check, BUILDS the loads + strength report, and gate-checks
132
+ deliverables. No AeroSkills checkout required.
133
+
134
+ Run the role:
135
+ ```bash
136
+ python3 cli.py build --out report.md # example wing report
137
+ python3 cli.py build --out report.md --bundle # + evidence bundle
138
+ python3 cli.py build --category commuter --weight 18000 # other wing classes
139
+ python3 cli.py check --file report.md # gate-check a report
140
+ ```
141
+
142
+ Evidence protocol (docs/PROTOCOL.md): `--bundle` emits
143
+ `evidence/{model.json, gates.json, provenance.json}` next to the
144
+ deliverable — the computed model, gate verdicts, and provenance (which
145
+ core function + which bound skill leaf produced each number). When
146
+ AeroSkills is present, the CLI dispatches the bound gust-maneuver-loads
147
+ logic and cross-checks its VC discrete-gust load factor against the
148
+ core's: two independent implementations agreeing (delta 0) is recorded
149
+ in provenance.json. Any harness can consume the bundle programmatically.
150
+
151
+ Tests:
152
+ - tests/test_structures_loads_core.py (24 tests): domain rules (gust
153
+ alleviation, maneuver limits, Euler/plate/lug/fatigue anchors),
154
+ report builder, evidence gates, standalone (no skills repo).
155
+ - tests/test_bundle_protocol.py (6 tests): bundle emits 3 files, model
156
+ numbers + status, gates all_pass, dispatch cross-check agrees (when
157
+ skills present), standalone honest (cross_checked=false).
158
+ - tests/test_role_structures_loads_engineer.py: bound-skill
159
+ resolution (skips if the skills repo is absent), workflow order,
160
+ filled template present, boundaries.
161
+
162
+ Bound skills in Aero Agent Skills deepen individual stages when the
163
+ library is present (FEM runs, spectra counting, detail joints); the
164
+ core engine does not depend on them. The filled deliverable template
165
+ (templates/loads-strength-report-template.md) is the generated worked
166
+ example for the example wing - zero blanks.
167
+
168
+ ## Compliance
169
+
170
+ - far-25 TIER-1; mmpsd TIER-2 reference-only (never reproduce tables).
171
+ - SOURCES.md records standards referenced.
@@ -0,0 +1,44 @@
1
+ # SOURCES.md - Structures and Loads Engineer
2
+
3
+ | Source | Role use | Gated |
4
+ |---|---|---|
5
+ | 14 CFR Part 25 (subpart C/D) | loads and structure requirements | false |
6
+ | 14 CFR 25.341 / 25.337 / 25.303 | discrete gust load factor, alleviation factor, limit maneuvering load factor n = max(2.5, min(3.8, 2.1 + 24000/(W+10000))), 1.5 factor of safety | false |
7
+ | MMPDS | metallic allowables (licensed; never reproduced - screening values cited from bound leaf anchors with basis) | true |
8
+ | CMH-17 | composite allowables (licensed) | true |
9
+ | Bruhn, Analysis and Design of Flight Vehicle Structures | analysis methods (book); elliptic span-load / box-beam idealizations | true |
10
+ | Niu, Airframe Structural Design | airframe methods (book) | true |
11
+ | CalculiX documentation | FEM tooling | false |
12
+
13
+ Summary-not-copy per STANDARDS.md. Allowables cited with source, never
14
+ reproduced.
15
+
16
+ ## Domain-rule provenance (core/structures_loads_core.py)
17
+
18
+ Every computation in the executable core mirrors a REAL rule from the
19
+ bound AeroSkills leaves or a quotable public regulation:
20
+
21
+ - Gust envelope, K_g, mass ratio, V-n diagram, gust-critical margins:
22
+ bound leaf structures/loads/gust-maneuver-loads (gust_load_logic.py)
23
+ and FAR 25.341 / 25.337 / 25.333.
24
+ - Landing reactions, braked-roll deceleration: bound leaf
25
+ structures/loads/landing-ground-loads (level-landing statics, limit
26
+ vertical inertia factor 2.5 default).
27
+ - Euler column + yield transition (lambda_1), plate buckling (k=4 ssss
28
+ long plate; k_s shear coefficient): bound leaves
29
+ structures/fem/buckling-analysis and structures/fem/plate-buckling.
30
+ - Lug bearing / net-section / tearout margins, governing mode: bound
31
+ leaf structures/fem/lug-joint-analysis (worked example reproduced:
32
+ 7075-T6 Ftu 572 / Fsu 331 / Fbru 1050 MPa -> margins +1.800 / +1.135
33
+ / +0.926, tearout governs).
34
+ - Fatigue: Basquin S-N (bound stress-life-curve leaf), modified Goodman
35
+ mean correction (bound goodman-diagram leaf), Palmgren-Miner damage
36
+ sum (bound miner-damage leaf); 7075-T6 class fatigue constants
37
+ (sigma_f' ~ 690 MPa, b = -0.10) from the bound strain-life leaf
38
+ (representative typical, reference-only).
39
+ - First wing bending frequency: bound leaf
40
+ structures/fem/beam-vibration (cantilever root beta1*L = 1.8751).
41
+
42
+ Example wing geometry (reference item) is a self-consistent candidate
43
+ design; all margins of safety in the filled template are computed, not
44
+ stated.
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+ """cli.py - run the Structures and Loads Engineer role.
3
+
4
+ Usage:
5
+ python3 cli.py build [--out <file.md>] [--category <normal|commuter|transport>]
6
+ [--weight <lb>] [--bundle] [--no-dispatch]
7
+ # build the loads + strength report
8
+ # --bundle also emit evidence/{model,gates,provenance}.json (PROTOCOL.md)
9
+ # --no-dispatch skip dispatching bound AeroSkills logic for cross-check
10
+ python3 cli.py check --file <file.md> # gate-check an existing report
11
+
12
+ The role ENGINE (core/structures_loads_core.py) does the work standalone:
13
+ FAR 25 gust/maneuver envelope, limit/ultimate loads, root internal loads,
14
+ margins of safety per critical component, fatigue screening with the
15
+ S-N basis and Miner sum, dynamics, and the evidence gates. When
16
+ AeroSkills is present (AEROSKILLS_DEV or ~/AeroSkills), the CLI
17
+ dispatches the bound gust-maneuver-loads leaf logic and cross-checks its
18
+ gust load factor against the core's — two independent implementations
19
+ agreeing is recorded in provenance.json.
20
+ """
21
+ import argparse
22
+ import importlib.util
23
+ import json
24
+ import os
25
+ import sys
26
+
27
+ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
28
+ "core"))
29
+ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
30
+ "..", "..", "scripts"))
31
+ import structures_loads_core as core # noqa: E402
32
+ import evidence # noqa: E402
33
+
34
+ AEROSKILLS = os.environ.get("AEROSKILLS_DEV", os.path.expanduser("~/AeroSkills"))
35
+ GUST_LEAF = os.path.join(AEROSKILLS, "skills", "structures", "loads",
36
+ "gust-maneuver-loads", "scripts", "gust_load_logic.py")
37
+
38
+ ROLE_SLUG = "structures-loads-engineer"
39
+
40
+
41
+ def _load_gust_logic():
42
+ """Import the bound AeroSkills gust logic if present."""
43
+ if not os.path.exists(GUST_LEAF):
44
+ return None
45
+ spec = importlib.util.spec_from_file_location("aeroskills_gust", GUST_LEAF)
46
+ mod = importlib.util.module_from_spec(spec)
47
+ try:
48
+ spec.loader.exec_module(mod)
49
+ return mod
50
+ except Exception:
51
+ return None
52
+
53
+
54
+ def _dispatch_crosscheck(item, model):
55
+ """Run the bound skill's gust logic and compare with the core value.
56
+
57
+ Cross-check point: VC discrete-gust load factor. The vn model stores
58
+ speeds in ft/s EAS and per-region design gust velocities (FAR
59
+ 25.341: 66 fps VB/VC boundary, 50 fps VC, 25 fps VD). Both the core
60
+ and the AeroSkills leaf implement the same formula:
61
+ n = 1 + (rho0 * V_e * a * K_g * U_de) / (2 * W/S)
62
+ Returns a provenance 'skills' row (or None when dispatch unavailable).
63
+ """
64
+ gust = _load_gust_logic()
65
+ vn = model.get("vn", {})
66
+ ws = vn.get("ws")
67
+ cbar = vn.get("cbar_ft")
68
+ a = vn.get("a")
69
+ vc_fps = vn.get("vc") # ft/s EAS
70
+ u_de = vn.get("gust_velocities", {}).get("vc", 50.0)
71
+ if not (gust and ws and cbar and a and vc_fps):
72
+ return None
73
+ try:
74
+ core_kg = core.gust_alleviation_factor(ws, cbar, a)
75
+ skill_kg = gust.gust_alleviation_factor(ws, cbar, a, rho=core.RHO0)
76
+ core_n = core.gust_load_factor(vc_fps, ws, a, u_de, kg=core_kg)
77
+ skill_n = gust.gust_load_factor(vc_fps, ws, a, u_de, kg=skill_kg)
78
+ delta = abs(core_n - skill_n)
79
+ return {
80
+ "leaf": "structures/loads/gust-maneuver-loads",
81
+ "skill_md": "SKILL.md",
82
+ "logic_file": "scripts/gust_load_logic.py",
83
+ "function": "gust_load_factor",
84
+ "dispatched": True,
85
+ "cross_check_point": "VC discrete gust, U_de=%.0f fps EAS" % u_de,
86
+ "core_value": round(core_n, 6),
87
+ "skill_value": round(skill_n, 6),
88
+ "delta": round(delta, 9),
89
+ "agrees": delta <= 1e-6,
90
+ "tolerance": 1e-6,
91
+ "skills_release": "v1.3.0+",
92
+ }
93
+ except Exception as e:
94
+ return {"leaf": "structures/loads/gust-maneuver-loads",
95
+ "dispatched": True, "error": str(e), "agrees": False}
96
+
97
+
98
+ def _provenance(item, model, dispatch_row):
99
+ vn = model.get("vn", {})
100
+ return {
101
+ "role": ROLE_SLUG,
102
+ "core": {
103
+ "file": "core/structures_loads_core.py",
104
+ "functions": ["gust_load_factor", "vn_diagram",
105
+ "margin_of_safety", "cumulative_damage"],
106
+ "version": "0.1.0",
107
+ },
108
+ "skills": [dispatch_row] if dispatch_row else [],
109
+ "cross_checked": bool(dispatch_row and dispatch_row.get("dispatched")
110
+ and not dispatch_row.get("error")),
111
+ "disclaimer": "DRAFT for human review. Not an approval document.",
112
+ }
113
+
114
+
115
+ def cmd_build(args):
116
+ item = core.example_item()
117
+ if args.category:
118
+ item.category = args.category
119
+ if args.weight:
120
+ item.resize_for_weight(float(args.weight))
121
+ model = core.build_report(item)
122
+ md = core.render_report_markdown(model)
123
+
124
+ # program profile (customer tailoring): load + apply context header
125
+ profile = None
126
+ try:
127
+ profile = evidence.load_profile(args.profile)
128
+ except ValueError as e:
129
+ print(f"error: bad profile: {e}")
130
+ return 1
131
+ if profile:
132
+ model["profile"] = {
133
+ "customer": profile.get("customer"),
134
+ "program": profile.get("program"),
135
+ "basis": profile.get("basis"),
136
+ "authority": profile.get("authority"),
137
+ "der": profile.get("der"),
138
+ "document_prefix": profile.get("document_prefix"),
139
+ "revision": profile.get("revision"),
140
+ }
141
+ md = evidence.profile_header_block(profile) + md
142
+
143
+ gates = core.check_report(model)
144
+
145
+ dispatch_row = None
146
+ if not args.no_dispatch:
147
+ dispatch_row = _dispatch_crosscheck(item, model)
148
+
149
+ if args.out:
150
+ with open(args.out, "w") as f:
151
+ f.write(md if md.endswith("\n") else md + "\n")
152
+ print("built loads + strength report -> %s" % args.out)
153
+ print("design limit: %s, n_limit=%.2f, n_ult=%.2f"
154
+ % (model["loads_condition"], model["n_limit"], model["n_ult"]))
155
+ print("gates: all_pass=%s %s" % (gates["all_pass"], gates))
156
+ if args.bundle:
157
+ prov = _provenance(item, model, dispatch_row)
158
+ paths = evidence.write_bundle(
159
+ args.out, ROLE_SLUG,
160
+ "loads + strength report", model, gates, prov)
161
+ print("bundle: model=%s" % paths["model"])
162
+ print(" gates=%s" % paths["gates"])
163
+ print(" provenance=%s" % paths["provenance"])
164
+ if dispatch_row:
165
+ print("cross-check: core=%.6f skill=%.6f delta=%.9f agrees=%s"
166
+ % (dispatch_row["core_value"],
167
+ dispatch_row["skill_value"],
168
+ dispatch_row["delta"], dispatch_row["agrees"]))
169
+ else:
170
+ print("cross-check: not dispatched (no AeroSkills logic)")
171
+ else:
172
+ print(md)
173
+ return 0 if gates["all_pass"] else 1
174
+
175
+
176
+ def cmd_check(args):
177
+ if not os.path.exists(args.file):
178
+ print("file not found: %s" % args.file)
179
+ return 1
180
+ md = open(args.file).read()
181
+ gates = core.check_report_markdown(md)
182
+ for name, ok in gates.items():
183
+ if name != "all_pass":
184
+ print("%s %s" % ("PASS" if ok else "FAIL", name))
185
+ print("RESULT: %s" % ("PASS" if gates["all_pass"] else "FAIL"))
186
+ return 0 if gates["all_pass"] else 1
187
+
188
+
189
+ def main():
190
+ p = argparse.ArgumentParser(
191
+ description="Structures and Loads Engineer role")
192
+ sub = p.add_subparsers(dest="cmd", required=True)
193
+
194
+ b = sub.add_parser("build")
195
+ b.add_argument("--out", default="", help="output file (default: stdout)")
196
+ b.add_argument("--category", default="",
197
+ help="normal/commuter/transport (default: example)")
198
+ b.add_argument("--weight", default="",
199
+ help="gross weight in lb to re-size the example wing")
200
+ b.add_argument("--bundle", action="store_true",
201
+ help="emit evidence/{model,gates,provenance}.json")
202
+ b.add_argument("--no-dispatch", action="store_true",
203
+ help="skip dispatching bound AeroSkills logic")
204
+ b.add_argument("--profile", default="",
205
+ help="program profile JSON (customer tailoring, "
206
+ "docs/PROFILE-SCHEMA.md)")
207
+ b.set_defaults(fn=cmd_build)
208
+
209
+ c = sub.add_parser("check")
210
+ c.add_argument("--file", required=True,
211
+ help="loads + strength report markdown to gate-check")
212
+ c.set_defaults(fn=cmd_check)
213
+
214
+ args = p.parse_args()
215
+ sys.exit(args.fn(args))
216
+
217
+
218
+ if __name__ == "__main__":
219
+ main()