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,153 @@
1
+ ---
2
+ type: role
3
+ name: aerodynamics-engineer
4
+ title: "Aerodynamics Engineer"
5
+ status: draft
6
+ domain: aerodynamics
7
+ deliverable_type: "aerodynamic design + analysis report"
8
+ standards_bound:
9
+ - id: far-25
10
+ tier: TIER-1
11
+ reference-only: false
12
+ skills_bound:
13
+ - aerodynamics/airfoil/xfoil-analysis
14
+ - aerodynamics/airfoil/airfoil-selection
15
+ - aerodynamics/airfoil/airfoil-geometry
16
+ - aerodynamics/airfoil/airfoil-optimization
17
+ - aerodynamics/wing-design/wing-planform-design
18
+ - aerodynamics/wing-design/winglet-design
19
+ - aerodynamics/drag-polars/drag-polar
20
+ - aerodynamics/drag-polars/parasite-drag
21
+ - aerodynamics/drag-polars/lift-curve-slope
22
+ - aerodynamics/high-lift/high-lift-systems
23
+ - aerodynamics/cfd/vortex-lattice-method
24
+ - aerodynamics/cfd/panel-method
25
+ - aerodynamics/cfd/cfd-validation
26
+ - aerodynamics/cfd/cfd-convergence
27
+ - aerodynamics/cfd/cfd-mesh-generation
28
+ - aerodynamics/cfd/cfd-turbulence-modeling
29
+ - aerodynamics/high-speed/swept-wing-aerodynamics
30
+ - aerodynamics/high-speed/transonic-similarity
31
+ - aerodynamics/high-speed/supercritical-airfoil
32
+ - aerodynamics/high-speed/wave-drag-area-rule
33
+ - aerodynamics/high-speed/normal-shock
34
+ - aerodynamics/boundary-layer/boundary-layer-theory
35
+ - aerodynamics/boundary-layer/boundary-layer-transition
36
+ - aerodynamics/aeroelasticity/flutter-speed-prediction
37
+ - aerodynamics/aeroelasticity/aeroelastic-gust-response
38
+ - aerodynamics/ground-effects/ground-effect
39
+ - aerodynamics/wind-tunnel/windtunnel-data-reduction
40
+ - aerodynamics/wind-tunnel/windtunnel-wall-corrections
41
+ tools_allowed: [stdlib, offline-file-processing, xfoil-avl-su2-cli]
42
+ forbidden:
43
+ - "claim certification approval"
44
+ - "declare a compliance finding"
45
+ - "reproduce proprietary standard text"
46
+ sign_off_required: true
47
+ license: Apache-2.0
48
+ compatibility: "agentskills.io ROLE.md; any SKILL.md host"
49
+ metadata:
50
+ version: 0.1.0
51
+ author: Aero Agent Roles
52
+ skills_release: "v1.3.0+"
53
+ ---
54
+
55
+ # Aerodynamics Engineer
56
+
57
+ ## Role identity
58
+
59
+ Owns the aerodynamic design and analysis workflow for an aircraft
60
+ configuration: airfoil selection, wing planform design, drag buildup,
61
+ high-lift integration, CFD validation, transonic behavior, and the
62
+ aeroelastic checks that gate the configuration. Use when a design must
63
+ demonstrate its aerodynamic characteristics with numbers (CL/CD, polars,
64
+ load distributions, margins). Do NOT use for structural sizing (see
65
+ structures role), control law design (see GNC role), or engine work.
66
+
67
+ ## Deliverable contract
68
+
69
+ 1. **Aerodynamic design report** - configuration summary: chosen airfoil
70
+ with rationale, wing planform (area, aspect, sweep, taper), high-lift
71
+ system, computed drag polar and lift curve, transonic limits.
72
+ 2. **Analysis evidence set** - XFOIL/AVL/panel outputs, CFD convergence
73
+ study, validation case vs known data (NACA 0012, ONERA M6), boundary
74
+ layer / transition assessment, aeroelastic screening (flutter speed
75
+ vs Vd, gust response).
76
+ 3. **Margin summary** - key margins (flutter margin, buffet margin,
77
+ CL_max margin, wave drag onset) with the source of each number.
78
+
79
+ ## Workflow (stages -> bound skills)
80
+
81
+ | Stage | Loads skill | Produces |
82
+ |---|---|---|
83
+ | 1. Airfoil analysis | xfoil-analysis + airfoil-geometry + airfoil-selection | candidate airfoil polars (cl/cd/cm), selected airfoil with rationale |
84
+ | 2. Airfoil optimization | airfoil-optimization | optimized section if geometry change is needed |
85
+ | 3. Wing planform | wing-planform-design | planform: area, AR, sweep, taper; CL distribution |
86
+ | 4. High-lift | high-lift-systems | high-lift config + CL_max estimate |
87
+ | 5. Drag buildup | drag-polar + parasite-drag + lift-curve-slope | full drag polar, Cd0 breakdown |
88
+ | 6. Winglet / 3D | winglet-design + vortex-lattice-method + panel-method | induced drag, span loading, 3D corrections |
89
+ | 7. CFD validation | cfd-validation + cfd-convergence + cfd-mesh-generation + cfd-turbulence-modeling | validated CFD evidence for the critical case |
90
+ | 8. Transonic | swept-wing-aerodynamics + transonic-similarity + supercritical-airfoil + wave-drag-area-rule + normal-shock | drag rise, wave drag, shock location, Mcrit/Mdd |
91
+ | 9. Boundary layer | boundary-layer-theory + boundary-layer-transition | transition/turbulence assessment |
92
+ | 10. Aeroelastic screen | flutter-speed-prediction + aeroelastic-gust-response | flutter margin vs Vd, gust load factor |
93
+ | 11. Ground/wind tunnel | ground-effect + windtunnel-data-reduction + windtunnel-wall-corrections | ground-effect delta, corrected test data |
94
+ | 12. Report | (all above) | the aerodynamic design report |
95
+
96
+ ## Evidence gates
97
+
98
+ - Stage 1 done = polars exist for the operating Re range, CL_max and
99
+ drag divergence identified.
100
+ - Stage 5 done = Cd0 has a breakdown (each term attributed to a
101
+ component), polar spans the flight envelope.
102
+ - Stage 7 done = CFD case has a mesh-convergence study + a validation
103
+ comparison against measured/known data.
104
+ - Stage 10 done = flutter speed computed vs Vd with margin stated.
105
+ - FINAL = every number in the margin summary traces to a stage output.
106
+
107
+ ## Boundary / forbidden
108
+
109
+ - NEVER claim certification approval or a compliance finding.
110
+ - NEVER reproduce proprietary text (data references are summary + cite).
111
+ - Aeroelastic results are SCREENING inputs for the loads/structures
112
+ role - not the final flutter clearance.
113
+
114
+ ## Verification
115
+
116
+ The role runs STANDALONE: `core/aerodynamics_core.py` is an executable
117
+ engine that computes the aerodynamic design numbers with the real domain
118
+ formulas of the bound AeroSkills leaves (parasite-drag buildup, parabolic
119
+ drag polar, lifting-line/sweep/compressibility lift-curve slope,
120
+ high-lift CL_max and stall speed, Korn drag-divergence Mach, flutter and
121
+ divergence margins, discrete-gust screening, CFD validation metrics),
122
+ BUILDS the aerodynamic design report, and gate-checks deliverables. No
123
+ AeroSkills checkout required.
124
+
125
+ Run the role:
126
+ ```bash
127
+ python3 cli.py build --out report.md # example transport (M 0.78)
128
+ python3 cli.py build --mach 0.80 --altitude 10668 # condition override
129
+ python3 cli.py build --ws 5500 # cruise W/S override
130
+ python3 cli.py check --file report.md # gate-check a report
131
+ ```
132
+
133
+ Tests:
134
+ - tests/test_aerodynamics_core.py (12 tests): formula correctness vs
135
+ known leaf values (Reynolds, skin friction, form factors, polar, lift
136
+ slope, flutter/divergence margins, high lift, Korn rule, Richardson),
137
+ ISA atmosphere, report builder + gates + markdown completeness +
138
+ STANDALONE (no skills repo)
139
+ - tests/test_role_aerodynamics.py: bound-skill resolution (skips if the
140
+ skills repo is absent) + workflow + template + boundaries
141
+
142
+ Templates: templates/aero-design-report-template.md is the FILLED
143
+ generated report for the reference transport (zero blank fields) -
144
+ exactly what `cli.py build` produces.
145
+
146
+ Bound skills in Aero Agent Skills deepen individual stages when the
147
+ library is present; the core engine does not depend on them.
148
+
149
+ ## Compliance
150
+
151
+ - far-25 TIER-1 for the Vd/envelope context; data references
152
+ summary-not-copy per STANDARDS.md.
153
+ - SOURCES.md records standards referenced.
@@ -0,0 +1,12 @@
1
+ # SOURCES.md - Aerodynamics Engineer
2
+
3
+ | Source | Role use | Gated |
4
+ |---|---|---|
5
+ | 14 CFR Part 25 | Vd/envelope context (subpart C structure) | false |
6
+ | ESDU data items | airfoil/drag data (licensed) | true |
7
+ | Hoerner, Fluid-Dynamic Drag | drag buildup reference (book) | true |
8
+ | UIUC Airfoil Database | airfoil polar data source | false |
9
+ | NASA validation cases | CFD validation targets (NACA 0012, ONERA M6) | false |
10
+
11
+ Summary-not-copy per STANDARDS.md. Data references cite sources, never
12
+ reproduce them.
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env python3
2
+ """cli.py - run the Aerodynamics Engineer role.
3
+
4
+ Usage:
5
+ python3 cli.py build [--out file.md] [--mach M] [--altitude m] [--ws N/m2]
6
+ [--bundle]
7
+ # build the aerodynamic design report
8
+ # --bundle also emit evidence/{model,gates,provenance}.json (PROTOCOL.md)
9
+ python3 cli.py check --file file.md
10
+
11
+ `build` computes the aerodynamic design report for the reference aircraft
12
+ (example_item) with the role ENGINE (core/aerodynamics_core.py), applying
13
+ any condition overrides:
14
+ --mach <x> cruise Mach number (default 0.78)
15
+ --altitude <m> cruise altitude in metres (default 10668)
16
+ --ws <N/m2> cruise wing loading W/S override; the cruise weight
17
+ becomes ws * S_ref (geometry stays fixed)
18
+ `check` gate-checks an existing report markdown document.
19
+ """
20
+ import argparse
21
+ import os
22
+ import sys
23
+
24
+ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "core"))
25
+ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
26
+ "..", "..", "scripts"))
27
+ import aerodynamics_core as core # noqa: E402
28
+ import evidence # noqa: E402
29
+
30
+ ROLE_SLUG = "aerodynamics-engineer"
31
+
32
+
33
+ def cmd_build(args):
34
+ item = core.example_item()
35
+ if args.mach is not None:
36
+ item.cruise_mach = args.mach
37
+ if args.altitude is not None:
38
+ item.cruise_altitude_m = args.altitude
39
+ if args.ws is not None:
40
+ if args.ws <= 0:
41
+ print("error: --ws must be > 0")
42
+ return 1
43
+ item.w_cruise = args.ws * item.s_ref
44
+ model = core.build_report(item)
45
+ md = core.render_report_markdown(model)
46
+
47
+ # program profile (customer tailoring): load + apply context header
48
+ profile = None
49
+ try:
50
+ profile = evidence.load_profile(args.profile)
51
+ except ValueError as e:
52
+ print("error: bad profile: %s" % e)
53
+ return 1
54
+ if profile:
55
+ model["profile"] = {
56
+ "customer": profile.get("customer"),
57
+ "program": profile.get("program"),
58
+ "basis": profile.get("basis"),
59
+ "authority": profile.get("authority"),
60
+ "der": profile.get("der"),
61
+ "document_prefix": profile.get("document_prefix"),
62
+ "revision": profile.get("revision"),
63
+ }
64
+ md = evidence.profile_header_block(profile) + md
65
+
66
+ gates = core.check_report(model)
67
+ if args.out:
68
+ with open(args.out, "w") as f:
69
+ f.write(md)
70
+ print("built aerodynamic design report for %s -> %s"
71
+ % (model["aircraft"], args.out))
72
+ if profile:
73
+ print("profile: %s / %s" % (profile.get("customer"),
74
+ profile.get("program")))
75
+ print("CL_cruise=%.3f CD0=%.5f L/D=%.2f M_DD=%.3f "
76
+ "flutter_margin=%.2f"
77
+ % (model["cl_cruise"], model["cd0"], model["ld_cruise"],
78
+ model["m_dd"], model["flutter_margin"]))
79
+ print("gates: all_pass=%s %s" % (gates["all_pass"], gates))
80
+ if args.bundle:
81
+ prov = {
82
+ "role": ROLE_SLUG,
83
+ "core": {"file": "core/aerodynamics_core.py",
84
+ "version": "0.1.0"},
85
+ "skills": [],
86
+ "cross_checked": False,
87
+ "disclaimer": "DRAFT for human review. Not an approval document.",
88
+ }
89
+ paths = evidence.write_bundle(
90
+ args.out, ROLE_SLUG,
91
+ "aerodynamic design report", model, gates, prov)
92
+ print("bundle: model=%s" % paths["model"])
93
+ print(" gates=%s" % paths["gates"])
94
+ print(" provenance=%s" % paths["provenance"])
95
+ else:
96
+ print(md)
97
+ return 0 if gates["all_pass"] else 1
98
+
99
+
100
+ def cmd_check(args):
101
+ if not os.path.exists(args.file):
102
+ print("file not found: %s" % args.file)
103
+ return 1
104
+ md = open(args.file).read()
105
+ gates = core.check_report_markdown(md)
106
+ for name, ok in sorted(gates.items()):
107
+ if name != "all_pass":
108
+ print("%s %s" % ("PASS" if ok else "FAIL", name))
109
+ print("RESULT: %s" % ("PASS" if gates["all_pass"] else "FAIL"))
110
+ return 0 if gates["all_pass"] else 1
111
+
112
+
113
+ def main():
114
+ p = argparse.ArgumentParser(description="Aerodynamics Engineer role")
115
+ sub = p.add_subparsers(dest="cmd", required=True)
116
+
117
+ b = sub.add_parser("build")
118
+ b.add_argument("--out", default="", help="output file (default: stdout)")
119
+ b.add_argument("--mach", type=float, default=None,
120
+ help="cruise Mach override (default 0.78)")
121
+ b.add_argument("--altitude", type=float, default=None,
122
+ help="cruise altitude override in metres (default 10668)")
123
+ b.add_argument("--ws", type=float, default=None,
124
+ help="cruise wing loading W/S override in N/m2 "
125
+ "(cruise weight = ws * S_ref)")
126
+ b.add_argument("--bundle", action="store_true",
127
+ help="emit evidence/{model,gates,provenance}.json")
128
+ b.add_argument("--profile", default="",
129
+ help="program profile JSON (customer tailoring, "
130
+ "docs/PROFILE-SCHEMA.md)")
131
+ b.set_defaults(fn=cmd_build)
132
+
133
+ c = sub.add_parser("check")
134
+ c.add_argument("--file", required=True,
135
+ help="aerodynamic design report markdown to gate-check")
136
+ c.set_defaults(fn=cmd_check)
137
+
138
+ args = p.parse_args()
139
+ sys.exit(args.fn(args))
140
+
141
+
142
+ if __name__ == "__main__":
143
+ main()