mustflow 2.112.14 → 2.114.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.
- package/README.md +2 -0
- package/dist/cli/commands/skill.js +90 -4
- package/dist/cli/lib/command-registry.js +1 -1
- package/dist/cli/lib/external-skill-import.js +649 -5
- package/dist/core/public-json-contracts.js +9 -0
- package/package.json +1 -1
- package/schemas/README.md +4 -0
- package/schemas/skill-import-report.schema.json +75 -0
- package/schemas/skill-update-report.schema.json +256 -0
- package/templates/default/i18n.toml +1 -1
- package/templates/default/locales/en/.mustflow/skills/security-privacy-review/SKILL.md +4 -1
- package/templates/default/manifest.toml +1 -1
|
@@ -685,6 +685,15 @@ const PUBLIC_JSON_SCHEMA_CONTRACTS = [
|
|
|
685
685
|
],
|
|
686
686
|
expectedExitCodes: [0, 1],
|
|
687
687
|
},
|
|
688
|
+
{
|
|
689
|
+
id: 'skill-update-report',
|
|
690
|
+
schemaFile: 'skill-update-report.schema.json',
|
|
691
|
+
producer: 'mf skill outdated --json / mf skill update <skill-name>|--all --json',
|
|
692
|
+
packaged: true,
|
|
693
|
+
documented: true,
|
|
694
|
+
installedCommand: ['mf', 'skill', 'outdated', '--json'],
|
|
695
|
+
expectedExitCodes: [0, 1],
|
|
696
|
+
},
|
|
688
697
|
{
|
|
689
698
|
id: 'route-fixture',
|
|
690
699
|
schemaFile: 'route-fixture.schema.json',
|
package/package.json
CHANGED
package/schemas/README.md
CHANGED
|
@@ -195,6 +195,10 @@ Current schemas:
|
|
|
195
195
|
- `skill-import-report.schema.json`: output of `mf skill import <github-url> --json`, containing
|
|
196
196
|
GitHub source provenance, target `.mustflow/external-skills/<name>/` paths, imported file hashes,
|
|
197
197
|
warnings for inert external scripts, rejection issues, and whether files were written
|
|
198
|
+
- `skill-update-report.schema.json`: output of
|
|
199
|
+
`mf skill outdated --json` and `mf skill update <skill-name>|--all --json`, containing saved
|
|
200
|
+
external-skill provenance, current and remote file hashes, changed-file summaries, local-drift
|
|
201
|
+
rejection issues, script-trust status, last update-check state, and whether skill files were written
|
|
198
202
|
- `route-fixture.schema.json`: parsed `.mustflow/skills/route-fixtures.json`, containing strict
|
|
199
203
|
skill-route golden cases with required and forbidden route expectations
|
|
200
204
|
- `latest-run-pointer.schema.json`: `.mustflow/state/runs/latest.json` when `mf verify` writes a
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"type": "array",
|
|
44
44
|
"items": { "$ref": "#/$defs/file" }
|
|
45
45
|
},
|
|
46
|
+
"script_trust": { "$ref": "#/$defs/scriptTrust" },
|
|
46
47
|
"warnings": {
|
|
47
48
|
"type": "array",
|
|
48
49
|
"items": { "type": "string" }
|
|
@@ -92,6 +93,80 @@
|
|
|
92
93
|
"bytes": { "type": "integer", "minimum": 0 },
|
|
93
94
|
"sha256": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" }
|
|
94
95
|
}
|
|
96
|
+
},
|
|
97
|
+
"scriptTrust": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"additionalProperties": false,
|
|
100
|
+
"required": [
|
|
101
|
+
"requested",
|
|
102
|
+
"status",
|
|
103
|
+
"grants_command_authority",
|
|
104
|
+
"command_contract_path",
|
|
105
|
+
"include_entry",
|
|
106
|
+
"fragment_path",
|
|
107
|
+
"intents"
|
|
108
|
+
],
|
|
109
|
+
"properties": {
|
|
110
|
+
"requested": { "type": "boolean" },
|
|
111
|
+
"status": { "type": "string", "enum": ["not_requested", "no_scripts", "planned", "trusted"] },
|
|
112
|
+
"grants_command_authority": { "type": "boolean" },
|
|
113
|
+
"command_contract_path": {
|
|
114
|
+
"oneOf": [
|
|
115
|
+
{ "const": ".mustflow/config/commands.toml" },
|
|
116
|
+
{ "type": "null" }
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"include_entry": {
|
|
120
|
+
"oneOf": [
|
|
121
|
+
{ "type": "string", "pattern": "^commands/external-skills-[a-z0-9]+(?:-[a-z0-9]+)*\\.toml$" },
|
|
122
|
+
{ "type": "null" }
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"fragment_path": {
|
|
126
|
+
"oneOf": [
|
|
127
|
+
{ "type": "string", "pattern": "^\\.mustflow/config/commands/external-skills-[a-z0-9]+(?:-[a-z0-9]+)*\\.toml$" },
|
|
128
|
+
{ "type": "null" }
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"intents": {
|
|
132
|
+
"type": "array",
|
|
133
|
+
"items": { "$ref": "#/$defs/trustedScriptIntent" }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"trustedScriptIntent": {
|
|
138
|
+
"type": "object",
|
|
139
|
+
"additionalProperties": false,
|
|
140
|
+
"required": [
|
|
141
|
+
"intent",
|
|
142
|
+
"script_path",
|
|
143
|
+
"argv",
|
|
144
|
+
"run_policy",
|
|
145
|
+
"network",
|
|
146
|
+
"destructive",
|
|
147
|
+
"approval_required"
|
|
148
|
+
],
|
|
149
|
+
"properties": {
|
|
150
|
+
"intent": { "type": "string", "pattern": "^external_skill_[A-Za-z0-9_-]+$" },
|
|
151
|
+
"script_path": { "type": "string", "pattern": "^scripts/.+$" },
|
|
152
|
+
"argv": {
|
|
153
|
+
"type": "array",
|
|
154
|
+
"minItems": 2,
|
|
155
|
+
"items": { "type": "string" }
|
|
156
|
+
},
|
|
157
|
+
"run_policy": { "const": "agent_allowed" },
|
|
158
|
+
"network": { "const": true },
|
|
159
|
+
"destructive": { "const": true },
|
|
160
|
+
"approval_required": {
|
|
161
|
+
"type": "array",
|
|
162
|
+
"prefixItems": [
|
|
163
|
+
{ "const": "network_access" },
|
|
164
|
+
{ "const": "destructive_command" }
|
|
165
|
+
],
|
|
166
|
+
"minItems": 2,
|
|
167
|
+
"maxItems": 2
|
|
168
|
+
}
|
|
169
|
+
}
|
|
95
170
|
}
|
|
96
171
|
}
|
|
97
172
|
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mustflow.github.io/schemas/skill-update-report.schema.json",
|
|
4
|
+
"title": "mustflow skill update report",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"kind",
|
|
10
|
+
"command",
|
|
11
|
+
"action",
|
|
12
|
+
"ok",
|
|
13
|
+
"mode",
|
|
14
|
+
"status",
|
|
15
|
+
"check_state",
|
|
16
|
+
"skills",
|
|
17
|
+
"warnings",
|
|
18
|
+
"issues",
|
|
19
|
+
"wrote_files"
|
|
20
|
+
],
|
|
21
|
+
"properties": {
|
|
22
|
+
"schema_version": { "const": "1" },
|
|
23
|
+
"kind": { "const": "skill_update_report" },
|
|
24
|
+
"command": { "const": "skill" },
|
|
25
|
+
"action": { "type": "string", "enum": ["outdated", "update"] },
|
|
26
|
+
"ok": { "type": "boolean" },
|
|
27
|
+
"mode": { "type": "string", "enum": ["check", "dry_run", "install"] },
|
|
28
|
+
"status": { "type": "string", "enum": ["checked", "preview", "updated", "rejected"] },
|
|
29
|
+
"check_state": { "$ref": "#/$defs/checkState" },
|
|
30
|
+
"skills": {
|
|
31
|
+
"type": "array",
|
|
32
|
+
"items": { "$ref": "#/$defs/skill" }
|
|
33
|
+
},
|
|
34
|
+
"warnings": {
|
|
35
|
+
"type": "array",
|
|
36
|
+
"items": { "type": "string" }
|
|
37
|
+
},
|
|
38
|
+
"issues": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"items": { "type": "string" }
|
|
41
|
+
},
|
|
42
|
+
"wrote_files": { "type": "boolean" }
|
|
43
|
+
},
|
|
44
|
+
"$defs": {
|
|
45
|
+
"checkState": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"required": [
|
|
49
|
+
"state_path",
|
|
50
|
+
"stale_after_days",
|
|
51
|
+
"checked_at",
|
|
52
|
+
"previous_checked_at",
|
|
53
|
+
"next_check_due_at",
|
|
54
|
+
"stale_before_command"
|
|
55
|
+
],
|
|
56
|
+
"properties": {
|
|
57
|
+
"state_path": { "const": ".mustflow/state/external-skills/update-check.json" },
|
|
58
|
+
"stale_after_days": { "const": 7 },
|
|
59
|
+
"checked_at": { "type": "string" },
|
|
60
|
+
"previous_checked_at": {
|
|
61
|
+
"oneOf": [
|
|
62
|
+
{ "type": "string" },
|
|
63
|
+
{ "type": "null" }
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"next_check_due_at": { "type": "string" },
|
|
67
|
+
"stale_before_command": { "type": "boolean" }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"skill": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"additionalProperties": false,
|
|
73
|
+
"required": [
|
|
74
|
+
"skill_name",
|
|
75
|
+
"ok",
|
|
76
|
+
"status",
|
|
77
|
+
"source",
|
|
78
|
+
"target",
|
|
79
|
+
"current_files",
|
|
80
|
+
"remote_files",
|
|
81
|
+
"changed_files",
|
|
82
|
+
"warnings",
|
|
83
|
+
"issues",
|
|
84
|
+
"wrote_files"
|
|
85
|
+
],
|
|
86
|
+
"properties": {
|
|
87
|
+
"skill_name": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
|
88
|
+
"ok": { "type": "boolean" },
|
|
89
|
+
"status": { "type": "string", "enum": ["current", "outdated", "updated", "rejected"] },
|
|
90
|
+
"source": {
|
|
91
|
+
"oneOf": [
|
|
92
|
+
{ "$ref": "#/$defs/source" },
|
|
93
|
+
{ "type": "null" }
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
"target": { "$ref": "#/$defs/target" },
|
|
97
|
+
"current_files": {
|
|
98
|
+
"type": "array",
|
|
99
|
+
"items": { "$ref": "#/$defs/file" }
|
|
100
|
+
},
|
|
101
|
+
"remote_files": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"items": { "$ref": "#/$defs/file" }
|
|
104
|
+
},
|
|
105
|
+
"changed_files": {
|
|
106
|
+
"type": "array",
|
|
107
|
+
"items": { "$ref": "#/$defs/fileChange" }
|
|
108
|
+
},
|
|
109
|
+
"script_trust": { "$ref": "#/$defs/scriptTrust" },
|
|
110
|
+
"warnings": {
|
|
111
|
+
"type": "array",
|
|
112
|
+
"items": { "type": "string" }
|
|
113
|
+
},
|
|
114
|
+
"issues": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": { "type": "string" }
|
|
117
|
+
},
|
|
118
|
+
"wrote_files": { "type": "boolean" }
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"source": {
|
|
122
|
+
"type": "object",
|
|
123
|
+
"additionalProperties": false,
|
|
124
|
+
"required": ["input_url", "host", "owner", "repo", "ref", "skill_path", "source_url"],
|
|
125
|
+
"properties": {
|
|
126
|
+
"input_url": { "type": "string" },
|
|
127
|
+
"host": { "type": "string", "enum": ["github.com", "raw.githubusercontent.com"] },
|
|
128
|
+
"owner": { "type": "string" },
|
|
129
|
+
"repo": { "type": "string" },
|
|
130
|
+
"ref": { "type": "string" },
|
|
131
|
+
"skill_path": { "type": "string" },
|
|
132
|
+
"source_url": { "type": "string" }
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"target": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"additionalProperties": false,
|
|
138
|
+
"required": ["root", "skill_name", "skill_dir", "provenance_path"],
|
|
139
|
+
"properties": {
|
|
140
|
+
"root": { "const": ".mustflow/external-skills" },
|
|
141
|
+
"skill_name": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
|
142
|
+
"skill_dir": { "type": "string", "pattern": "^\\.mustflow/external-skills/[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
|
143
|
+
"provenance_path": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"pattern": "^\\.mustflow/external-skills/[a-z0-9]+(?:-[a-z0-9]+)*/mustflow-skill-source\\.json$"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"file": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"additionalProperties": false,
|
|
152
|
+
"required": ["relative_path", "kind", "bytes", "sha256"],
|
|
153
|
+
"properties": {
|
|
154
|
+
"relative_path": { "type": "string" },
|
|
155
|
+
"kind": { "type": "string", "enum": ["skill", "asset", "reference", "script"] },
|
|
156
|
+
"bytes": { "type": "integer", "minimum": 0 },
|
|
157
|
+
"sha256": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" }
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"fileChange": {
|
|
161
|
+
"type": "object",
|
|
162
|
+
"additionalProperties": false,
|
|
163
|
+
"required": ["relative_path", "status", "current_sha256", "remote_sha256"],
|
|
164
|
+
"properties": {
|
|
165
|
+
"relative_path": { "type": "string" },
|
|
166
|
+
"status": { "type": "string", "enum": ["added", "modified", "removed"] },
|
|
167
|
+
"current_sha256": {
|
|
168
|
+
"oneOf": [
|
|
169
|
+
{ "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
|
|
170
|
+
{ "type": "null" }
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
"remote_sha256": {
|
|
174
|
+
"oneOf": [
|
|
175
|
+
{ "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
|
|
176
|
+
{ "type": "null" }
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"scriptTrust": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"additionalProperties": false,
|
|
184
|
+
"required": [
|
|
185
|
+
"requested",
|
|
186
|
+
"status",
|
|
187
|
+
"grants_command_authority",
|
|
188
|
+
"command_contract_path",
|
|
189
|
+
"include_entry",
|
|
190
|
+
"fragment_path",
|
|
191
|
+
"intents"
|
|
192
|
+
],
|
|
193
|
+
"properties": {
|
|
194
|
+
"requested": { "type": "boolean" },
|
|
195
|
+
"status": { "type": "string", "enum": ["not_requested", "no_scripts", "planned", "trusted"] },
|
|
196
|
+
"grants_command_authority": { "type": "boolean" },
|
|
197
|
+
"command_contract_path": {
|
|
198
|
+
"oneOf": [
|
|
199
|
+
{ "const": ".mustflow/config/commands.toml" },
|
|
200
|
+
{ "type": "null" }
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"include_entry": {
|
|
204
|
+
"oneOf": [
|
|
205
|
+
{ "type": "string", "pattern": "^commands/external-skills-[a-z0-9]+(?:-[a-z0-9]+)*\\.toml$" },
|
|
206
|
+
{ "type": "null" }
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
"fragment_path": {
|
|
210
|
+
"oneOf": [
|
|
211
|
+
{ "type": "string", "pattern": "^\\.mustflow/config/commands/external-skills-[a-z0-9]+(?:-[a-z0-9]+)*\\.toml$" },
|
|
212
|
+
{ "type": "null" }
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
"intents": {
|
|
216
|
+
"type": "array",
|
|
217
|
+
"items": { "$ref": "#/$defs/trustedScriptIntent" }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"trustedScriptIntent": {
|
|
222
|
+
"type": "object",
|
|
223
|
+
"additionalProperties": false,
|
|
224
|
+
"required": [
|
|
225
|
+
"intent",
|
|
226
|
+
"script_path",
|
|
227
|
+
"argv",
|
|
228
|
+
"run_policy",
|
|
229
|
+
"network",
|
|
230
|
+
"destructive",
|
|
231
|
+
"approval_required"
|
|
232
|
+
],
|
|
233
|
+
"properties": {
|
|
234
|
+
"intent": { "type": "string", "pattern": "^external_skill_[A-Za-z0-9_-]+$" },
|
|
235
|
+
"script_path": { "type": "string", "pattern": "^scripts/.+$" },
|
|
236
|
+
"argv": {
|
|
237
|
+
"type": "array",
|
|
238
|
+
"minItems": 2,
|
|
239
|
+
"items": { "type": "string" }
|
|
240
|
+
},
|
|
241
|
+
"run_policy": { "const": "agent_allowed" },
|
|
242
|
+
"network": { "const": true },
|
|
243
|
+
"destructive": { "const": true },
|
|
244
|
+
"approval_required": {
|
|
245
|
+
"type": "array",
|
|
246
|
+
"prefixItems": [
|
|
247
|
+
{ "const": "network_access" },
|
|
248
|
+
{ "const": "destructive_command" }
|
|
249
|
+
],
|
|
250
|
+
"minItems": 2,
|
|
251
|
+
"maxItems": 2
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
@@ -1164,7 +1164,7 @@ translations = {}
|
|
|
1164
1164
|
[documents."skill.security-privacy-review"]
|
|
1165
1165
|
source = "locales/en/.mustflow/skills/security-privacy-review/SKILL.md"
|
|
1166
1166
|
source_locale = "en"
|
|
1167
|
-
revision =
|
|
1167
|
+
revision = 25
|
|
1168
1168
|
translations = {}
|
|
1169
1169
|
|
|
1170
1170
|
[documents."skill.security-regression-tests"]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
mustflow_doc: skill.security-privacy-review
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 25
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: security-privacy-review
|
|
@@ -200,6 +200,9 @@ Catch security, privacy, and disclosure risks introduced by ordinary code, docum
|
|
|
200
200
|
35. For pinned action references, distinguish tag objects from the commit that implements the tag. Verify pinned SHAs against the action repository so scanner tooling does not report an imposter or non-member commit.
|
|
201
201
|
36. For dependency scanner alerts, separate production dependency manifests from fixtures, examples, generated test repositories, and intentionally vulnerable samples. Narrow the scan scope before treating fixture-only alerts as product vulnerabilities.
|
|
202
202
|
- For lockfile CVEs, inspect the manifest and lockfile together. Identify the direct parent that keeps the vulnerable transitive package in the graph, update the narrowest direct dependency or override needed to reach the fixed range, and confirm the vulnerable package version no longer appears in the resolved graph before claiming the alert is fixed.
|
|
203
|
+
- For object merge, defaulting, or configuration merge advisories, trace whether parsed request bodies, database records, uploaded JSON, repository config, or provider payloads can become the first or highest-priority merge input. Treat `__proto__`, `constructor`, and `prototype` keys, inherited polluted values, and default-overwrite behavior as prototype-pollution sinks; prove the patched dependency is resolved or add a regression payload that cannot override trusted defaults.
|
|
204
|
+
- For ORM or SQL-builder advisories around identifiers, aliases, dynamic sorting, report columns, CTE names, or `.as()`-style APIs, remember that value parameter binding does not protect identifier positions. Runtime input must map through an allowlist of known columns or aliases, and dialect quote delimiters inside identifiers must be escaped by the library before the identifier is wrapped.
|
|
205
|
+
- For serializer or deserializer advisories, treat sparse arrays, giant indexes, deep objects, cyclic references, and attacker-controlled serialized payloads as allocation and CPU sinks. Bound serialized size, array length or highest index, nesting depth, and parse source trust before claiming a parser-only upgrade removes the availability risk.
|
|
203
206
|
- For advisories involving development tools such as Vite, Vitest UI, browser-mode test servers, Storybook, docs preview, asset servers, or framework dev servers, do not dismiss the issue merely because the package is a devDependency. Check whether scripts, docs, Docker, Codespaces, CI previews, tunnels, or config bind the server to a non-localhost host, widen file-serving roots, disable deny lists, or expose privileged read, write, rerun, snapshot, attachment, or execute APIs.
|
|
204
207
|
37. For deployment settings, check debug mode, sample admin accounts, default credentials, public admin panels, open metrics endpoints, public storage, root container users, HTTPS enforcement, and exposed GraphQL or development consoles.
|
|
205
208
|
38. For runtime and framework security updates, check that supported versions are documented, end-of-life versions are rejected, dependency locks exist where appropriate, security patches can be tested and deployed quickly, and rollback or redeploy can happen without manual dashboard memory. Do not treat a fashionable or high-performance runtime as safe unless the patch path is operationally credible.
|