omgkit 2.12.0 → 2.15.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 (140) hide show
  1. package/README.md +97 -12
  2. package/package.json +2 -2
  3. package/plugin/agents/api-designer.md +5 -0
  4. package/plugin/agents/architect.md +8 -0
  5. package/plugin/agents/brainstormer.md +4 -0
  6. package/plugin/agents/cicd-manager.md +6 -0
  7. package/plugin/agents/code-reviewer.md +6 -0
  8. package/plugin/agents/copywriter.md +2 -0
  9. package/plugin/agents/data-engineer.md +255 -0
  10. package/plugin/agents/database-admin.md +10 -0
  11. package/plugin/agents/debugger.md +10 -0
  12. package/plugin/agents/devsecops.md +314 -0
  13. package/plugin/agents/docs-manager.md +4 -0
  14. package/plugin/agents/domain-decomposer.md +181 -0
  15. package/plugin/agents/embedded-systems.md +397 -0
  16. package/plugin/agents/fullstack-developer.md +12 -0
  17. package/plugin/agents/game-systems-designer.md +375 -0
  18. package/plugin/agents/git-manager.md +10 -0
  19. package/plugin/agents/journal-writer.md +2 -0
  20. package/plugin/agents/ml-engineer.md +284 -0
  21. package/plugin/agents/observability-engineer.md +353 -0
  22. package/plugin/agents/oracle.md +9 -0
  23. package/plugin/agents/performance-engineer.md +290 -0
  24. package/plugin/agents/pipeline-architect.md +6 -0
  25. package/plugin/agents/planner.md +12 -0
  26. package/plugin/agents/platform-engineer.md +325 -0
  27. package/plugin/agents/project-manager.md +3 -0
  28. package/plugin/agents/researcher.md +5 -0
  29. package/plugin/agents/scientific-computing.md +426 -0
  30. package/plugin/agents/scout.md +3 -0
  31. package/plugin/agents/security-auditor.md +7 -0
  32. package/plugin/agents/sprint-master.md +17 -0
  33. package/plugin/agents/tester.md +10 -0
  34. package/plugin/agents/ui-ux-designer.md +12 -0
  35. package/plugin/agents/vulnerability-scanner.md +6 -0
  36. package/plugin/commands/data/pipeline.md +47 -0
  37. package/plugin/commands/data/quality.md +49 -0
  38. package/plugin/commands/domain/analyze.md +34 -0
  39. package/plugin/commands/domain/map.md +41 -0
  40. package/plugin/commands/game/balance.md +56 -0
  41. package/plugin/commands/game/optimize.md +62 -0
  42. package/plugin/commands/iot/provision.md +58 -0
  43. package/plugin/commands/ml/evaluate.md +47 -0
  44. package/plugin/commands/ml/train.md +48 -0
  45. package/plugin/commands/perf/benchmark.md +54 -0
  46. package/plugin/commands/perf/profile.md +49 -0
  47. package/plugin/commands/platform/blueprint.md +56 -0
  48. package/plugin/commands/security/audit.md +54 -0
  49. package/plugin/commands/security/scan.md +55 -0
  50. package/plugin/commands/sre/dashboard.md +53 -0
  51. package/plugin/registry.yaml +711 -0
  52. package/plugin/skills/ai-ml/experiment-tracking/SKILL.md +338 -0
  53. package/plugin/skills/ai-ml/feature-stores/SKILL.md +340 -0
  54. package/plugin/skills/ai-ml/llm-ops/SKILL.md +454 -0
  55. package/plugin/skills/ai-ml/ml-pipelines/SKILL.md +390 -0
  56. package/plugin/skills/ai-ml/model-monitoring/SKILL.md +398 -0
  57. package/plugin/skills/ai-ml/model-serving/SKILL.md +386 -0
  58. package/plugin/skills/event-driven/cqrs-patterns/SKILL.md +348 -0
  59. package/plugin/skills/event-driven/event-sourcing/SKILL.md +334 -0
  60. package/plugin/skills/event-driven/kafka-deep/SKILL.md +252 -0
  61. package/plugin/skills/event-driven/saga-orchestration/SKILL.md +335 -0
  62. package/plugin/skills/event-driven/schema-registry/SKILL.md +328 -0
  63. package/plugin/skills/event-driven/stream-processing/SKILL.md +313 -0
  64. package/plugin/skills/game/game-audio/SKILL.md +446 -0
  65. package/plugin/skills/game/game-networking/SKILL.md +490 -0
  66. package/plugin/skills/game/godot-patterns/SKILL.md +413 -0
  67. package/plugin/skills/game/shader-programming/SKILL.md +492 -0
  68. package/plugin/skills/game/unity-patterns/SKILL.md +488 -0
  69. package/plugin/skills/iot/device-provisioning/SKILL.md +405 -0
  70. package/plugin/skills/iot/edge-computing/SKILL.md +369 -0
  71. package/plugin/skills/iot/industrial-protocols/SKILL.md +438 -0
  72. package/plugin/skills/iot/mqtt-deep/SKILL.md +418 -0
  73. package/plugin/skills/iot/ota-updates/SKILL.md +426 -0
  74. package/plugin/skills/microservices/api-gateway-patterns/SKILL.md +201 -0
  75. package/plugin/skills/microservices/circuit-breaker-patterns/SKILL.md +246 -0
  76. package/plugin/skills/microservices/contract-testing/SKILL.md +284 -0
  77. package/plugin/skills/microservices/distributed-tracing/SKILL.md +246 -0
  78. package/plugin/skills/microservices/service-discovery/SKILL.md +304 -0
  79. package/plugin/skills/microservices/service-mesh/SKILL.md +181 -0
  80. package/plugin/skills/mobile-advanced/mobile-ci-cd/SKILL.md +407 -0
  81. package/plugin/skills/mobile-advanced/mobile-security/SKILL.md +403 -0
  82. package/plugin/skills/mobile-advanced/offline-first/SKILL.md +473 -0
  83. package/plugin/skills/mobile-advanced/push-notifications/SKILL.md +494 -0
  84. package/plugin/skills/mobile-advanced/react-native-deep/SKILL.md +374 -0
  85. package/plugin/skills/simulation/numerical-methods/SKILL.md +434 -0
  86. package/plugin/skills/simulation/parallel-computing/SKILL.md +382 -0
  87. package/plugin/skills/simulation/physics-engines/SKILL.md +377 -0
  88. package/plugin/skills/simulation/validation-verification/SKILL.md +479 -0
  89. package/plugin/skills/simulation/visualization-scientific/SKILL.md +365 -0
  90. package/plugin/templates/autonomous/archetypes/event-driven-app.yaml +460 -0
  91. package/plugin/templates/autonomous/archetypes/microservices-app.yaml +431 -0
  92. package/plugin/templates/autonomous/state-schema.yaml +1 -1
  93. package/plugin/workflows/ai-engineering/agent-development.md +3 -3
  94. package/plugin/workflows/ai-engineering/fine-tuning.md +3 -3
  95. package/plugin/workflows/ai-engineering/model-evaluation.md +3 -3
  96. package/plugin/workflows/ai-engineering/prompt-engineering.md +2 -2
  97. package/plugin/workflows/ai-engineering/rag-development.md +4 -4
  98. package/plugin/workflows/ai-ml/data-pipeline.md +188 -0
  99. package/plugin/workflows/ai-ml/experiment-cycle.md +203 -0
  100. package/plugin/workflows/ai-ml/feature-engineering.md +208 -0
  101. package/plugin/workflows/ai-ml/model-deployment.md +199 -0
  102. package/plugin/workflows/ai-ml/monitoring-setup.md +227 -0
  103. package/plugin/workflows/api/api-design.md +1 -1
  104. package/plugin/workflows/api/api-testing.md +2 -2
  105. package/plugin/workflows/content/technical-docs.md +1 -1
  106. package/plugin/workflows/database/migration.md +1 -1
  107. package/plugin/workflows/database/optimization.md +1 -1
  108. package/plugin/workflows/database/schema-design.md +3 -3
  109. package/plugin/workflows/development/bug-fix.md +3 -3
  110. package/plugin/workflows/development/code-review.md +2 -1
  111. package/plugin/workflows/development/feature.md +3 -3
  112. package/plugin/workflows/development/refactor.md +2 -2
  113. package/plugin/workflows/event-driven/consumer-groups.md +190 -0
  114. package/plugin/workflows/event-driven/event-storming.md +172 -0
  115. package/plugin/workflows/event-driven/replay-testing.md +186 -0
  116. package/plugin/workflows/event-driven/saga-implementation.md +206 -0
  117. package/plugin/workflows/event-driven/schema-evolution.md +173 -0
  118. package/plugin/workflows/fullstack/authentication.md +4 -4
  119. package/plugin/workflows/fullstack/full-feature.md +4 -4
  120. package/plugin/workflows/game-dev/content-pipeline.md +218 -0
  121. package/plugin/workflows/game-dev/platform-submission.md +263 -0
  122. package/plugin/workflows/game-dev/playtesting.md +237 -0
  123. package/plugin/workflows/game-dev/prototype-to-production.md +205 -0
  124. package/plugin/workflows/microservices/contract-first.md +151 -0
  125. package/plugin/workflows/microservices/distributed-tracing.md +166 -0
  126. package/plugin/workflows/microservices/domain-decomposition.md +123 -0
  127. package/plugin/workflows/microservices/integration-testing.md +149 -0
  128. package/plugin/workflows/microservices/service-mesh-setup.md +153 -0
  129. package/plugin/workflows/microservices/service-scaffolding.md +151 -0
  130. package/plugin/workflows/omega/1000x-innovation.md +2 -2
  131. package/plugin/workflows/omega/100x-architecture.md +2 -2
  132. package/plugin/workflows/omega/10x-improvement.md +2 -2
  133. package/plugin/workflows/quality/performance-optimization.md +2 -2
  134. package/plugin/workflows/research/best-practices.md +1 -1
  135. package/plugin/workflows/research/technology-research.md +1 -1
  136. package/plugin/workflows/security/penetration-testing.md +3 -3
  137. package/plugin/workflows/security/security-audit.md +3 -3
  138. package/plugin/workflows/sprint/sprint-execution.md +2 -2
  139. package/plugin/workflows/sprint/sprint-retrospective.md +1 -1
  140. package/plugin/workflows/sprint/sprint-setup.md +1 -1
