aero-agent-roles 1.1.0 → 1.2.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 (104) hide show
  1. package/lib/mcp.js +130 -6
  2. package/manifest.json +248 -8
  3. package/package.json +4 -2
  4. package/roles/adcs-engineer/ROLE.md +156 -0
  5. package/roles/adcs-engineer/SOURCES.md +22 -0
  6. package/roles/adcs-engineer/cli.py +344 -0
  7. package/roles/adcs-engineer/core/adcs_core.py +1390 -0
  8. package/roles/adcs-engineer/templates/adcs-subsystem-report-template.md +114 -0
  9. package/roles/adcs-engineer/tests/test_adcs_engineer_core.py +314 -0
  10. package/roles/adcs-engineer/tests/test_role_adcs.py +187 -0
  11. package/roles/aircraft-performance-engineer/ROLE.md +187 -0
  12. package/roles/aircraft-performance-engineer/SOURCES.md +41 -0
  13. package/roles/aircraft-performance-engineer/cli.py +350 -0
  14. package/roles/aircraft-performance-engineer/core/aircraft_performance_core.py +2327 -0
  15. package/roles/aircraft-performance-engineer/templates/performance-analysis-report-template.md +190 -0
  16. package/roles/aircraft-performance-engineer/tests/test_aircraft_performance_bundle.py +184 -0
  17. package/roles/aircraft-performance-engineer/tests/test_aircraft_performance_core.py +573 -0
  18. package/roles/aircraft-performance-engineer/tests/test_role_aircraft_performance.py +143 -0
  19. package/roles/aircraft-systems-sizing-engineer/ROLE.md +171 -0
  20. package/roles/aircraft-systems-sizing-engineer/SOURCES.md +17 -0
  21. package/roles/aircraft-systems-sizing-engineer/cli.py +391 -0
  22. package/roles/aircraft-systems-sizing-engineer/core/aircraft_systems_sizing_core.py +1669 -0
  23. package/roles/aircraft-systems-sizing-engineer/templates/systems-sizing-report-template.md +109 -0
  24. package/roles/aircraft-systems-sizing-engineer/tests/test_aircraft_systems_sizing_core.py +181 -0
  25. package/roles/aircraft-systems-sizing-engineer/tests/test_bundle_protocol.py +116 -0
  26. package/roles/aircraft-systems-sizing-engineer/tests/test_role_aircraft_systems_sizing_engineer.py +140 -0
  27. package/roles/autopilot-control-engineer/ROLE.md +173 -0
  28. package/roles/autopilot-control-engineer/SOURCES.md +38 -0
  29. package/roles/autopilot-control-engineer/cli.py +147 -0
  30. package/roles/autopilot-control-engineer/core/autopilot_control_engineer_core.py +1450 -0
  31. package/roles/autopilot-control-engineer/templates/autopilot-control-law-package-template.md +139 -0
  32. package/roles/autopilot-control-engineer/tests/test_autopilot_control_engineer_core.py +302 -0
  33. package/roles/autopilot-control-engineer/tests/test_role_autopilot_control_engineer.py +189 -0
  34. package/roles/boundary-layer-engineer/ROLE.md +180 -0
  35. package/roles/boundary-layer-engineer/SOURCES.md +31 -0
  36. package/roles/boundary-layer-engineer/cli.py +261 -0
  37. package/roles/boundary-layer-engineer/core/boundary_layer_engineer_core.py +1412 -0
  38. package/roles/boundary-layer-engineer/templates/boundary-layer-analysis-report-template.md +99 -0
  39. package/roles/boundary-layer-engineer/tests/test_boundary_layer_engineer_core.py +208 -0
  40. package/roles/boundary-layer-engineer/tests/test_role_boundary_layer_engineer.py +139 -0
  41. package/roles/composites-structures-engineer/ROLE.md +155 -0
  42. package/roles/composites-structures-engineer/SOURCES.md +29 -0
  43. package/roles/composites-structures-engineer/cli.py +348 -0
  44. package/roles/composites-structures-engineer/core/composites_structures_core.py +1024 -0
  45. package/roles/composites-structures-engineer/templates/composite-analysis-report-template.md +88 -0
  46. package/roles/composites-structures-engineer/tests/test_composites_structures_core.py +269 -0
  47. package/roles/composites-structures-engineer/tests/test_role_composites_structures_engineer.py +169 -0
  48. package/roles/do178c-cert-engineer/ROLE.md +6 -0
  49. package/roles/fem-analysis-engineer/ROLE.md +150 -0
  50. package/roles/fem-analysis-engineer/SOURCES.md +24 -0
  51. package/roles/fem-analysis-engineer/cli.py +257 -0
  52. package/roles/fem-analysis-engineer/core/fem_analysis_core.py +1659 -0
  53. package/roles/fem-analysis-engineer/templates/fem-report-template.md +114 -0
  54. package/roles/fem-analysis-engineer/tests/test_fem_analysis_core.py +236 -0
  55. package/roles/fem-analysis-engineer/tests/test_role_fem_analysis.py +129 -0
  56. package/roles/flight-software-engineer/ROLE.md +158 -0
  57. package/roles/flight-software-engineer/SOURCES.md +30 -0
  58. package/roles/flight-software-engineer/cli.py +502 -0
  59. package/roles/flight-software-engineer/core/flight_software_core.py +1841 -0
  60. package/roles/flight-software-engineer/templates/flight-sw-plan-template.md +149 -0
  61. package/roles/flight-software-engineer/tests/test_flight_software_bundle.py +160 -0
  62. package/roles/flight-software-engineer/tests/test_flight_software_core.py +376 -0
  63. package/roles/flight-software-engineer/tests/test_role_flight_software.py +153 -0
  64. package/roles/flight-test-planning-engineer/ROLE.md +177 -0
  65. package/roles/flight-test-planning-engineer/SOURCES.md +37 -0
  66. package/roles/flight-test-planning-engineer/cli.py +349 -0
  67. package/roles/flight-test-planning-engineer/core/flight_test_planning_core.py +2294 -0
  68. package/roles/flight-test-planning-engineer/templates/flight-test-plan-template.md +296 -0
  69. package/roles/flight-test-planning-engineer/tests/test_flight_test_planning_bundle.py +174 -0
  70. package/roles/flight-test-planning-engineer/tests/test_flight_test_planning_core.py +437 -0
  71. package/roles/flight-test-planning-engineer/tests/test_role_flight_test_planning.py +178 -0
  72. package/roles/navigation-engineer/ROLE.md +175 -0
  73. package/roles/navigation-engineer/SOURCES.md +35 -0
  74. package/roles/navigation-engineer/cli.py +142 -0
  75. package/roles/navigation-engineer/core/navigation_engineer_core.py +1386 -0
  76. package/roles/navigation-engineer/templates/navigation-analysis-report-template.md +94 -0
  77. package/roles/navigation-engineer/tests/test_navigation_engineer_core.py +313 -0
  78. package/roles/navigation-engineer/tests/test_role_navigation_engineer.py +153 -0
  79. package/roles/numerical-analysis-engineer/templates/verification-memo-template.md +1 -1
  80. package/roles/numerical-analysis-engineer/tests/test_numerical_analysis_core.py +3 -2
  81. package/roles/quality-management-engineer/ROLE.md +161 -0
  82. package/roles/quality-management-engineer/SOURCES.md +36 -0
  83. package/roles/quality-management-engineer/cli.py +366 -0
  84. package/roles/quality-management-engineer/core/quality_management_core.py +1915 -0
  85. package/roles/quality-management-engineer/templates/qms-audit-report-template.md +230 -0
  86. package/roles/quality-management-engineer/tests/test_quality_management_cli_profile.py +127 -0
  87. package/roles/quality-management-engineer/tests/test_quality_management_core.py +245 -0
  88. package/roles/quality-management-engineer/tests/test_role_quality_management_engineer.py +133 -0
  89. package/roles/rocket-propulsion-engineer/ROLE.md +177 -0
  90. package/roles/rocket-propulsion-engineer/SOURCES.md +18 -0
  91. package/roles/rocket-propulsion-engineer/cli.py +284 -0
  92. package/roles/rocket-propulsion-engineer/core/rocket_propulsion_core.py +2205 -0
  93. package/roles/rocket-propulsion-engineer/templates/rocket-propulsion-report-template.md +141 -0
  94. package/roles/rocket-propulsion-engineer/tests/test_rocket_propulsion_cli_profile.py +147 -0
  95. package/roles/rocket-propulsion-engineer/tests/test_rocket_propulsion_core.py +221 -0
  96. package/roles/rocket-propulsion-engineer/tests/test_role_rocket_propulsion_engineer.py +179 -0
  97. package/roles/stability-control-flight-test-engineer/ROLE.md +165 -0
  98. package/roles/stability-control-flight-test-engineer/SOURCES.md +40 -0
  99. package/roles/stability-control-flight-test-engineer/cli.py +439 -0
  100. package/roles/stability-control-flight-test-engineer/core/stability_control_flight_test_core.py +1596 -0
  101. package/roles/stability-control-flight-test-engineer/templates/stability-control-report-template.md +98 -0
  102. package/roles/stability-control-flight-test-engineer/tests/test_role_stability_control_flight_test.py +145 -0
  103. package/roles/stability-control-flight-test-engineer/tests/test_stability_control_flight_test_bundle.py +146 -0
  104. package/roles/stability-control-flight-test-engineer/tests/test_stability_control_flight_test_core.py +405 -0
