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.
- package/NOTICE +18 -0
- package/README.md +49 -0
- package/bin/aero-agent-roles.js +127 -0
- package/lib/catalog.js +97 -0
- package/lib/install.js +48 -0
- package/lib/mcp.js +199 -0
- package/manifest.json +516 -0
- package/package.json +44 -0
- package/roles/aerodynamics-engineer/ROLE.md +153 -0
- package/roles/aerodynamics-engineer/SOURCES.md +12 -0
- package/roles/aerodynamics-engineer/cli.py +143 -0
- package/roles/aerodynamics-engineer/core/aerodynamics_core.py +1218 -0
- package/roles/aerodynamics-engineer/templates/aero-design-report-template.md +72 -0
- package/roles/aerodynamics-engineer/tests/test_aerodynamics_core.py +227 -0
- package/roles/aerodynamics-engineer/tests/test_role_aerodynamics.py +94 -0
- package/roles/aircraft-design-engineer/ROLE.md +138 -0
- package/roles/aircraft-design-engineer/SOURCES.md +12 -0
- package/roles/aircraft-design-engineer/cli.py +152 -0
- package/roles/aircraft-design-engineer/core/aircraft_design_core.py +1278 -0
- package/roles/aircraft-design-engineer/templates/concept-design-template.md +99 -0
- package/roles/aircraft-design-engineer/tests/test_aircraft_design_core.py +269 -0
- package/roles/aircraft-design-engineer/tests/test_role_aircraft_design_engineer.py +106 -0
- package/roles/airworthiness-compliance-engineer/ROLE.md +122 -0
- package/roles/airworthiness-compliance-engineer/SOURCES.md +16 -0
- package/roles/airworthiness-compliance-engineer/cli.py +146 -0
- package/roles/airworthiness-compliance-engineer/core/airworthiness_core.py +894 -0
- package/roles/airworthiness-compliance-engineer/templates/compliance-matrix-template.md +46 -0
- package/roles/airworthiness-compliance-engineer/tests/test_airworthiness_core.py +224 -0
- package/roles/airworthiness-compliance-engineer/tests/test_role_airworthiness.py +85 -0
- package/roles/as9100-quality-auditor/ROLE.md +128 -0
- package/roles/as9100-quality-auditor/SOURCES.md +16 -0
- package/roles/as9100-quality-auditor/cli.py +136 -0
- package/roles/as9100-quality-auditor/core/as9100_core.py +857 -0
- package/roles/as9100-quality-auditor/templates/findings-report-template.md +119 -0
- package/roles/as9100-quality-auditor/tests/test_as9100_cli_profile.py +105 -0
- package/roles/as9100-quality-auditor/tests/test_as9100_core.py +204 -0
- package/roles/as9100-quality-auditor/tests/test_role_as9100.py +90 -0
- package/roles/data-bus-avionics-engineer/ROLE.md +146 -0
- package/roles/data-bus-avionics-engineer/SOURCES.md +23 -0
- package/roles/data-bus-avionics-engineer/cli.py +311 -0
- package/roles/data-bus-avionics-engineer/core/data_bus_avionics_core.py +1121 -0
- package/roles/data-bus-avionics-engineer/templates/bus-assessment-template.md +134 -0
- package/roles/data-bus-avionics-engineer/tests/test_bundle_protocol.py +137 -0
- package/roles/data-bus-avionics-engineer/tests/test_data_bus_avionics_core.py +261 -0
- package/roles/data-bus-avionics-engineer/tests/test_role_data_bus_avionics_engineer.py +121 -0
- package/roles/do160-environmental-engineer/ROLE.md +136 -0
- package/roles/do160-environmental-engineer/SOURCES.md +30 -0
- package/roles/do160-environmental-engineer/cli.py +147 -0
- package/roles/do160-environmental-engineer/core/do160_environmental_core.py +1246 -0
- package/roles/do160-environmental-engineer/templates/environmental-qualification-plan-template.md +114 -0
- package/roles/do160-environmental-engineer/tests/test_do160_environmental_core.py +312 -0
- package/roles/do160-environmental-engineer/tests/test_role_do160_environmental_engineer.py +281 -0
- package/roles/do178c-cert-engineer/ROLE.md +120 -0
- package/roles/do178c-cert-engineer/SOURCES.md +16 -0
- package/roles/do178c-cert-engineer/cli.py +129 -0
- package/roles/do178c-cert-engineer/core/do178c_core.py +411 -0
- package/roles/do178c-cert-engineer/templates/psac-template.md +74 -0
- package/roles/do178c-cert-engineer/tests/test_do178c_cert_engineer_core.py +91 -0
- package/roles/do178c-cert-engineer/tests/test_role_do178c.py +109 -0
- package/roles/do254-hardware-engineer/ROLE.md +127 -0
- package/roles/do254-hardware-engineer/SOURCES.md +19 -0
- package/roles/do254-hardware-engineer/cli.py +308 -0
- package/roles/do254-hardware-engineer/core/do254_hardware_core.py +761 -0
- package/roles/do254-hardware-engineer/templates/phac-template.md +87 -0
- package/roles/do254-hardware-engineer/tests/test_do254_bundle_profile.py +152 -0
- package/roles/do254-hardware-engineer/tests/test_do254_hardware_core.py +200 -0
- package/roles/do254-hardware-engineer/tests/test_role_do254_hardware.py +108 -0
- package/roles/engineering-analysis-engineer/ROLE.md +154 -0
- package/roles/engineering-analysis-engineer/SOURCES.md +15 -0
- package/roles/engineering-analysis-engineer/cli.py +151 -0
- package/roles/engineering-analysis-engineer/core/engineering_analysis_engineer_core.py +866 -0
- package/roles/engineering-analysis-engineer/templates/analysis-memo-template.md +73 -0
- package/roles/engineering-analysis-engineer/tests/test_engineering_analysis_engineer_core.py +367 -0
- package/roles/engineering-analysis-engineer/tests/test_role_engineering_analysis_engineer.py +113 -0
- package/roles/flight-management-engineer/ROLE.md +160 -0
- package/roles/flight-management-engineer/SOURCES.md +30 -0
- package/roles/flight-management-engineer/cli.py +258 -0
- package/roles/flight-management-engineer/core/flight_management_core.py +1473 -0
- package/roles/flight-management-engineer/templates/route-assessment-template.md +94 -0
- package/roles/flight-management-engineer/tests/test_flight_management_core.py +437 -0
- package/roles/flight-management-engineer/tests/test_role_flight_management_engineer.py +123 -0
- package/roles/flight-mechanics-engineer/ROLE.md +162 -0
- package/roles/flight-mechanics-engineer/SOURCES.md +51 -0
- package/roles/flight-mechanics-engineer/cli.py +149 -0
- package/roles/flight-mechanics-engineer/core/flight_mechanics_core.py +1507 -0
- package/roles/flight-mechanics-engineer/templates/perf-sc-report-template.md +82 -0
- package/roles/flight-mechanics-engineer/tests/test_flight_mechanics_core.py +277 -0
- package/roles/flight-mechanics-engineer/tests/test_role_flight_mechanics_engineer.py +141 -0
- package/roles/flight-test-engineer/ROLE.md +137 -0
- package/roles/flight-test-engineer/SOURCES.md +24 -0
- package/roles/flight-test-engineer/cli.py +135 -0
- package/roles/flight-test-engineer/core/flight_test_core.py +931 -0
- package/roles/flight-test-engineer/templates/flight-test-template.md +143 -0
- package/roles/flight-test-engineer/tests/test_flight_test_engineer_core.py +227 -0
- package/roles/flight-test-engineer/tests/test_role_flight_test_engineer.py +150 -0
- package/roles/flight-test-performance-engineer/ROLE.md +165 -0
- package/roles/flight-test-performance-engineer/SOURCES.md +20 -0
- package/roles/flight-test-performance-engineer/cli.py +319 -0
- package/roles/flight-test-performance-engineer/core/flight_test_performance_core.py +1398 -0
- package/roles/flight-test-performance-engineer/templates/performance-report-template.md +105 -0
- package/roles/flight-test-performance-engineer/tests/test_flight_test_performance_engineer_core.py +308 -0
- package/roles/flight-test-performance-engineer/tests/test_role_flight_test_performance_engineer.py +165 -0
- package/roles/gnc-engineer/ROLE.md +141 -0
- package/roles/gnc-engineer/SOURCES.md +35 -0
- package/roles/gnc-engineer/cli.py +141 -0
- package/roles/gnc-engineer/core/gnc_core.py +1074 -0
- package/roles/gnc-engineer/templates/gnc-report-template.md +105 -0
- package/roles/gnc-engineer/tests/test_gnc_engineer_core.py +238 -0
- package/roles/gnc-engineer/tests/test_role_gnc_engineer.py +142 -0
- package/roles/guidance-engineer/ROLE.md +156 -0
- package/roles/guidance-engineer/SOURCES.md +43 -0
- package/roles/guidance-engineer/cli.py +280 -0
- package/roles/guidance-engineer/core/guidance_core.py +820 -0
- package/roles/guidance-engineer/templates/guidance-report-template.md +70 -0
- package/roles/guidance-engineer/tests/test_guidance_engineer_core.py +269 -0
- package/roles/guidance-engineer/tests/test_role_guidance_engineer.py +146 -0
- package/roles/high-speed-aerodynamics-engineer/ROLE.md +161 -0
- package/roles/high-speed-aerodynamics-engineer/SOURCES.md +18 -0
- package/roles/high-speed-aerodynamics-engineer/cli.py +282 -0
- package/roles/high-speed-aerodynamics-engineer/core/high_speed_aero_core.py +1566 -0
- package/roles/high-speed-aerodynamics-engineer/templates/high-speed-memo-template.md +75 -0
- package/roles/high-speed-aerodynamics-engineer/tests/test_bundle_protocol.py +103 -0
- package/roles/high-speed-aerodynamics-engineer/tests/test_high_speed_aero_core.py +280 -0
- package/roles/high-speed-aerodynamics-engineer/tests/test_role_high_speed_aerodynamics.py +125 -0
- package/roles/ndt-engineer/ROLE.md +157 -0
- package/roles/ndt-engineer/SOURCES.md +18 -0
- package/roles/ndt-engineer/cli.py +316 -0
- package/roles/ndt-engineer/core/ndt_core.py +1590 -0
- package/roles/ndt-engineer/templates/ndt-plan-template.md +109 -0
- package/roles/ndt-engineer/tests/test_ndt_cli_bundle.py +183 -0
- package/roles/ndt-engineer/tests/test_ndt_core.py +437 -0
- package/roles/ndt-engineer/tests/test_role_ndt_engineer.py +148 -0
- package/roles/numerical-analysis-engineer/ROLE.md +158 -0
- package/roles/numerical-analysis-engineer/SOURCES.md +19 -0
- package/roles/numerical-analysis-engineer/cli.py +414 -0
- package/roles/numerical-analysis-engineer/core/numerical_analysis_core.py +1220 -0
- package/roles/numerical-analysis-engineer/templates/verification-memo-template.md +120 -0
- package/roles/numerical-analysis-engineer/tests/test_bundle_protocol.py +157 -0
- package/roles/numerical-analysis-engineer/tests/test_numerical_analysis_core.py +337 -0
- package/roles/numerical-analysis-engineer/tests/test_role_numerical_analysis_engineer.py +117 -0
- package/roles/propulsion-engineer/ROLE.md +163 -0
- package/roles/propulsion-engineer/SOURCES.md +15 -0
- package/roles/propulsion-engineer/cli.py +168 -0
- package/roles/propulsion-engineer/core/propulsion_core.py +1291 -0
- package/roles/propulsion-engineer/templates/propulsion-report-template.md +92 -0
- package/roles/propulsion-engineer/tests/test_propulsion_engineer_core.py +294 -0
- package/roles/propulsion-engineer/tests/test_role_propulsion_engineer.py +106 -0
- package/roles/space-systems-engineer/ROLE.md +161 -0
- package/roles/space-systems-engineer/SOURCES.md +49 -0
- package/roles/space-systems-engineer/cli.py +173 -0
- package/roles/space-systems-engineer/core/space_systems_core.py +980 -0
- package/roles/space-systems-engineer/templates/space-systems-template.md +88 -0
- package/roles/space-systems-engineer/tests/test_role_space_systems_engineer.py +117 -0
- package/roles/space-systems-engineer/tests/test_space_systems_engineer_core.py +247 -0
- package/roles/state-estimation-engineer/ROLE.md +154 -0
- package/roles/state-estimation-engineer/SOURCES.md +27 -0
- package/roles/state-estimation-engineer/cli.py +326 -0
- package/roles/state-estimation-engineer/core/state_estimation_core.py +958 -0
- package/roles/state-estimation-engineer/templates/nav-state-estimator-design-template.md +76 -0
- package/roles/state-estimation-engineer/tests/test_bundle_protocol.py +110 -0
- package/roles/state-estimation-engineer/tests/test_role_state_estimation_engineer.py +127 -0
- package/roles/state-estimation-engineer/tests/test_state_estimation_engineer_core.py +231 -0
- package/roles/structures-loads-engineer/ROLE.md +171 -0
- package/roles/structures-loads-engineer/SOURCES.md +44 -0
- package/roles/structures-loads-engineer/cli.py +219 -0
- package/roles/structures-loads-engineer/core/structures_loads_core.py +1112 -0
- package/roles/structures-loads-engineer/templates/loads-strength-report-template.md +96 -0
- package/roles/structures-loads-engineer/tests/test_bundle_protocol.py +101 -0
- package/roles/structures-loads-engineer/tests/test_role_structures_loads_engineer.py +147 -0
- 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()
|