Skip to content

Commit 1cf9f37

Browse files
chore(skills): add eval manifests and host audits
1 parent c97c78e commit 1cf9f37

18 files changed

Lines changed: 1374 additions & 67 deletions

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ summary.json
3030
*.har
3131
*.html
3232
k6-results/
33+
skills/k6-plan/k6-plan-workspace/
34+
skills/k6-builder/k6-builder-workspace/
35+
skills/k6-validate/k6-validate-workspace/
36+
**/iteration-*/
37+
**/benchmark.json
38+
**/benchmark.md
39+
**/grading.json
40+
**/timing.json
41+
**/response.txt
42+
**/review.html
3343

3444
# Temporary files
3545
tmp/

skills/k6-builder/SKILL.md

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,82 @@ Then:
141141
2. If language is not explicit, default to English.
142142
3. Keep command names, k6 metric keys, and code identifiers in English.
143143

144+
## Dynamic Capacity Protocol
145+
146+
Run this protocol before emitting any runnable artifact.
147+
148+
Cross-skill required fields:
149+
150+
- `execution_context`
151+
- `machine_profile`
152+
- `projected_load`
153+
- `capacity_estimate`
154+
- `risk_status`
155+
- `safe_limit_recommendation`
156+
- `scale_out_recommendation`
157+
158+
High-risk gate rule (mandatory):
159+
160+
- Before generating or orchestrating any script that projects more than `500` VUs, run host audit silently with `node scripts/audit-host.js`.
161+
- If Node.js is unavailable, use the Python fallback: `python3 scripts/audit-host.py`.
162+
- Parse stdout JSON and use that as the authoritative `machine_profile` for this generation pass.
163+
164+
Contextual deterministic formulas:
165+
166+
- `vus_max = (logical_cpu * cpu_factor) + (free_ram_gb * ram_factor)`
167+
- `arrival_rate_max = floor(vus_max / max(expected_iteration_duration_seconds, 1))`
168+
169+
Default context factors:
170+
171+
- `local`: `cpu_factor=50`, `ram_factor=10`
172+
- `ci`: `cpu_factor=30`, `ram_factor=6`
173+
- `container`: `cpu_factor=25`, `ram_factor=5`
174+
- `cloud`: `cpu_factor=60`, `ram_factor=12`
175+
- `distributed`: compute per node, then aggregate
176+
177+
Evaluation order:
178+
179+
1. Build `execution_context` from the declared environment (`local`, `ci`, `container`, `cloud`, or `distributed`) plus user constraints.
180+
2. Derive `machine_profile` from current evidence: `logical_cpu`, `free_ram_gb`, `fd_limit`, `ephemeral_port_budget`, environment type, and declared user restrictions.
181+
3. If projected load is expected to exceed `500` VUs, run host audit (`node scripts/audit-host.js`, fallback `python3 scripts/audit-host.py`) and overwrite missing or stale machine evidence with audit output.
182+
4. Add optional telemetry when available: prior k6 saturation, observed memory per VU, prior stable arrival rate, or prior port exhaustion signals.
183+
5. Derive `projected_load` from the runnable executor shape: target VUs, arrival rate, duration, and stages.
184+
6. Calculate `capacity_estimate.vus_max` and `capacity_estimate.arrival_rate_max` from the current `machine_profile` using contextual deterministic formulas. Never use a universal fixed VU ceiling.
185+
7. Classify `risk_status` as `SAFE`, `AT_RISK`, or `HIGH_RISK`.
186+
8. Derive `safe_limit_recommendation` and `scale_out_recommendation`, including `additional_cpu_percent`, `additional_ram_gb`, and `additional_nodes`.
187+
188+
Incomplete-data rules:
189+
190+
- If critical machine inputs are missing, ask one clarification question when that is the cheapest unblocker.
191+
- If the scenario is otherwise clear, continue with a conservative `[assumption-based]` estimate instead of inventing a global default capacity.
192+
- Mark every derived field that depends on missing telemetry as `[assumption-based]` and state the missing evidence explicitly.
193+
194+
Builder-stage gate behavior:
195+
196+
- `SAFE`: emit runnable artifacts normally.
197+
- `AT_RISK`: runnable artifacts are allowed only if the output includes the canonical capacity alert, the reduced safe limit, and the distributed mitigation guidance.
198+
- `HIGH_RISK`: block runnable single-node artifact emission. Replace the runnable artifact section with a blocked-output explanation plus a reduced-load or distributed execution path.
199+
200+
When `HIGH_RISK`, the blocked-output explanation must use this exact format:
201+
202+
`Tu máquina solo tiene [X]GB de RAM disponibles/libres. Intentar correr [Y] VUs localmente colapsará el generador. Te recomiendo limitar la prueba local a [Z] VUs o exportar este diseño para k6-operator (Configuración distribuida).`
203+
204+
Canonical alert format:
205+
206+
```md
207+
LOAD GENERATOR CAPACITY ALERT
208+
Risk Detected: The requested scenario ([X] VUs) exceeds the load generator operating limit ([Y] VUs).
209+
Impact: Possible metric skew, TCP port exhaustion, or k6 process collapse.
210+
Recommendation: Reduce the scenario to [Z] VUs or use distributed infrastructure with at least [N] additional nodes.
211+
```
212+
213+
Determinism rules:
214+
215+
- `Y` must come from the current `capacity_estimate`.
216+
- `Z` must come from the current `safe_limit_recommendation`.
217+
- `N` must come from the current `scale_out_recommendation.additional_nodes`.
218+
- The same request and machine evidence must produce the same capacity classification.
219+
144220
## Required k6 Invariants
145221