package/lib/mcp.js CHANGED
@@ -2,12 +2,44 @@
2
2
  // Same wire protocol and host-config shape as Aero Agent Skills' MCP
3
3
  // server (JetBrains AI Assistant/Junie, Claude Desktop, VS Code, Cursor,
4
4
  // Windsurf all speak this identically) — implements initialize, ping,
5
- // tools/list, tools/call; anything else gets -32601, and requests without
6
- // an id are notifications and never answered. Offline: every answer comes
7
- // from the bundled manifest — no network, ever.
5
+ // tools/list, tools/call, plus the SEP-2640 resources model
6
+ // (resources/list, resources/read over role:// URIs) so roles are
7
+ // discoverable as resources, not only through tool calls. Anything else
8
+ // gets -32601, and requests without an id are notifications and never
9
+ // answered. Offline: every answer comes from the bundled manifest — no
10
+ // network, ever.
8
11
  'use strict';
9
12
 
10
- const { Catalog, version } = require('./catalog');
13
+ const { Catalog, tokens, version } = require('./catalog');
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ /* Reverse binding index: skill leaf path -> [role slugs that bind it].
18
+ Built once from ROLE.md frontmatter (skills_bound), cached. Lets a host
19
+ answer "which role owns the deliverable for this skill?" offline. */
20
+ let _reverseCache = null;
21
+ function reverseIndex(catalog) {
22
+ if (_reverseCache) return _reverseCache;
23
+ const inv = new Map();
24
+ const root = catalog.root; // roles tree (repo checkout or bundled)
25
+ for (const r of catalog.roles) {
26
+ const roleMd = path.join(root, r.slug, 'ROLE.md');
27
+ let text = '';
28
+ try { text = fs.readFileSync(roleMd, 'utf8'); } catch (e) { continue; }
29
+ const m = text.match(/^---\n([\s\S]*?)\n---/);
30
+ if (!m) continue;
31
+ const fm = m[1];
32
+ const block = fm.match(/^skills_bound:([\s\S]*?)(?=^[a-z_]+:|\Z)/m);
33
+ if (!block) continue;
34
+ for (const lm of block[1].matchAll(/^\s+-\s+([a-z0-9\-/]+)/gm)) {
35
+ const leaf = lm[1];
36
+ if (!inv.has(leaf)) inv.set(leaf, []);
37
+ inv.get(leaf).push(r.slug);
38
+ }
39
+ }
40
+ _reverseCache = inv;
41
+ return _reverseCache;
42
+ }
11
43
 
