@tetherto/mdk-skill 0.0.0 → 0.12.1

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 (62) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +133 -0
  3. package/dist/skills/mdk/SKILL.md +114 -0
  4. package/dist/skills/mdk/references/architecture.md +89 -0
  5. package/dist/skills/mdk/references/glossary.md +27 -0
  6. package/dist/skills/mdk/references/mdk-contract.schema.json +138 -0
  7. package/dist/skills/mdk/references/package-index.md +53 -0
  8. package/dist/skills/mdk/references/protocol.md +95 -0
  9. package/dist/skills/mdk-create-app/SKILL.md +231 -0
  10. package/dist/skills/mdk-deployment/SKILL.md +161 -0
  11. package/dist/skills/mdk-gateway-plugin/SKILL.md +192 -0
  12. package/dist/skills/mdk-gateway-plugin/references/controller-patterns.md +99 -0
  13. package/dist/skills/mdk-gateway-plugin/references/plugin-authoring.md +121 -0
  14. package/dist/skills/mdk-publish-security/SKILL.md +177 -0
  15. package/dist/skills/mdk-publish-security/references/vuln-classes.md +151 -0
  16. package/dist/skills/mdk-publish-security/scripts/scan-packages.mjs +544 -0
  17. package/dist/skills/mdk-site-sizing/SKILL.md +160 -0
  18. package/dist/skills/mdk-site-sizing/eval/held-out.json +104 -0
  19. package/dist/skills/mdk-site-sizing/eval/profiles/cap-100devices-2workers-mixed.json +24 -0
  20. package/dist/skills/mdk-site-sizing/eval/profiles/cap-100devices-2workers.json +23 -0
  21. package/dist/skills/mdk-site-sizing/eval/profiles/cap-10devices-1workers.json +23 -0
  22. package/dist/skills/mdk-site-sizing/eval/profiles/cap-15devices-2workers.json +24 -0
  23. package/dist/skills/mdk-site-sizing/eval/profiles/cap-200devices-4workers.json +23 -0
  24. package/dist/skills/mdk-site-sizing/eval/profiles/cap-500devices-4workers.json +23 -0
  25. package/dist/skills/mdk-site-sizing/eval/profiles/cap-50devices-2workers.json +23 -0
  26. package/dist/skills/mdk-site-sizing/references/envelope.json +284 -0
  27. package/dist/skills/mdk-site-sizing/references/envelope.md +42 -0
  28. package/dist/skills/mdk-site-sizing/scripts/compile-envelope.mjs +45 -0
  29. package/dist/skills/mdk-site-sizing/scripts/eval-held-out.mjs +50 -0
  30. package/dist/skills/mdk-site-sizing/scripts/lib.mjs +591 -0
  31. package/dist/skills/mdk-site-sizing/scripts/parse-site.mjs +25 -0
  32. package/dist/skills/mdk-site-sizing/scripts/size-site.mjs +49 -0
  33. package/dist/skills/mdk-ui-component/SKILL.md +207 -0
  34. package/dist/skills/mdk-ui-component/references/page-recipe.md +78 -0
  35. package/dist/skills/mdk-ui-component/references/ui-registry.json +1 -0
  36. package/dist/skills/mdk-worker-plugin/SKILL.md +198 -0
  37. package/dist/skills/mdk-worker-plugin/assets/mdk-contract.template.json +45 -0
  38. package/dist/skills/mdk-worker-plugin/assets/worker-template/README.md +93 -0
  39. package/dist/skills/mdk-worker-plugin/assets/worker-template/mdk-contract.json +26 -0
  40. package/dist/skills/mdk-worker-plugin/assets/worker-template/mock/server.js +93 -0
  41. package/dist/skills/mdk-worker-plugin/assets/worker-template/package.json +23 -0
  42. package/dist/skills/mdk-worker-plugin/assets/worker-template/smoke.config.js +41 -0
  43. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/client.js +47 -0
  44. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/commands/reboot.js +5 -0
  45. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/commands/set-power-mode.js +10 -0
  46. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/hashrate-rt.js +5 -0
  47. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/power-mode.js +5 -0
  48. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/power.js +5 -0
  49. package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/temperature.js +5 -0
  50. package/dist/skills/mdk-worker-plugin/references/contract-authoring.md +135 -0
  51. package/dist/skills/mdk-worker-plugin/references/device-families.md +96 -0
  52. package/dist/skills/mdk-worker-plugin/references/local-testing.md +134 -0
  53. package/dist/skills/mdk-worker-plugin/references/mdk-contract.schema.json +138 -0
  54. package/dist/skills/mdk-worker-plugin/references/worker-base-api.md +152 -0
  55. package/dist/skills/mdk-worker-plugin/scripts/validate-contract.mjs +129 -0
  56. package/dist/skills/mdk-worker-plugin/scripts/worker-smoke.mjs +256 -0
  57. package/package.json +47 -1
  58. package/src/assemble.mjs +11 -0
  59. package/src/index.d.ts +57 -0
  60. package/src/index.mjs +254 -0
  61. package/src/install.mjs +57 -0
  62. package/src/sources.map.json +34 -0