146222
Always enforce these validations before returning output:
@@ -394,7 +470,26 @@ Every response must include these sections in order:
394470
/k6-validate <your-plan-or-test-config>
395471
```
396472
- **For other scenarios** (load, stress, soak, spike): Include validation recommendation that references k6-validate.
397-
10. Next recommended step
473+
10. Execution Hints (required)
474+
- Include at least one concrete run command that can be copied as-is.
475+
- Include required environment variables used by that command.
476+
- Use deterministic command shape (`k6 run <script>` plus `-e` flags when needed).
477+
- Keep hints runnable and aligned with the emitted artifact names.
478+
- Treat `Execution Hints` as a hard companion of `Runnable Artifacts`: if artifact code exists, hints must include the exact script filename and matching env var flags.
479+
- Never emit conceptual guidance only; include at least one concrete copy-paste command.
480+
11. Next recommended step
481+
482+
Dynamic capacity reporting requirements:
483+
484+
- `Build Inputs Summary` must include `execution_context`.
485+
- `Internal Minimal Plan` must include `machine_profile` and `projected_load`.
486+
- `Guardrail Validation` must also include these checklist items:
487+
- [ ] Dynamic capacity gate executed with current `machine_profile`
488+
- [ ] `capacity_estimate`, `risk_status`, and `safe_limit_recommendation` are present
489+
- [ ] `scale_out_recommendation` includes `additional_cpu_percent`, `additional_ram_gb`, and `additional_nodes`
490+
- [ ] Canonical capacity alert emitted when `risk_status` is `AT_RISK` or `HIGH_RISK`
491+
492+
- When `risk_status` is `HIGH_RISK`, `Runnable Artifacts` must not include a single-node runnable artifact.
398493
399494
## Runnable Artifact Rules
400495
@@ -445,8 +540,17 @@ Keep this file focused on generation workflow. Place deep guidance in:
445540
8. Select executor and derive coherent scenario config.
446541
9. Enforce executor coherence: if scenario type is `load` and the user did not explicitly request rate-based control, recommend and emit `ramping-vus`.
447542
10. Parse SLA thresholds or apply deterministic defaults.
448-
11. For multi-environment requests, choose architecture using Multi-Environment Architecture Options (default single-script unless explicitly overridden).
449-
12. Generate runnable script/options/config outputs.
450-
13. Apply dashboard and secrets safety policies.
451-
14. Validate all required invariants, including: (a) the generated default export function is named — reject anonymous `export default function () {}`; (b) SLA thresholds are identical across all environments — reject any per-environment threshold relaxation. Both are hard invariant violations that block output emission.
452-
15. Return output in Output Contract order.
543+
11. Run the Dynamic Capacity Protocol using current machine evidence and projected workload (mandatory host audit first when projected load exceeds 500 VUs).
544+
12. For multi-environment requests, choose architecture using Multi-Environment Architecture Options (default single-script unless explicitly overridden).
545+
13. Generate runnable script/options/config outputs only when the capacity gate allows them.
546+
14. Apply dashboard and secrets safety policies.
547+
15. Validate all required invariants, including: (a) the generated default export function is named — reject anonymous `export default function () {}`; (b) SLA thresholds are identical across all environments — reject any per-environment threshold relaxation. Both are hard invariant violations that block output emission.
548+
16. Return output in Output Contract order.
549+
550+
## Local Evaluation Workspace Policy
551+
552+
For official skill evaluation runs in this repository:
553+
554+
- Store artifacts under `skills/k6-builder/k6-builder-workspace/iteration-N/`.
555+
- Keep each run isolated inside its own `iteration-N` directory.
556+
- Treat benchmark outputs, grading files, timing files, and generated responses as non-versioned execution artifacts.

skills/k6-builder/evals/evals.json

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
{
2323
"name": "runnable_artifact",
24-
"text": "Must produce runnable script artifact and execution hints"
24+
"text": "Must produce a runnable script artifact and execution hints that include at least one concrete k6 run command and required env vars"
2525
}
2626
]
2727
},
@@ -200,6 +200,90 @@
200200
],
201201
"files": [],
202202
"expected_output": "browser-smoke-runnable"
203+
},
204+
{
205+
"id": 8,
206+
"prompt": "Build a runnable k6 HTTP load script for a local workstation with 8 logical CPUs, 6 GB free RAM, fd limit 10240, and ephemeral port budget 16000. Target load is 1200 VUs for 15m against https://perf.example.com/checkout. SLA: p95<600ms and error<1%.",
207+
"expected_output": "builder-local-at-risk-capacity-gate",
208+
"files": [],
209+
"assertions": [
210+
{
211+
"name": "capacity_gate_fields",
212+
"text": "Must include execution_context, machine_profile, projected_load, capacity_estimate, risk_status, and safe_limit_recommendation"
213+
},
214+
{
215+
"name": "canonical_capacity_alert",
216+
"text": "Must emit the canonical LOAD GENERATOR CAPACITY ALERT when projected load exceeds the operating limit"
217+
},
218+
{
219+
"name": "mitigation_guidance",
220+
"text": "Must include scale_out_recommendation with additional_cpu_percent, additional_ram_gb, and additional_nodes"
221+
},
222+
{
223+
"name": "at_risk_warning_required",
224+
"text": "Must not emit an at-risk runnable artifact silently; the warning and mitigation must be explicit"
225+
}
226+
]
227+
},
228+
{
229+
"id": 9,
230+
"prompt": "Build a runnable k6 stress script for 6000 VUs on a local Docker Desktop environment with 4 logical CPUs, 4 GB free RAM, fd limit 4096, and ephemeral port budget 8000. Target is https://stress.example.com/api. SLA: p95<900ms.",
231+
"expected_output": "builder-high-risk-capacity-block",
232+
"files": [],
233+
"assertions": [
234+
{
235+
"name": "high_risk_block",
236+
"text": "Must block single-node runnable artifact emission when the capacity gate classifies the scenario as HIGH_RISK"
237+
},
238+
{
239+
"name": "canonical_capacity_alert",
240+
"text": "Must emit the canonical LOAD GENERATOR CAPACITY ALERT for the blocked scenario"
241+
},
242+
{
243+
"name": "reduced_or_distributed_path",
244+
"text": "Must replace the runnable artifact with a reduced-load or distributed execution path"
245+
}
246+
]
247+
},
248+
{
249+
"id": 10,
250+
"prompt": "Build a distributed k6 configuration for 9000 VUs across cloud load generators. Each node has 8 logical CPUs, 16 GB free RAM, fd limit 65535, and environment type cloud. Use https://api.example.net/orders and SLA p95<750ms.",
251+
"expected_output": "builder-distributed-cloud-config",
252+
"files": [],
253+
"assertions": [
254+
{
255+
"name": "distributed_capacity_model",
256+
"text": "Must model per-node capacity instead of applying a single fixed global VU limit"
257+
},
258+
{
259+
"name": "node_count_guidance",
260+
"text": "Must include scale_out_recommendation.additional_nodes derived from the current capacity estimate"
261+
},
262+
{
263+
"name": "distributed_runnable_output",
264+
"text": "Must produce a runnable distributed configuration when the cloud/distributed capacity gate allows it"
265+
}
266+
]
267+
},
268+
{
269+
"id": 11,
270+
"prompt": "Build a rate-driven k6 config for 2600 RPS over 20m on a cloud generator with 16 logical CPUs, 32 GB free RAM, fd limit 65535, and ephemeral port budget 50000. Target is https://rate.example.net and SLA p95<450ms, error<0.5%.",
271+
"expected_output": "builder-rate-driven-cloud-capacity",
272+
"files": [],
273+
"assertions": [
274+
{
275+
"name": "arrival_rate_capacity_fields",
276+
"text": "Must include projected arrival rate and capacity_estimate.arrival_rate_max based on the provided machine profile"
277+
},
278+
{
279+
"name": "rate_driven_scale_out_math",
280+
"text": "Must include scale_out_recommendation.additional_nodes derived from arrival-rate capacity rather than VU-only math"
281+
},
282+
{
283+
"name": "capacity_gate_coherent_with_output",
284+
"text": "Must keep the emitted configuration coherent with the resulting SAFE or AT_RISK capacity assessment"
285+
}
286+
]
203287
}
204288
]
205289
}

skills/k6-builder/references/executor-decision-matrix.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@
142142

143143
## Capacity Guardrails
144144

145+
### Mandatory pre-generation audit for high load
146+
147+
- If projected load exceeds `500` VUs, execute host audit before script generation:
148+
- Primary: `node scripts/audit-host.js`
149+
- Fallback: `python3 scripts/audit-host.py`
150+
- Use audit JSON as the canonical machine evidence (`logical_cpu`, `free_ram_gb`, `fd_limit`, `ephemeral_port_budget`).
151+
145152
### For arrival-rate executors:
146153

147154
**Dimensioning Formula:**
@@ -168,6 +175,23 @@ required_vus = 100 × 0.5 = 50 VUs
168175
- Monitor CPU/memory on load generator
169176
- **Rule:** 1 GB RAM ≈ 50–100 VUs sustained
170177

178+
### Contextual deterministic capacity model
179+
180+
Use context factors instead of a universal ceiling:
181+
182+
```
183+
vus_max = (logical_cpu * cpu_factor) + (free_ram_gb * ram_factor)
184+
arrival_rate_max = floor(vus_max / max(expected_iteration_duration_seconds, 1))
185+
```
186+
187+
Default factors:
188+
189+
- local: `cpu_factor=50`, `ram_factor=10`
190+
- ci: `cpu_factor=30`, `ram_factor=6`
191+
- container: `cpu_factor=25`, `ram_factor=5`
192+
- cloud: `cpu_factor=60`, `ram_factor=12`
193+
- distributed: compute per node, then aggregate
194+
171195
## Threshold Mapping by Executor
172196

173197
| Executor Type | Typical Threshold | Rationale |

skills/k6-builder/references/sla-defaults.md

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,42 @@ When no explicit profile is specified, the following environment-to-profile mapp
2020

2121
This mapping ensures consistent profile selection across different deployment contexts. Users can override by explicitly specifying a profile (e.g., `--profile=standard`).
2222

23-
## VU Capacity Boundaries
23+
## Dynamic Capacity Assessment Baseline
2424

25-
Load generator capacity varies by execution context. Recommended VU limits:
25+
Load generator capacity must be calculated from the current execution context rather than from a universal VU table.
2626

27-
| Context | Recommended Max VUs | Rationale |
28-
|---------|-------------------|-----------|
29-
| Local (laptop/desktop) | 50-100 | Limited CPU/memory; avoid overwhelming local machine |
30-
| CI/CD (standard runner) | 100-200 | Shared resources; keep tests fast and reliable |
31-
| Cloud (dedicated instance) | 500-1000+ | Higher capacity; can scale with larger instance types |
27+
Required inputs:
3228

33-
**Behavior on Out-of-Range Values:**
34-
- If user requests VUs exceeding context limits, the skill should:
35-
1. Issue a `WARNING` noting the potential resource constraint
36-
2. Suggest alternative: scale horizontally (multiple load generators) or use cloud execution
37-
3. Proceed with user-specified value (explicit override) unless it's clearly invalid (e.g., negative VUs)
29+
- `logical_cpu`
30+
- `free_ram_gb`
31+
- `fd_limit`
32+
- `ephemeral_port_budget`
33+
- environment type (`local`, `ci`, `container`, `cloud`, or `distributed`)
34+
- user-declared restrictions
3835

39-
**Example Warning:**
40-
```
41-
⚠️ WARNING: Requested 500 VUs exceeds recommended limit for local execution (50-100 VUs).
42-
Consider running this test on a cloud load generator or reducing VU count to avoid resource exhaustion.
36+
Optional telemetry:
37+
38+
- prior stable VU count
39+
- prior stable arrival rate
40+
- observed CPU saturation
41+
- observed memory per VU
42+
- prior port exhaustion or socket-pressure signals
43+
44+
Required behavior:
45+
46+
1. Derive `capacity_estimate.vus_max` and `capacity_estimate.arrival_rate_max` from the current machine evidence.
47+
2. Derive `safe_limit_recommendation` from the same estimate.
48+
3. Derive `scale_out_recommendation.additional_nodes`, `additional_cpu_percent`, and `additional_ram_gb` whenever projected load exceeds the safe operating range.
49+
4. If critical inputs are missing, use a conservative `[assumption-based]` estimate and state what evidence is missing.
50+
5. Do not rely on a global fixed maximum such as a single laptop or CI runner VU ceiling.
51+
52+
Canonical alert when risk exists:
53+
54+
```md
55+
LOAD GENERATOR CAPACITY ALERT
56+
Risk Detected: The requested scenario ([X] VUs) exceeds the load generator operating limit ([Y] VUs).
57+
Impact: Possible metric skew, TCP port exhaustion, or k6 process collapse.
58+
Recommendation: Reduce the scenario to [Z] VUs or use distributed infrastructure with at least [N] additional nodes.
4359
```
4460

4561
## Parsing Examples

0 commit comments

Comments
 (0)