12
44
  const TOOLS = [
13
45
  {
@@ -73,6 +105,21 @@ const TOOLS = [
73
105
  additionalProperties: false,
74
106
  },
75
107
  },
108
+ {
109
+ name: 'suggest_role',
110
+ description: 'Reverse binding: given a bound skill leaf path (e.g. avionics/do178c/planning) '
111
+ + 'or a task in plain words, return the role(s) that own the end-to-end deliverable for it. '
112
+ + 'Use when a loaded skill says "who executes this method?" — the role pulls the skill '
113
+ + 'forward; this tool inverts the map. For a task query it ranks roles by title/domain overlap.',
114
+ inputSchema: {
115
+ type: 'object',
116
+ properties: {
117
+ skill: { type: 'string', description: 'Bound skill leaf path (family/pack/skill).' },
118
+ task: { type: 'string', description: 'Plain-words task to rank roles for (alternative to skill).' },
119
+ },
120
+ additionalProperties: false,
121
+ },
122
+ },
76
123
  ];
77
124
 
78
125
  function text(t) {
@@ -134,11 +181,71 @@ function callTool(catalog, name, args) {
134
181
  `${s.id}: ${s.name}\n publisher: ${s.publisher}${s.gated ? ' (gated: no verbatim text)' : ''}\n roles: ${s.roles.join(', ')}`)
135
182
  .join('\n\n'));
136
183
  }
184
+ case 'suggest_role': {
185
+ const inv = reverseIndex(catalog);
186
+ if (args.skill) {
187
+ const skill = String(args.skill).replace(/\/+$/, '');
188
+ const roles = inv.get(skill) || [];
189
+ if (roles.length === 0) {
190
+ const prefixHits = [...inv.entries()].filter(([p]) => p.startsWith(skill + '/')).slice(0, 10);
191
+ if (prefixHits.length === 0) return toolError(`no role binds skill '${skill}' (unbound leaf — wave candidate).`);
192
+ return text(`leaves under ${skill} bound by roles:\n` + prefixHits.map(([p, rs]) => `${p}: ${rs.join(', ')}`).join('\n'));
193
+ }
194
+ return text(`${skill}\n bound by roles:\n` + roles.map((r) => ` -> roles/${r}/ROLE.md`).join('\n'));
195
+ }
196
+ if (args.task) {
197
+ const q = new Set(tokens(String(args.task)));
198
+ const scored = catalog.roles.map((r) => {
199
+ const hay = new Set(tokens(`${r.title} ${r.deliverable_type} ${r.domain} ${r.slug}`));
200
+ let s = 0; for (const w of q) if (hay.has(w)) s += 1;
201
+ return { r, s };
202
+ }).filter((x) => x.s > 0).sort((a, b) => b.s - a.s || (a.r.slug < b.r.slug ? -1 : 1)).slice(0, 8);
203
+ if (scored.length === 0) return toolError('no role matches that task. Call list_domains to browse.');
204
+ return text(scored.map(({ r, s }) => `${r.slug} (score ${s}): ${r.title} — ${r.deliverable_type}`).join('\n'));
205
+ }
206
+ return toolError('suggest_role needs a skill leaf path or a task query.');
207
+ }
137
208
  default:
138
209
  return toolError(`unknown tool '${name}'`);
139
210
  }
140
211
  }
141
212
 
213
+ function resourcesList(catalog) {
214
+ // SEP-2640: roles are resources under the role:// namespace. Every role
215
+ // is listed so hosts can enumerate without guessing slugs; domains are
216
+ // collection URIs.
217
+ const out = [];
218
+ const seen = new Set();
219
+ const push = (uri, name, kind) => {
220
+ if (seen.has(uri)) return;
221
+ seen.add(uri);
222
+ out.push({ uri, name, mimeType: 'text/markdown', description: `${kind} — ${name}` });
223
+ };
224
+ for (const r of catalog.roles) {
225
+ push(`role://${r.slug}`, r.slug, 'role');
226
+ push(`role://${r.domain}`, r.domain, 'role domain');
227
+ }
228
+ push('role://', 'role bank root', 'role');
229
+ return out;
230
+ }
231
+
232
+ function readResource(catalog, uri) {
233
+ const u = String(uri || '');
234
+ if (u === 'role://' || u === 'role:') {
235
+ return text(`Aero Agent Roles — resource root\n\nDomains:\n${domainsSummary(catalog)}\n\nLoad a domain or role with role://<domain> or role://<slug>\n`);
236
+ }
237
+ if (!u.startsWith('role://')) return toolError(`unknown resource uri '${uri}' (expected role://…)`);
238
+ const path = u.slice('role://'.length).replace(/\/+$/, '');
239
+ if (!path) return text(`Aero Agent Roles — resource root\n\n${domainsSummary(catalog)}\n`);
240
+ const role = catalog.find(path);
241
+ if (role) return text(catalog.readRoleMd(role.slug));
242
+ const inDomain = catalog.roles.filter((r) => r.domain === path);
243
+ if (inDomain.length > 0) {
244
+ return text(`${path} — ${inDomain.length} roles\n` + inDomain.map((r) => `${r.slug}: ${r.title} — ${r.deliverable_type}`).join('\n'));
245
+ }
246
+ return toolError(`no role or domain '${path}'. Closest: ${catalog.search(path.replace(/-/g, ' '), 3).map((h) => h.role.slug).join(', ') || 'none'}`);
247
+ }
248
+
142
249
  function serve() {
143
250
  const catalog = new Catalog();
144
251
  let buffer = '';
@@ -156,7 +263,10 @@ function serve() {
156
263
  case 'initialize':
157
264
  return reply(req.id, {
158
265
  protocolVersion: (req.params && req.params.protocolVersion) || '2025-06-18',
159
- capabilities: { tools: { listChanged: false } },
266
+ capabilities: {
267
+ tools: { listChanged: false },
268
+ resources: { subscribe: false, listChanged: false },
269
+ },
160
270
  serverInfo: { name: 'aero-agent-roles', version: version() },
161
271
  });
162
272
  case 'ping':
@@ -169,6 +279,20 @@ function serve() {
169
279
  } catch (e) {
170
280
  return reply(req.id, toolError(`tool failed: ${e.message}`));
171
281
  }
282
+ case 'resources/list':
283
+ try {
284
+ return reply(req.id, { resources: resourcesList(catalog) });
285
+ } catch (e) {
286
+ return reply(req.id, undefined, { code: -32603, message: `resources/list failed: ${e.message}` });
287
+ }
288
+ case 'resources/read':
289
+ try {
290
+ const uri = req.params && req.params.uri;
291
+ const res = readResource(catalog, uri);
292
+ return reply(req.id, { contents: [{ uri, mimeType: 'text/markdown', text: res.content[0].text }] });
293
+ } catch (e) {
294
+ return reply(req.id, undefined, { code: -32603, message: `resources/read failed: ${e.message}` });
295
+ }
172
296
  default:
173
297
  if (isNotification) return undefined;
174
298
  return reply(req.id, undefined, { code: -32601, message: `method not found: ${req.method}` });
@@ -196,4 +320,4 @@ function serve() {
196
320
  process.stdin.on('end', () => process.exit(0));
197
321
  }
198
322
 
199
- module.exports = { serve, callTool, TOOLS };
323
+ module.exports = { serve, callTool, TOOLS, resourcesList, readResource };
package/manifest.json CHANGED
@@ -1,13 +1,26 @@
1
1
  {
2
2
  "schema": "aero-agent-roles/manifest@1",
3
3
  "counts": {
4
- "roles": 25,
4
+ "roles": 38,
5
5
  "domains": 12,
6
- "skills_bound": 466,
7
- "tests": 966,
8
- "standards": 22
6
+ "skills_bound": 597,
7
+ "tests": 1519,
8
+ "standards": 27
9
9
  },
10
10
  "roles": [
11
+ {
12
+ "slug": "adcs-engineer",
13
+ "title": "ADCS Engineer",
14
+ "domain": "space-systems",
15
+ "deliverable_type": "Attitude Determination and Control Subsystem Report",
16
+ "status": "draft",
17
+ "standards": [
18
+ "ecss"
19
+ ],
20
+ "skills_bound": 14,
21
+ "tests": 46,
22
+ "stage_preview": "adcs/pointing-error-budget -> adcs/environmental-disturbance-tor -> adcs/gravity-gradient-stabilizatio -> adcs/star-tracker -> adcs/magnetometer-calibration"
23
+ },
11
24
  {
12
25
  "slug": "aerodynamics-engineer",
13
26
  "title": "Aerodynamics Engineer",
@@ -34,6 +47,34 @@
34
47
  "tests": 27,
35
48
  "stage_preview": "constraint-analysis -> sizing-mission-profile -> openvsp-geometry -> ws-tw-trade -> weight-estimation + tow-estimation"
36
49
  },
50
+ {
51
+ "slug": "aircraft-performance-engineer",
52
+ "title": "Aircraft Performance Engineer",
53
+ "domain": "flight-mechanics",
54
+ "deliverable_type": "Aircraft Performance Analysis Report",
55
+ "status": "draft",
56
+ "standards": [
57
+ "far-25",
58
+ "far-29"
59
+ ],
60
+ "skills_bound": 9,
61
+ "tests": 73,
62
+ "stage_preview": "(workbook planning) -> flight-mechanics/performance/balan -> flight-mechanics/performance/prope -> flight-mechanics/performance/rotor -> flight-mechanics/performance/rotor"
63
+ },
64
+ {
65
+ "slug": "aircraft-systems-sizing-engineer",
66
+ "title": "Aircraft Systems Sizing Engineer",
67
+ "domain": "vehicle-design",
68
+ "deliverable_type": "Aircraft System Sizing Report",
69
+ "status": "draft",
70
+ "standards": [
71
+ "far-25",
72
+ "cs-25"
73
+ ],
74
+ "skills_bound": 14,
75
+ "tests": 30,
76
+ "stage_preview": "sizing/aircraft-electrical-load-an -> sizing/air-cycle-machine-sizing -> sizing/avionics-bay-cooling-sizing -> sizing/aircraft-oxygen-system-sizi -> sizing/brake-energy-sizing, sizing"
77
+ },
37
78
  {
38
79
  "slug": "airworthiness-compliance-engineer",
39
80
  "title": "Airworthiness Compliance Engineer",
@@ -61,6 +102,46 @@
61
102
  "tests": 32,
62
103
  "stage_preview": "as9100/internal-quality-audit -> as9100/document-control -> as9100/management-review -> as9100/risk-management + quality -> as9100/nonconformance-control + co"
63
104
  },
105
+ {
106
+ "slug": "autopilot-control-engineer",
107
+ "title": "Autopilot Control Engineer",
108
+ "domain": "gnc-autonomy",
109
+ "deliverable_type": "autopilot control law design package",
110
+ "status": "draft",
111
+ "standards": [
112
+ "mil-std-1797a"
113
+ ],
114
+ "skills_bound": 12,
115
+ "tests": 46,
116
+ "stage_preview": "gnc-autonomy/control/state-space-a -> gnc-autonomy/control/pid-control-d -> gnc-autonomy/control/frequency-res -> gnc-autonomy/control/root-locus-de -> gnc-autonomy/control/frequency-res"
117
+ },
118
+ {
119
+ "slug": "boundary-layer-engineer",
120
+ "title": "Boundary-Layer Engineer",
121
+ "domain": "aerodynamics",
122
+ "deliverable_type": "boundary-layer and viscous drag analysis report",
123
+ "status": "draft",
124
+ "standards": [
125
+ "naca-tr-824"
126
+ ],
127
+ "skills_bound": 10,
128
+ "tests": 27,
129
+ "stage_preview": "aerodynamics/boundary-layer/bounda -> aerodynamics/boundary-layer/squire -> aerodynamics/boundary-layer/mangle -> aerodynamics/boundary-layer/lamina -> aerodynamics/boundary-layer/rough-"
130
+ },
131
+ {
132
+ "slug": "composites-structures-engineer",
133
+ "title": "Composite Structures Engineer (Analysis + Certification Evidence)",
134
+ "domain": "structures",
135
+ "deliverable_type": "composite structure analysis + certification report",
136
+ "status": "draft",
137
+ "standards": [
138
+ "far-25",
139
+ "cmh-17"
140
+ ],
141
+ "skills_bound": 12,
142
+ "tests": 36,
143
+ "stage_preview": "cmh17-allowables -> laminate-stiffness, laminate-first -> failure-criteria, laminate-first-p -> laminate-hygrothermal-response -> laminate-plate-buckling"
144
+ },
64
145
  {
65
146
  "slug": "data-bus-avionics-engineer",
66
147
  "title": "Data Bus / Avionics Network Engineer",
@@ -129,6 +210,21 @@
129
210
  "tests": 41,
130
211
  "stage_preview": "isa-atmosphere + density-altitude -> finite-difference-derivatives + nu -> least-squares-regression + optimiz -> eigenvalue-decomposition + singula -> fast-fourier-transform + fir-filte"
131
212
  },
213
+ {
214
+ "slug": "fem-analysis-engineer",
215
+ "title": "Finite Element Analysis Engineer",
216
+ "domain": "structures",
217
+ "deliverable_type": "Finite Element Analysis Report",
218
+ "status": "draft",
219
+ "standards": [
220
+ "far-25",
221
+ "cs-25",
222
+ "mmpsd"
223
+ ],
224
+ "skills_bound": 8,
225
+ "tests": 27,
226
+ "stage_preview": "structures/fem/truss-analysis -> structures/fem/beam-frame-analysis -> structures/fem/beam-column-analysi -> structures/fem/buckling-analysis -> structures/fem/beam-vibration"
227
+ },
132
228
  {
133
229
  "slug": "flight-management-engineer",
134
230
  "title": "Flight Management Engineer",
@@ -158,6 +254,19 @@
158
254
  "tests": 42,
159
255
  "stage_preview": "breguet-range + breguet-endurance -> climb-performance + descent-perfor -> oei-climb-gradient + energy-height -> rotorcraft-hover-performance + rot -> longitudinal-stability + lateral-d"
160
256
  },
257
+ {
258
+ "slug": "flight-software-engineer",
259
+ "title": "Flight Software Engineer",
260
+ "domain": "avionics",
261
+ "deliverable_type": "Flight Software Design and Verification Plan",
262
+ "status": "draft",
263
+ "standards": [
264
+ "do-178c"
265
+ ],
266
+ "skills_bound": 4,
267
+ "tests": 54,
268
+ "stage_preview": "avionics/fsw/cfs-architecture -> avionics/fsw/fprime-component -> avionics/fsw/fprime-component -> avionics/fsw/cfs-architecture -> avionics/fsw/real-time-scheduling"
269
+ },
161
270
  {
162
271
  "slug": "flight-test-engineer",
163
272
  "title": "Flight Test Engineer",
@@ -186,6 +295,20 @@
186
295
  "tests": 45,
187
296
  "stage_preview": "flight-test-data-reduction -> (ISA physics, climb leaf method) -> takeoff-distance-determination + e -> landing-distance-determination -> level-acceleration-test + engine-f"
188
297
  },
298
+ {
299
+ "slug": "flight-test-planning-engineer",
300
+ "title": "Flight Test Planning Engineer",
301
+ "domain": "flight-test-operations",
302
+ "deliverable_type": "Flight Test Plan and Requirements Traceability",
303
+ "status": "draft",
304
+ "standards": [
305
+ "far-25",
306
+ "cs-25"
307
+ ],
308
+ "skills_bound": 7,
309
+ "tests": 54,
310
+ "stage_preview": "role core (standalone traceability -> flight-test-operations/planning/te -> flight-test-operations/planning/fl -> flight-test-operations/planning/te -> flight-test-operations/planning/pc"
311
+ },
189
312
  {
190
313
  "slug": "gnc-engineer",
191
314
  "title": "Guidance, Navigation and Control (GNC) Engineer",
@@ -241,6 +364,21 @@
241
364
  "tests": 49,
242
365
  "stage_preview": "mbse/requirements-modeling -> mbse/systems-engineering -> mbse/sysml-modeling -> mbse/systems-engineering -> mbse/trade-study-analysis, mbse/sy"
243
366
  },
367
+ {
368
+ "slug": "navigation-engineer",
369
+ "title": "Navigation Engineer",
370
+ "domain": "gnc-autonomy",
371
+ "deliverable_type": "navigation architecture and position error analysis report",
372
+ "status": "draft",
373
+ "standards": [
374
+ "do-229",
375
+ "do-208",
376
+ "icao-annex-10"
377
+ ],
378
+ "skills_bound": 13,
379
+ "tests": 27,
380
+ "stage_preview": "navigation-frames -> inertial-navigation -> gnss-pseudorange-positioning + dil -> gnss-raim-fde -> gnss-carrier-smoothing + gnss-dopp"
381
+ },
244
382
  {
245
383
  "slug": "ndt-engineer",
246
384
  "title": "NDT Engineer",
@@ -281,6 +419,32 @@
281
419
  "tests": 31,
282
420
  "stage_preview": "gas-turbine-cycle + real-cycle-eff -> bypass-ratio-trade + regenerative- -> turbofan-off-design -> compressor-map + multi-stage-compr -> turbine-blade-cooling"
283
421
  },
422
+ {
423
+ "slug": "quality-management-engineer",
424
+ "title": "AS9100 Quality Management Engineer",
425
+ "domain": "manufacturing-quality",
426
+ "deliverable_type": "AS9100 quality management system audit report",
427
+ "status": "draft",
428
+ "standards": [
429
+ "as9100"
430
+ ],
431
+ "skills_bound": 10,
432
+ "tests": 42,
433
+ "stage_preview": "manufacturing-quality/as9100/gage- -> manufacturing-quality/as9100/gage- -> manufacturing-quality/as9100/attri -> manufacturing-quality/as9100/stati -> manufacturing-quality/as9100/indiv"
434
+ },
435
+ {
436
+ "slug": "rocket-propulsion-engineer",
437
+ "title": "Rocket Propulsion Engineer",
438
+ "domain": "propulsion",
439
+ "deliverable_type": "rocket propulsion system design report",
440
+ "status": "draft",
441
+ "standards": [
442
+ "ecss"
443
+ ],
444
+ "skills_bound": 14,
445
+ "tests": 38,
446
+ "stage_preview": "propulsion/rocket/propellant-selec -> propulsion/rocket/rocket-sizing, r -> propulsion/rocket/rocket-gravity-l -> propulsion/rocket/rocket-engine-cy -> propulsion/rocket/combustion-chamb"
447
+ },
284
448
  {
285
449
  "slug": "safety-assessment-engineer",
286
450
  "title": "Safety Assessment Engineer (ARP4761A)",
@@ -310,6 +474,20 @@
310
474
  "tests": 33,
311
475
  "stage_preview": "mission-delta-v-budget + keplerian -> hohmann-transfer + bi-elliptic-tra -> launch-window-analysis + c3-depart -> satellite-coverage + walker-delta- -> eclipse-time + orbital-perturbatio"
312
476
  },
477
+ {
478
+ "slug": "stability-control-flight-test-engineer",
479
+ "title": "Stability and Control Flight Test Engineer",
480
+ "domain": "flight-test-operations",
481
+ "deliverable_type": "Stability and Control Flight Test Report",
482
+ "status": "draft",
483
+ "standards": [
484
+ "far-25",
485
+ "cs-25"
486
+ ],
487
+ "skills_bound": 4,
488
+ "tests": 53,
489
+ "stage_preview": "(item facts; no leaf) -> flight-test-operations/stability/s -> flight-test-operations/stability/d -> flight-test-operations/stability/l -> flight-test-operations/stability/c"
490
+ },
313
491
  {
314
492
  "slug": "state-estimation-engineer",
315
493
  "title": "State Estimation Engineer",
@@ -412,7 +590,8 @@
412
590
  "gated": true,
413
591
  "roles": [
414
592
  "as9100-quality-auditor",
415
- "ndt-engineer"
593
+ "ndt-engineer",
594
+ "quality-management-engineer"
416
595
  ]
417
596
  },
418
597
  {
@@ -433,16 +612,29 @@
433
612
  "engineering-analysis-engineer"
434
613
  ]
435
614
  },
615
+ {
616
+ "id": "cmh-17",
617
+ "name": "cmh-17",
618
+ "publisher": "unknown",
619
+ "gated": true,
620
+ "roles": [
621
+ "composites-structures-engineer"
622
+ ]
623
+ },
436
624
  {
437
625
  "id": "cs-25",
438
626
  "name": "EASA CS-25, Certification Specifications",
439
627
  "publisher": "EASA",
440
628
  "gated": true,
441
629
  "roles": [
630
+ "aircraft-systems-sizing-engineer",
442
631
  "airworthiness-compliance-engineer",
632
+ "fem-analysis-engineer",
443
633
  "flight-test-performance-engineer",
634
+ "flight-test-planning-engineer",
444
635
  "guidance-engineer",
445
- "safety-assessment-engineer"
636
+ "safety-assessment-engineer",
637
+ "stability-control-flight-test-engineer"
446
638
  ]
447
639
  },
448
640
  {
@@ -460,7 +652,26 @@
460
652
  "publisher": "RTCA/EUROCAE",
461
653
  "gated": true,
462
654
  "roles": [
463
- "do178c-cert-engineer"
655
+ "do178c-cert-engineer",
656
+ "flight-software-engineer"
657
+ ]
658
+ },
659
+ {
660
+ "id": "do-208",
661
+ "name": "RTCA DO-208, Minimum Operational Performance Standards for Airborne Supplemental Navigation Equipment Using GPS",
662
+ "publisher": "RTCA",
663
+ "gated": true,
664
+ "roles": [
665
+ "navigation-engineer"
666
+ ]
667
+ },
668
+ {
669
+ "id": "do-229",
670
+ "name": "RTCA DO-229, Minimum Operational Performance Standards for GPS/WAAS Airborne Equipment",
671
+ "publisher": "RTCA",
672
+ "gated": true,
673
+ "roles": [
674
+ "navigation-engineer"
464
675
  ]
465
676
  },
466
677
  {
@@ -496,6 +707,8 @@
496
707
  "publisher": "ECSS",
497
708
  "gated": true,
498
709
  "roles": [
710
+ "adcs-engineer",
711
+ "rocket-propulsion-engineer",
499
712
  "space-systems-engineer"
500
713
  ]
501
714
  },
@@ -507,15 +720,30 @@
507
720
  "roles": [
508
721
  "aerodynamics-engineer",
509
722
  "aircraft-design-engineer",
723
+ "aircraft-performance-engineer",
724
+ "aircraft-systems-sizing-engineer",
510
725
  "airworthiness-compliance-engineer",
726
+ "composites-structures-engineer",
727
+ "fem-analysis-engineer",
511
728
  "flight-mechanics-engineer",
512
729
  "flight-test-engineer",
513
730
  "flight-test-performance-engineer",
731
+ "flight-test-planning-engineer",
514
732
  "guidance-engineer",
515
733
  "safety-assessment-engineer",
734
+ "stability-control-flight-test-engineer",
516
735
  "structures-loads-engineer"
517
736
  ]
518
737
  },
738
+ {
739
+ "id": "far-29",
740
+ "name": "far-29",
741
+ "publisher": "unknown",
742
+ "gated": true,
743
+ "roles": [
744
+ "aircraft-performance-engineer"
745
+ ]
746
+ },
519
747
  {
520
748
  "id": "far-33",
521
749
  "name": "14 CFR Part 33, Airworthiness Standards: Aircraft Engines",
@@ -525,6 +753,15 @@
525
753
  "propulsion-engineer"
526
754
  ]
527
755
  },
756
+ {
757
+ "id": "icao-annex-10",
758
+ "name": "ICAO Annex 10, Aeronautical Telecommunications (Vol I: Radio Navigation Aids)",
759
+ "publisher": "ICAO",
760
+ "gated": true,
761
+ "roles": [
762
+ "navigation-engineer"
763
+ ]
764
+ },
528
765
  {
529
766
  "id": "mil-std-1553",
530
767
  "name": "MIL-STD-1553B, Digital Time Division Command/Response Multiplex Data Bus",
@@ -538,8 +775,9 @@
538
775
  "id": "mil-std-1797a",
539
776
  "name": "MIL-STD-1797A, Flying Qualities of Piloted Aircraft",
540
777
  "publisher": "US DoD",
541
- "gated": false,
778
+ "gated": true,
542
779
  "roles": [
780
+ "autopilot-control-engineer",
543
781
  "flight-mechanics-engineer",
544
782
  "flight-test-engineer",
545
783
  "gnc-engineer"
@@ -551,6 +789,7 @@
551
789
  "publisher": "Battelle / FAA",
552
790
  "gated": true,
553
791
  "roles": [
792
+ "fem-analysis-engineer",
554
793
  "structures-loads-engineer"
555
794
  ]
556
795
  },
@@ -560,6 +799,7 @@
560
799
  "publisher": "NACA/NASA (public domain)",
561
800
  "gated": true,
562
801
  "roles": [
802
+ "boundary-layer-engineer",
563
803
  "high-speed-aerodynamics-engineer"
564
804
  ]
565
805
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aero-agent-roles",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "The role layer for aerospace engineering agents: professional roles that bind verified Aero Agent Skills into end-to-end deliverables, with evidence gates and a human sign-off. A CLI and an MCP server. By Ashforde OU.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Ashforde OU <contact@ashforde.org> (https://ashforde.org)",
@@ -22,7 +22,9 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "prepack": "node scripts/prepack.js",
25
- "test": "node test/smoke.mjs"
25
+ "test": "node test/smoke.mjs",
26
+ "mcp": "node bin/aero-agent-roles.js mcp",
27
+ "mcp:verify": "node test/smoke.mjs"
26
28
  },
27
29
  "engines": {
28
30
  "node": ">=18"