@@ -0,0 +1,160 @@
1
+ ---
2
+ name: mdk-site-sizing
3
+ description: >
4
+ Size an MDK deployment from a plain description of a site using measured
5
+ benchmark envelopes. Use when the task mentions "size a site", "how many
6
+ Workers", "capacity", "hardware for N miners", "sizing recommendation",
7
+ "deployment envelope", "devices per Worker", or turning benchmark results
8
+ into a Kernel/Worker/Gateway layout.
9
+ metadata:
10
+ suite: mdk-developer-skill
11
+ mdk_version: "0.7.0"
12
+ license: Apache-2.0
13
+ ---
14
+
15
+ # Size an MDK site from a description
16
+
17
+ Measured performance data turned into an Agent Skill that sizes an MDK
18
+ deployment from a plain description of a site. Bar: the Skill's recommendations
19
+ match the measured envelope on a held-out set of site descriptions.
20
+
21
+ Do **not** invent CPU, RAM, devices-per-Worker, or pass/fail status. Parse the
22
+ site, run the sizer, quote the matching envelope.
23
+
24
+ ## When to use
25
+
26
+ | Situation | Action |
27
+ | --------------------------------------------------- | ---------- |
28
+ | "How many Workers for N miners on this host?" | This skill |
29
+ | "Size a site from this description" | This skill |
30
+ | Turn `backend/tests/benchmark/results/*.json` into advice | Compile the envelope, then this skill |
31
+ | Write `mdk.yaml` / `mdk run` after a size is agreed | Hand off to `mdk-deployment` |
32
+ | Measure a new host | Point at the [capacity harness](../../../../../backend/tests/benchmark/README.md); do not guess |
33
+
34
+ ## Workflow
35
+
36
+ Copy this checklist:
37
+
38
+ ```
39
+ Task Progress:
40
+ - [ ] 1. Parse the site description into facts
41
+ - [ ] 2. Run size-site.mjs against the envelope (never skip)
42
+ - [ ] 3. Present the script output as the recommendation
43
+ - [ ] 4. If status is unmeasured or beyond-envelope, stop claiming support
44
+ ```
45
+
46
+ ### 1. Parse
47
+
48
+ Extract facts matching this shape (or run `scripts/parse-site.mjs`):
49
+
50
+ ```json
51
+ {
52
+ "devices": [
53
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "count": 80 }
54
+ ],
55
+ "deviceCount": 80,
56
+ "host": {
57
+ "tier": "edge | site-server | custom",
58
+ "cpuCoresPhysical": 16,
59
+ "ramGiB": 64,
60
+ "diskType": "nvme | sata | hdd | sd"
61
+ },
62
+ "kernels": 1,
63
+ "gateways": 1
64
+ }
65
+ ```
66
+
67
+ Worker `type` values are package names (`mdk-worker-whatsminer`,
68
+ `mdk-worker-antminer`, `mdk-worker-avalon`). Map vendor prose (MicroBT,
69
+ Bitmain, Canaan) onto those names. Default topology is **1 Kernel, 1 Gateway**.
70
+
71
+ If a count or family is missing, leave it null. Do not fill gaps with a guess.
72
+
73
+ ### 2. Size (mandatory)
74
+
75
+ From this skill directory. Never paste the operator's text into a shell
76
+ command (not even inside double quotes: `$( )`, backticks and `"` still
77
+ expand). Write it verbatim to a file with your file-writing tool, then pass the
78
+ file:
79
+
80
+ ```bash
81
+ node scripts/size-site.mjs --description-file site.txt --md
82
+ # or, if you already wrote facts.json:
83
+ node scripts/size-site.mjs facts.json --md
84
+ ```
85
+
86
+ The script reads [`references/envelope.json`](./references/envelope.json) and
87
+ prints the recommendation. That JSON is the measured envelope. Treat its
88
+ `status`, Worker count, devices-per-Worker, and resource numbers as
89
+ authoritative.
90
+
91
+ Rebuild the envelope after a real harness run:
92
+
93
+ ```bash
94
+ node scripts/compile-envelope.mjs --from <repo>/backend/tests/benchmark/results
95
+ ```
96
+
97
+ Without committed harness reports, the envelope is compiled from
98
+ [`eval/profiles/`](./eval/profiles/cap-100devices-2workers.json) (same schema
99
+ as a harness profile). Label any quote from a `source: fixture` envelope as
100
+ fixture data.
101
+
102
+ ### 3. Present
103
+
104
+ Use the script's `--md` output, or the same table it renders: status, tier,
105
+ devices, Workers, devices per Worker, Kernels, Gateways, matching profile,
106
+ RSS, CPU, p99, supported-up-to (densest **green** profile on that mix and
107
+ tier). Repeat the script's caveats verbatim.
108
+
109
+ **Supported** means `status: green` inside the envelope. Amber is "little spare
110
+ capacity", not a supported-up-to bound. `beyond-envelope` and `unmeasured` are
111
+ not sizes: tell the operator to run the harness.
112
+
113
+ ### 4. Hand-off
114
+
115
+ Once the operator accepts a green (or explicit amber) layout, use
116
+ `mdk-deployment` to write `mdk.yaml` with that Worker count and device split.
117
+
118
+ ## Envelope rules (do not override)
119
+
120
+ - Match on device-family set, then reference tier (`edge` / `site-server` /
121
+ `custom`). Custom profiles may fill a tier gap; they do not change the host
122
+ tier you report.
123
+ - Covering profile = smallest profile with `deviceCount >= requested` at the
124
+ best pass/fail (`green` then `amber`). Worker count is
125
+ `ceil(requested / devices-per-Worker)` from that profile.
126
+ - Resource numbers interpolate between the next-smaller green point and the
127
+ covering profile. Do not extrapolate past the last non-red point and call it
128
+ green.
129
+ - Densest green on that mix+tier is `supportedUpTo`. A red profile is a
130
+ measured failure, not a layout to copy.
131
+ - Unknown families (no profile in the envelope) → `unmeasured`.
132
+
133
+ Full compile/lookup notes: [`references/envelope.md`](./references/envelope.md).
134
+
135
+ ## Held-out bar
136
+
137
+ The bar is that the Skill's recommendations match the measured envelope on a
138
+ held-out set of site descriptions. Prove it:
139
+
140
+ ```bash
141
+ node scripts/compile-envelope.mjs
142
+ node scripts/eval-held-out.mjs
143
+ ```
144
+
145
+ [`eval/held-out.json`](./eval/held-out.json) is the held-out set: prose the
146
+ train profiles never use as ids, expected windows read off the envelope.
147
+ `eval-held-out.mjs` parses each description, sizes it, and exits 0 only when
148
+ every case matches. Do not edit expected windows to make a bad recommendation
149
+ pass; fix parse/size or add a measured profile.
150
+
151
+ ## Utility scripts
152
+
153
+ | Script | Run |
154
+ | ---------------------- | ------------------------------------------------------- |
155
+ | `parse-site.mjs` | `node scripts/parse-site.mjs < site.txt` |
156
+ | `size-site.mjs` | `node scripts/size-site.mjs --description-file site.txt [--md]` |
157
+ | `compile-envelope.mjs` | `node scripts/compile-envelope.mjs [--from <dir>]` |
158
+ | `eval-held-out.mjs` | `node scripts/eval-held-out.mjs` |
159
+
160
+ Execute these. Do not reimplement them in the conversation.
@@ -0,0 +1,104 @@
1
+ {
2
+ "bar": "the Skill's recommendations match the measured envelope on a held-out set of site descriptions.",
3
+ "note": "Descriptions are never the profile ids. Expected windows are read off the compiled envelope, not re-authored from the prose.",
4
+ "cases": [
5
+ {
6
+ "id": "edge-ten-whatsminer",
7
+ "description": "A single rack of ten Whatsminer M56S colocated with a small edge box: 4 physical cores, 8 GiB RAM, SATA SSD.",
8
+ "expected": {
9
+ "status": "green",
10
+ "tier": "edge",
11
+ "workerCount": 1,
12
+ "matchingProfileId": "cap-10devices-1workers",
13
+ "supportedUpToDevices": 10,
14
+ "rssSumMiB": 400
15
+ }
16
+ },
17
+ {
18
+ "id": "edge-ten-paraphrase",
19
+ "description": "Small box next to the rack, four cores and 8GB sata, running 10 MicroBT M56S miners.",
20
+ "expected": {
21
+ "status": "green",
22
+ "tier": "edge",
23
+ "workerCount": 1,
24
+ "matchingProfileId": "cap-10devices-1workers"
25
+ }
26
+ },
27
+ {
28
+ "id": "site-server-fifty-microbt",
29
+ "description": "About fifty MicroBT miners on a proper site server: 16 cores, 64 GiB, NVMe.",
30
+ "expected": {
31
+ "status": "green",
32
+ "tier": "site-server",
33
+ "workerCount": 2,
34
+ "matchingProfileId": "cap-50devices-2workers",
35
+ "supportedUpToDevices": 100,
36
+ "rssSumMiB": 800
37
+ }
38
+ },
39
+ {
40
+ "id": "site-server-eighty-interpolated",
41
+ "description": "80 Whatsminer M56S on a 16-core NVMe site-server with 64 GiB RAM.",
42
+ "expected": {
43
+ "status": "green",
44
+ "tier": "site-server",
45
+ "workerCount": 2,
46
+ "matchingProfileId": "cap-100devices-2workers",
47
+ "supportedUpToDevices": 100,
48
+ "rssSumMiB": 1040
49
+ }
50
+ },
51
+ {
52
+ "id": "mixed-sixty-forty",
53
+ "description": "Sixty Whatsminer M56S and forty Antminer S19 XP sharing one 16-core NVMe site server.",
54
+ "expected": {
55
+ "status": "green",
56
+ "tier": "site-server",
57
+ "workerCount": 2,
58
+ "matchingProfileId": "cap-100devices-2workers-mixed",
59
+ "supportedUpToDevices": 100,
60
+ "rssSumMiB": 1300
61
+ }
62
+ },
63
+ {
64
+ "id": "mixed-bench-fifteen",
65
+ "description": "A small mixed fleet like the example bench: ten Whatsminers and five Antminers, 8 cores, 32 GiB, SATA.",
66
+ "expected": {
67
+ "status": "green",
68
+ "tier": "site-server",
69
+ "workerCount": 2,
70
+ "matchingProfileId": "cap-15devices-2workers",
71
+ "rssSumMiB": 500
72
+ }
73
+ },
74
+ {
75
+ "id": "amber-two-hundred",
76
+ "description": "Two hundred Whatsminer M56S on a 16-core NVMe site-server, four worker processes.",
77
+ "expected": {
78
+ "status": "amber",
79
+ "tier": "site-server",
80
+ "workerCount": 4,
81
+ "matchingProfileId": "cap-200devices-4workers",
82
+ "supportedUpToDevices": 100
83
+ }
84
+ },
85
+ {
86
+ "id": "beyond-five-hundred",
87
+ "description": "Five hundred Whatsminer ASICs on one 16-core NVMe site-server.",
88
+ "expected": {
89
+ "status": "beyond-envelope",
90
+ "tier": "site-server",
91
+ "matchingProfileId": "cap-500devices-4workers",
92
+ "supportedUpToDevices": 100
93
+ }
94
+ },
95
+ {
96
+ "id": "unmeasured-avalon",
97
+ "description": "A handful of Avalon miners on an SD-card Raspberry Pi.",
98
+ "expected": {
99
+ "status": "unmeasured",
100
+ "tier": "edge"
101
+ }
102
+ }
103
+ ]
104
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "profileId": "cap-100devices-2workers-mixed",
3
+ "tier": "site-server",
4
+ "hardware": {
5
+ "referenceTier": "site-server",
6
+ "cpuCoresPhysical": 16,
7
+ "cpuCoresLogical": 32,
8
+ "ramGiB": 64,
9
+ "diskType": "nvme"
10
+ },
11
+ "deviceCount": 100,
12
+ "workerCount": 2,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 60 },
15
+ { "type": "mdk-worker-antminer", "model": "s19xp", "deviceCount": 40 }
16
+ ],
17
+ "status": "green",
18
+ "headroomRatio": 0.5,
19
+ "rssSumMiB": 1300,
20
+ "cpuSumPct": 65,
21
+ "readP99Ms": 75,
22
+ "actionP99Ms": 120,
23
+ "source": "fixture"
24
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "profileId": "cap-100devices-2workers",
3
+ "tier": "site-server",
4
+ "hardware": {
5
+ "referenceTier": "site-server",
6
+ "cpuCoresPhysical": 16,
7
+ "cpuCoresLogical": 32,
8
+ "ramGiB": 64,
9
+ "diskType": "nvme"
10
+ },
11
+ "deviceCount": 100,
12
+ "workerCount": 2,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 100 }
15
+ ],
16
+ "status": "green",
17
+ "headroomRatio": 0.55,
18
+ "rssSumMiB": 1200,
19
+ "cpuSumPct": 60,
20
+ "readP99Ms": 70,
21
+ "actionP99Ms": 110,
22
+ "source": "fixture"
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "profileId": "cap-10devices-1workers",
3
+ "tier": "edge",
4
+ "hardware": {
5
+ "referenceTier": "edge",
6
+ "cpuCoresPhysical": 4,
7
+ "cpuCoresLogical": 4,
8
+ "ramGiB": 8,
9
+ "diskType": "sata"
10
+ },
11
+ "deviceCount": 10,
12
+ "workerCount": 1,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 10 }
15
+ ],
16
+ "status": "green",
17
+ "headroomRatio": 0.15,
18
+ "rssSumMiB": 400,
19
+ "cpuSumPct": 20,
20
+ "readP99Ms": 40,
21
+ "actionP99Ms": 70,
22
+ "source": "fixture"
23
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "profileId": "cap-15devices-2workers",
3
+ "tier": "custom",
4
+ "hardware": {
5
+ "referenceTier": "custom",
6
+ "cpuCoresPhysical": 8,
7
+ "cpuCoresLogical": 16,
8
+ "ramGiB": 32,
9
+ "diskType": "sata"
10
+ },
11
+ "deviceCount": 15,
12
+ "workerCount": 2,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 10 },
15
+ { "type": "mdk-worker-antminer", "model": "s19xp", "deviceCount": 5 }
16
+ ],
17
+ "status": "green",
18
+ "headroomRatio": 0.2,
19
+ "rssSumMiB": 500,
20
+ "cpuSumPct": 25,
21
+ "readP99Ms": 50,
22
+ "actionP99Ms": 85,
23
+ "source": "fixture"
24
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "profileId": "cap-200devices-4workers",
3
+ "tier": "site-server",
4
+ "hardware": {
5
+ "referenceTier": "site-server",
6
+ "cpuCoresPhysical": 16,
7
+ "cpuCoresLogical": 32,
8
+ "ramGiB": 64,
9
+ "diskType": "nvme"
10
+ },
11
+ "deviceCount": 200,
12
+ "workerCount": 4,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 200 }
15
+ ],
16
+ "status": "amber",
17
+ "headroomRatio": 0.85,
18
+ "rssSumMiB": 2000,
19
+ "cpuSumPct": 90,
20
+ "readP99Ms": 140,
21
+ "actionP99Ms": 220,
22
+ "source": "fixture"
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "profileId": "cap-500devices-4workers",
3
+ "tier": "site-server",
4
+ "hardware": {
5
+ "referenceTier": "site-server",
6
+ "cpuCoresPhysical": 16,
7
+ "cpuCoresLogical": 32,
8
+ "ramGiB": 64,
9
+ "diskType": "nvme"
10
+ },
11
+ "deviceCount": 500,
12
+ "workerCount": 4,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 500 }
15
+ ],
16
+ "status": "red",
17
+ "headroomRatio": 1.4,
18
+ "rssSumMiB": 4500,
19
+ "cpuSumPct": 180,
20
+ "readP99Ms": 800,
21
+ "actionP99Ms": 2100,
22
+ "source": "fixture"
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "profileId": "cap-50devices-2workers",
3
+ "tier": "site-server",
4
+ "hardware": {
5
+ "referenceTier": "site-server",
6
+ "cpuCoresPhysical": 16,
7
+ "cpuCoresLogical": 32,
8
+ "ramGiB": 64,
9
+ "diskType": "nvme"
10
+ },
11
+ "deviceCount": 50,
12
+ "workerCount": 2,
13
+ "workers": [
14
+ { "type": "mdk-worker-whatsminer", "model": "m56s", "deviceCount": 50 }
15
+ ],
16
+ "status": "green",
17
+ "headroomRatio": 0.35,
18
+ "rssSumMiB": 800,
19
+ "cpuSumPct": 40,
20
+ "readP99Ms": 55,
21
+ "actionP99Ms": 90,
22
+ "source": "fixture"
23
+ }