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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.112.14",
3
+ "version": "2.114.0",
4
4
  "description": "Agent workflow documents and CLI for mustflow repository roots.",
5
5
  "type": "module",
6
6
  "license": "MIT-0",
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 = 24
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: 24
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.
@@ -1,6 +1,6 @@
1
1
  id = "default"
2
2
  name = "default"
3
- version = "2.112.14"
3
+ version = "2.114.0"
4
4
  description = "Minimal workflow for LLM agents to read, edit, and verify their work in a repository."
5
5
  common_root = "common"
6
6
  locales_root = "locales"