@@ -0,0 +1,405 @@
1
+ # Device Provisioning
2
+
3
+ Secure device onboarding, certificate management, fleet provisioning, and zero-touch deployment.
4
+
5
+ ## Overview
6
+
7
+ Device provisioning securely onboards IoT devices to a fleet, establishing identity, credentials, and configuration.
8
+
9
+ ## Core Concepts
10
+
11
+ ### Provisioning Methods
12
+ - **Pre-provisioning**: Credentials loaded at manufacture
13
+ - **Just-in-time**: Credentials issued on first connection
14
+ - **Self-provisioning**: Device generates own credentials
15
+ - **Fleet provisioning**: Template-based bulk provisioning
16
+
17
+ ### Security Requirements
18
+ - Unique device identity
19
+ - Secure credential storage
20
+ - Certificate rotation
21
+ - Revocation capability
22
+
23
+ ## AWS IoT Device Provisioning
24
+
25
+ ### Fleet Provisioning Template
26
+ ```json
27
+ {
28
+ "Parameters": {
29
+ "SerialNumber": { "Type": "String" },
30
+ "DeviceType": { "Type": "String" },
31
+ "FirmwareVersion": { "Type": "String" }
32
+ },
33
+ "Resources": {
34
+ "certificate": {
35
+ "Type": "AWS::IoT::Certificate",
36
+ "Properties": {
37
+ "CertificateId": { "Ref": "AWS::IoT::Certificate::Id" },
38
+ "Status": "Active"
39
+ }
40
+ },
41
+ "policy": {
42
+ "Type": "AWS::IoT::Policy",
43
+ "Properties": {
44
+ "PolicyDocument": {
45
+ "Version": "2012-10-17",
46
+ "Statement": [
47
+ {
48
+ "Effect": "Allow",
49
+ "Action": ["iot:Connect"],
50
+ "Resource": {
51
+ "Fn::Join": ["", [
52
+ "arn:aws:iot:",
53
+ { "Ref": "AWS::Region" },
54
+ ":",
55
+ { "Ref": "AWS::AccountId" },
56
+ ":client/${iot:Connection.Thing.ThingName}"
57
+ ]]
58
+ }
59
+ },
60
+ {
61
+ "Effect": "Allow",
62
+ "Action": ["iot:Publish", "iot:Receive"],
63
+ "Resource": {
64
+ "Fn::Join": ["", [
65
+ "arn:aws:iot:",
66
+ { "Ref": "AWS::Region" },
67
+ ":",
68
+ { "Ref": "AWS::AccountId" },
69
+ ":topic/devices/${iot:Connection.Thing.ThingName}/*"
70
+ ]]
71
+ }
72
+ },
73
+ {
74
+ "Effect": "Allow",
75
+ "Action": ["iot:Subscribe"],
76
+ "Resource": {
77
+ "Fn::Join": ["", [
78
+ "arn:aws:iot:",
79
+ { "Ref": "AWS::Region" },
80
+ ":",
81
+ { "Ref": "AWS::AccountId" },
82
+ ":topicfilter/devices/${iot:Connection.Thing.ThingName}/*"
83
+ ]]
84
+ }
85
+ }
86
+ ]
87
+ }
88
+ }
89
+ },
90
+ "thing": {
91
+ "Type": "AWS::IoT::Thing",
92
+ "Properties": {
93
+ "ThingName": { "Fn::Join": ["-", ["device", { "Ref": "SerialNumber" }]] },
94
+ "AttributePayload": {
95
+ "serialNumber": { "Ref": "SerialNumber" },
96
+ "deviceType": { "Ref": "DeviceType" },
97
+ "firmwareVersion": { "Ref": "FirmwareVersion" }
98
+ },
99
+ "ThingGroups": [{ "Ref": "DeviceType" }]
100
+ },
101
+ "OverrideSettings": {
102
+ "AttributePayload": "MERGE",
103
+ "ThingGroups": "DO_NOTHING"
104
+ }
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Device-Side Provisioning (ESP32)
111
+ ```cpp
112
+ #include <WiFiClientSecure.h>
113
+ #include <MQTTClient.h>
114
+ #include <ArduinoJson.h>
115
+ #include "Preferences.h"
116
+
117
+ // Claim certificate (embedded at manufacture)
118
+ const char* CLAIM_CERT = "-----BEGIN CERTIFICATE-----\n...";
119
+ const char* CLAIM_KEY = "-----BEGIN RSA PRIVATE KEY-----\n...";
120
+ const char* ROOT_CA = "-----BEGIN CERTIFICATE-----\n...";
121
+
122
+ Preferences prefs;
123
+ WiFiClientSecure net;
124
+ MQTTClient mqtt(4096);
125
+
126
+ struct DeviceCredentials {
127
+ String certificatePem;
128
+ String privateKey;
129
+ String thingName;
130
+ bool provisioned;
131
+ };
132
+
133
+ DeviceCredentials credentials;
134
+
135
+ void loadCredentials() {
136
+ prefs.begin("credentials", true);
137
+ credentials.provisioned = prefs.getBool("provisioned", false);
138
+ if (credentials.provisioned) {
139
+ credentials.certificatePem = prefs.getString("cert");
140
+ credentials.privateKey = prefs.getString("key");
141
+ credentials.thingName = prefs.getString("thing");
142
+ }
143
+ prefs.end();
144
+ }
145
+
146
+ void saveCredentials() {
147
+ prefs.begin("credentials", false);
148
+ prefs.putBool("provisioned", true);
149
+ prefs.putString("cert", credentials.certificatePem);
150
+ prefs.putString("key", credentials.privateKey);
151
+ prefs.putString("thing", credentials.thingName);
152
+ prefs.end();
153
+ }
154
+
155
+ void provisionDevice() {
156
+ // Connect with claim certificate
157
+ net.setCACert(ROOT_CA);
158
+ net.setCertificate(CLAIM_CERT);
159
+ net.setPrivateKey(CLAIM_KEY);
160
+
161
+ mqtt.begin("xxx.iot.region.amazonaws.com", 8883, net);
162
+
163
+ if (!mqtt.connect("provisioning-client")) {
164
+ Serial.println("Provisioning connection failed");
165
+ return;
166
+ }
167
+
168
+ // Subscribe to provisioning topics
169
+ mqtt.subscribe("$aws/provisioning-templates/MyTemplate/provision/json/accepted");
170
+ mqtt.subscribe("$aws/provisioning-templates/MyTemplate/provision/json/rejected");
171
+
172
+ // Create provisioning request
173
+ StaticJsonDocument<256> doc;
174
+ doc["serialNumber"] = getChipId();
175
+ doc["deviceType"] = "sensor-v2";
176
+ doc["firmwareVersion"] = FIRMWARE_VERSION;
177
+
178
+ String payload;
179
+ serializeJson(doc, payload);
180
+
181
+ mqtt.publish("$aws/provisioning-templates/MyTemplate/provision/json", payload);
182
+
183
+ // Wait for response
184
+ unsigned long start = millis();
185
+ while (millis() - start < 30000) {
186
+ mqtt.loop();
187
+
188
+ if (credentials.provisioned) {
189
+ Serial.println("Provisioning successful");
190
+ break;
191
+ }
192
+
193
+ delay(100);
194
+ }
195
+
196
+ mqtt.disconnect();
197
+ }
198
+
199
+ void handleProvisioningResponse(String& topic, String& payload) {
200
+ if (topic.endsWith("/accepted")) {
201
+ StaticJsonDocument<2048> doc;
202
+ deserializeJson(doc, payload);
203
+
204
+ credentials.certificatePem = doc["certificatePem"].as<String>();
205
+ credentials.privateKey = doc["privateKeyPem"].as<String>();
206
+ credentials.thingName = doc["thingName"].as<String>();
207
+ credentials.provisioned = true;
208
+
209
+ saveCredentials();
210
+ }
211
+ }
212
+
213
+ void setup() {
214
+ Serial.begin(115200);
215
+ connectWiFi();
216
+
217
+ loadCredentials();
218
+
219
+ if (!credentials.provisioned) {
220
+ Serial.println("Starting provisioning...");
221
+ provisionDevice();
222
+ }
223
+
224
+ if (credentials.provisioned) {
225
+ // Connect with device certificate
226
+ connectWithDeviceCert();
227
+ }
228
+ }
229
+ ```
230
+
231
+ ## Certificate Management
232
+
233
+ ### Certificate Rotation
234
+ ```python
235
+ from datetime import datetime, timedelta
236
+ from cryptography import x509
237
+ from cryptography.x509.oid import NameOID
238
+ from cryptography.hazmat.primitives import hashes
239
+ from cryptography.hazmat.primitives.asymmetric import rsa
240
+ from cryptography.hazmat.primitives import serialization
241
+
242
+ class CertificateManager:
243
+ def __init__(self, ca_cert_path: str, ca_key_path: str):
244
+ with open(ca_cert_path, 'rb') as f:
245
+ self.ca_cert = x509.load_pem_x509_certificate(f.read())
246
+ with open(ca_key_path, 'rb') as f:
247
+ self.ca_key = serialization.load_pem_private_key(f.read(), password=None)
248
+
249
+ def issue_certificate(
250
+ self,
251
+ device_id: str,
252
+ validity_days: int = 365
253
+ ) -> tuple:
254
+ """Issue a new device certificate"""
255
+ # Generate key pair
256
+ private_key = rsa.generate_private_key(
257
+ public_exponent=65537,
258
+ key_size=2048
259
+ )
260
+
261
+ # Create certificate
262
+ subject = x509.Name([
263
+ x509.NameAttribute(NameOID.COMMON_NAME, device_id),
264
+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "IoT Fleet")
265
+ ])
266
+
267
+ cert = (
268
+ x509.CertificateBuilder()
269
+ .subject_name(subject)
270
+ .issuer_name(self.ca_cert.subject)
271
+ .public_key(private_key.public_key())
272
+ .serial_number(x509.random_serial_number())
273
+ .not_valid_before(datetime.utcnow())
274
+ .not_valid_after(datetime.utcnow() + timedelta(days=validity_days))
275
+ .add_extension(
276
+ x509.BasicConstraints(ca=False, path_length=None),
277
+ critical=True
278
+ )
279
+ .sign(self.ca_key, hashes.SHA256())
280
+ )
281
+
282
+ # Serialize
283
+ cert_pem = cert.public_bytes(serialization.Encoding.PEM)
284
+ key_pem = private_key.private_bytes(
285
+ encoding=serialization.Encoding.PEM,
286
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
287
+ encryption_algorithm=serialization.NoEncryption()
288
+ )
289
+
290
+ return cert_pem, key_pem
291
+
292
+ def should_rotate(self, cert_pem: bytes, threshold_days: int = 30) -> bool:
293
+ """Check if certificate needs rotation"""
294
+ cert = x509.load_pem_x509_certificate(cert_pem)
295
+ days_until_expiry = (cert.not_valid_after - datetime.utcnow()).days
296
+ return days_until_expiry < threshold_days
297
+ ```
298
+
299
+ ## Provisioning Service
300
+
301
+ ### Backend API
302
+ ```python
303
+ from fastapi import FastAPI, HTTPException
304
+ from pydantic import BaseModel
305
+ import boto3
306
+
307
+ app = FastAPI()
308
+ iot = boto3.client('iot')
309
+
310
+ class ProvisioningRequest(BaseModel):
311
+ serial_number: str
312
+ device_type: str
313
+ firmware_version: str
314
+ claim_token: str
315
+
316
+ class ProvisioningResponse(BaseModel):
317
+ thing_name: str
318
+ certificate_pem: str
319
+ private_key: str
320
+ root_ca: str
321
+ endpoint: str
322
+
323
+ @app.post("/provision", response_model=ProvisioningResponse)
324
+ async def provision_device(request: ProvisioningRequest):
325
+ # Validate claim token
326
+ if not validate_claim_token(request.claim_token, request.serial_number):
327
+ raise HTTPException(status_code=401, detail="Invalid claim token")
328
+
329
+ # Check if device already provisioned
330
+ thing_name = f"device-{request.serial_number}"
331
+ try:
332
+ iot.describe_thing(thingName=thing_name)
333
+ raise HTTPException(status_code=409, detail="Device already provisioned")
334
+ except iot.exceptions.ResourceNotFoundException:
335
+ pass
336
+
337
+ # Create certificate
338
+ cert_response = iot.create_keys_and_certificate(setAsActive=True)
339
+
340
+ # Create thing
341
+ iot.create_thing(
342
+ thingName=thing_name,
343
+ thingTypeName=request.device_type,
344
+ attributePayload={
345
+ 'attributes': {
346
+ 'serialNumber': request.serial_number,
347
+ 'firmwareVersion': request.firmware_version
348
+ }
349
+ }
350
+ )
351
+
352
+ # Attach certificate to thing
353
+ iot.attach_thing_principal(
354
+ thingName=thing_name,
355
+ principal=cert_response['certificateArn']
356
+ )
357
+
358
+ # Attach policy
359
+ iot.attach_policy(
360
+ policyName=f"{request.device_type}-policy",
361
+ target=cert_response['certificateArn']
362
+ )
363
+
364
+ # Get endpoint
365
+ endpoint = iot.describe_endpoint(endpointType='iot:Data-ATS')
366
+
367
+ return ProvisioningResponse(
368
+ thing_name=thing_name,
369
+ certificate_pem=cert_response['certificatePem'],
370
+ private_key=cert_response['keyPair']['PrivateKey'],
371
+ root_ca=get_root_ca(),
372
+ endpoint=endpoint['endpointAddress']
373
+ )
374
+ ```
375
+
376
+ ## Best Practices
377
+
378
+ 1. **Unique Identity**: Each device has unique credentials
379
+ 2. **Secure Storage**: Use hardware security modules
380
+ 3. **Certificate Rotation**: Auto-rotate before expiry
381
+ 4. **Audit Trail**: Log all provisioning events
382
+ 5. **Revocation Support**: Ability to revoke compromised devices
383
+
384
+ ## Anti-Patterns
385
+
386
+ - Shared credentials across devices
387
+ - Hardcoded credentials
388
+ - No certificate expiration
389
+ - Missing revocation mechanism
390
+ - Unencrypted credential storage
391
+
392
+ ## When to Use
393
+
394
+ - Fleet management at scale
395
+ - Security-critical deployments
396
+ - Regulatory compliance requirements
397
+ - Zero-touch deployment needs
398
+ - Dynamic fleet scaling
399
+
400
+ ## When NOT to Use
401
+
402
+ - Small fixed fleet
403
+ - Dev/prototype phase
404
+ - No security requirements
405
+ - Manual deployment acceptable