mustflow 2.103.3 → 2.103.12
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/dist/cli/commands/run.js +11 -0
- package/dist/cli/commands/script-pack.js +2 -0
- package/dist/cli/i18n/en.js +35 -0
- package/dist/cli/i18n/es.js +35 -0
- package/dist/cli/i18n/fr.js +35 -0
- package/dist/cli/i18n/hi.js +35 -0
- package/dist/cli/i18n/ko.js +35 -0
- package/dist/cli/i18n/zh.js +35 -0
- package/dist/cli/lib/external-skill-import.js +78 -14
- package/dist/cli/lib/local-index/sql.js +9 -1
- package/dist/cli/lib/run-plan.js +37 -0
- package/dist/cli/lib/script-pack-registry.js +57 -0
- package/dist/cli/script-packs/repo-deploy-surface.js +98 -0
- package/dist/cli/script-packs/repo-security-pattern-scan.js +150 -0
- package/dist/core/change-impact.js +16 -0
- package/dist/core/code-outline.js +3 -13
- package/dist/core/command-env.js +26 -8
- package/dist/core/config-chain.js +3 -13
- package/dist/core/dependency-graph.js +3 -13
- package/dist/core/docs-link-integrity.js +23 -4
- package/dist/core/env-contract.js +3 -13
- package/dist/core/export-diff.js +3 -3
- package/dist/core/ignored-directories.js +40 -0
- package/dist/core/public-json-contracts.js +18 -0
- package/dist/core/reference-drift.js +4 -2
- package/dist/core/related-files.js +3 -13
- package/dist/core/repo-deploy-surface.js +428 -0
- package/dist/core/repo-merge-conflict-scan.js +3 -9
- package/dist/core/route-outline.js +3 -13
- package/dist/core/script-pack-suggestions.js +52 -14
- package/dist/core/secret-risk-scan.js +3 -13
- package/dist/core/security-pattern-scan.js +518 -0
- package/dist/core/skill-route-resolution.js +21 -1
- package/package.json +2 -2
- package/schemas/README.md +7 -0
- package/schemas/link-integrity-report.schema.json +1 -0
- package/schemas/reference-drift-report.schema.json +1 -0
- package/schemas/repo-deploy-surface-report.schema.json +190 -0
- package/schemas/security-pattern-scan-report.schema.json +196 -0
- package/templates/default/i18n.toml +20 -8
- package/templates/default/locales/en/.mustflow/skills/ai-generated-code-hardening/SKILL.md +30 -7
- package/templates/default/locales/en/.mustflow/skills/api-contract-change/SKILL.md +18 -9
- package/templates/default/locales/en/.mustflow/skills/api-request-performance-review/SKILL.md +12 -6
- package/templates/default/locales/en/.mustflow/skills/completion-evidence-gate/SKILL.md +20 -9
- package/templates/default/locales/en/.mustflow/skills/hot-path-performance-review/SKILL.md +20 -15
- package/templates/default/locales/en/.mustflow/skills/next-action-menu/SKILL.md +22 -7
- package/templates/default/locales/en/.mustflow/skills/quadratic-scan-review/SKILL.md +21 -19
- package/templates/default/locales/en/.mustflow/skills/react-code-change/SKILL.md +54 -8
- package/templates/default/locales/en/.mustflow/skills/vertical-slice-tdd/SKILL.md +22 -8
- package/templates/default/manifest.toml +1 -1
|
@@ -8,6 +8,7 @@ const SKILL_ROUTER_PATH = '.mustflow/skills/router.toml';
|
|
|
8
8
|
const SKILL_ROUTES_METADATA_PATH = '.mustflow/skills/routes.toml';
|
|
9
9
|
const SKILL_FRONTMATTER_SOURCE = '.mustflow/skills/*/SKILL.md';
|
|
10
10
|
const EXTERNAL_SKILL_FRONTMATTER_SOURCE = '.mustflow/external-skills/*/SKILL.md';
|
|
11
|
+
const EXTERNAL_SKILL_PROVENANCE_FILE = 'mustflow-skill-source.json';
|
|
11
12
|
const DEFAULT_MAX_CANDIDATES = 5;
|
|
12
13
|
const DEFAULT_MAX_MAIN = 1;
|
|
13
14
|
const DEFAULT_MAX_ADJUNCTS = 2;
|
|
@@ -214,6 +215,25 @@ function readSkillFrontmatterRoutes(projectRoot) {
|
|
|
214
215
|
}
|
|
215
216
|
return routes;
|
|
216
217
|
}
|
|
218
|
+
function hasValidExternalSkillProvenance(projectRoot, skillDirectory) {
|
|
219
|
+
const provenancePath = path.join(projectRoot, '.mustflow', 'external-skills', skillDirectory, EXTERNAL_SKILL_PROVENANCE_FILE);
|
|
220
|
+
if (!existsSync(provenancePath)) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const content = readUtf8FileInsideWithoutSymlinks(projectRoot, provenancePath, {
|
|
225
|
+
maxBytes: MUSTFLOW_TEXT_MAX_BYTES,
|
|
226
|
+
});
|
|
227
|
+
const parsed = JSON.parse(content);
|
|
228
|
+
return (isRecord(parsed) &&
|
|
229
|
+
parsed.schema_version === '1' &&
|
|
230
|
+
parsed.kind === 'external_skill_source' &&
|
|
231
|
+
isRecord(parsed.source));
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
217
237
|
function readExternalSkillFrontmatterRoutes(projectRoot) {
|
|
218
238
|
const skillRoot = path.join(projectRoot, '.mustflow', 'external-skills');
|
|
219
239
|
if (!existsSync(skillRoot)) {
|
|
@@ -227,7 +247,7 @@ function readExternalSkillFrontmatterRoutes(projectRoot) {
|
|
|
227
247
|
for (const skillDirectory of skillDirectories) {
|
|
228
248
|
const skillPath = `.mustflow/external-skills/${skillDirectory}/SKILL.md`;
|
|
229
249
|
const absoluteSkillPath = path.join(projectRoot, ...skillPath.split('/'));
|
|
230
|
-
if (!existsSync(absoluteSkillPath)) {
|
|
250
|
+
if (!existsSync(absoluteSkillPath) || !hasValidExternalSkillProvenance(projectRoot, skillDirectory)) {
|
|
231
251
|
continue;
|
|
232
252
|
}
|
|
233
253
|
const content = readUtf8FileInsideWithoutSymlinks(projectRoot, absoluteSkillPath, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mustflow",
|
|
3
|
-
"version": "2.103.
|
|
3
|
+
"version": "2.103.12",
|
|
4
4
|
"description": "Agent workflow documents and CLI for mustflow repository roots.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT-0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"check:package": "node -e \"const fs=require('fs'); JSON.parse(fs.readFileSync('package.json','utf8')); console.log('package.json ok')\"",
|
|
48
48
|
"check:typecheck": "tsc -p tsconfig.json --noEmit",
|
|
49
49
|
"prepack": "npm run build",
|
|
50
|
-
"check:pack": "npm pack --dry-run --json",
|
|
50
|
+
"check:pack": "npm pack --dry-run --json --ignore-scripts",
|
|
51
51
|
"check:install": "npm run check:pack && node --test tests/integration/*.test.js",
|
|
52
52
|
"release:check": "npm run check && npm run docs:check && npm run check:install",
|
|
53
53
|
"prepublishOnly": "npm run release:check",
|
package/schemas/README.md
CHANGED
|
@@ -124,6 +124,10 @@ Current schemas:
|
|
|
124
124
|
`mf script-pack run repo/secret-risk-scan scan [path...] --json`, containing plausible
|
|
125
125
|
hardcoded-secret findings with detector names, paths, line numbers, and redacted fingerprints
|
|
126
126
|
without printing secret values
|
|
127
|
+
- `security-pattern-scan-report.schema.json`: output of
|
|
128
|
+
`mf script-pack run repo/security-pattern-scan scan [path...] --json`, containing high-signal
|
|
129
|
+
security code-pattern leads with detector names, categories, paths, line numbers, review focus,
|
|
130
|
+
and redacted fingerprints without printing matched source lines or secret values
|
|
127
131
|
- `text-budget-report.schema.json`: output of
|
|
128
132
|
`mf script-pack run core/text-budget check <path...> --json`, containing
|
|
129
133
|
exact text-budget metrics, input content hashes, policy metadata, findings, and JSON Pointer field
|
|
@@ -152,6 +156,9 @@ Current schemas:
|
|
|
152
156
|
- `repo-approval-gate-report.schema.json`: output of
|
|
153
157
|
`mf script-pack run repo/approval-gate check --action <type> --json`, containing approval policy
|
|
154
158
|
decisions, required-action findings, and unreadable policy issues
|
|
159
|
+
- `repo-deploy-surface-report.schema.json`: output of
|
|
160
|
+
`mf script-pack run repo/deploy-surface inspect --json`, containing detected local deploy and
|
|
161
|
+
release surfaces, trigger evidence, required verification, and manual gates
|
|
155
162
|
- `related-files-report.schema.json`: output of
|
|
156
163
|
`mf script-pack run repo/related-files map <path...> --json`, containing conservative related-file
|
|
157
164
|
candidates from direct imports, importers, same-basename siblings, parent configuration files, and
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"max_file_bytes": { "type": "integer", "minimum": 1 },
|
|
87
87
|
"default_paths": { "$ref": "#/$defs/stringArray" },
|
|
88
88
|
"path_filters": { "$ref": "#/$defs/stringArray" },
|
|
89
|
+
"ignored_directories": { "$ref": "#/$defs/stringArray" },
|
|
89
90
|
"checked_link_kinds": {
|
|
90
91
|
"type": "array",
|
|
91
92
|
"items": { "$ref": "#/$defs/linkKind" }
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"max_file_bytes": { "type": "integer", "minimum": 1 },
|
|
87
87
|
"default_paths": { "$ref": "#/$defs/stringArray" },
|
|
88
88
|
"path_filters": { "$ref": "#/$defs/stringArray" },
|
|
89
|
+
"ignored_directories": { "$ref": "#/$defs/stringArray" },
|
|
89
90
|
"checked_reference_kinds": {
|
|
90
91
|
"type": "array",
|
|
91
92
|
"items": { "$ref": "#/$defs/referenceKind" }
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mustflow.github.io/schemas/repo-deploy-surface-report.schema.json",
|
|
4
|
+
"title": "mustflow repo deploy-surface report",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"command",
|
|
10
|
+
"pack_id",
|
|
11
|
+
"script_id",
|
|
12
|
+
"script_ref",
|
|
13
|
+
"action",
|
|
14
|
+
"status",
|
|
15
|
+
"ok",
|
|
16
|
+
"mustflow_root",
|
|
17
|
+
"input",
|
|
18
|
+
"input_hash",
|
|
19
|
+
"has_deploy_surface",
|
|
20
|
+
"summary",
|
|
21
|
+
"surfaces",
|
|
22
|
+
"required_verification",
|
|
23
|
+
"manual_gates",
|
|
24
|
+
"findings",
|
|
25
|
+
"issues"
|
|
26
|
+
],
|
|
27
|
+
"properties": {
|
|
28
|
+
"schema_version": { "const": "1" },
|
|
29
|
+
"command": { "const": "script-pack" },
|
|
30
|
+
"pack_id": { "const": "repo" },
|
|
31
|
+
"script_id": { "const": "deploy-surface" },
|
|
32
|
+
"script_ref": { "const": "repo/deploy-surface" },
|
|
33
|
+
"action": { "const": "inspect" },
|
|
34
|
+
"status": { "enum": ["passed", "failed", "error"] },
|
|
35
|
+
"ok": { "type": "boolean" },
|
|
36
|
+
"mustflow_root": { "type": "string" },
|
|
37
|
+
"input": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": ["scanned_paths", "max_file_bytes"],
|
|
41
|
+
"properties": {
|
|
42
|
+
"scanned_paths": {
|
|
43
|
+
"type": "array",
|
|
44
|
+
"items": { "type": "string", "minLength": 1 }
|
|
45
|
+
},
|
|
46
|
+
"max_file_bytes": { "type": "integer", "minimum": 1 }
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"input_hash": { "$ref": "#/$defs/sha256" },
|
|
50
|
+
"has_deploy_surface": { "type": "boolean" },
|
|
51
|
+
"summary": { "$ref": "#/$defs/summary" },
|
|
52
|
+
"surfaces": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": { "$ref": "#/$defs/surface" }
|
|
55
|
+
},
|
|
56
|
+
"required_verification": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": { "type": "string", "minLength": 1 }
|
|
59
|
+
},
|
|
60
|
+
"manual_gates": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"items": { "type": "string", "minLength": 1 }
|
|
63
|
+
},
|
|
64
|
+
"findings": {
|
|
65
|
+
"type": "array",
|
|
66
|
+
"items": { "$ref": "#/$defs/finding" }
|
|
67
|
+
},
|
|
68
|
+
"issues": {
|
|
69
|
+
"type": "array",
|
|
70
|
+
"items": { "type": "string" }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"$defs": {
|
|
74
|
+
"sha256": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"pattern": "^sha256:[a-f0-9]{64}$"
|
|
77
|
+
},
|
|
78
|
+
"summary": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"required": [
|
|
82
|
+
"has_deploy_surface",
|
|
83
|
+
"surface_count",
|
|
84
|
+
"workflow_count",
|
|
85
|
+
"package_script_count",
|
|
86
|
+
"config_file_count",
|
|
87
|
+
"package_metadata_count",
|
|
88
|
+
"manual_gate_count",
|
|
89
|
+
"required_verification_count"
|
|
90
|
+
],
|
|
91
|
+
"properties": {
|
|
92
|
+
"has_deploy_surface": { "type": "boolean" },
|
|
93
|
+
"surface_count": { "type": "integer", "minimum": 0 },
|
|
94
|
+
"workflow_count": { "type": "integer", "minimum": 0 },
|
|
95
|
+
"package_script_count": { "type": "integer", "minimum": 0 },
|
|
96
|
+
"config_file_count": { "type": "integer", "minimum": 0 },
|
|
97
|
+
"package_metadata_count": { "type": "integer", "minimum": 0 },
|
|
98
|
+
"manual_gate_count": { "type": "integer", "minimum": 0 },
|
|
99
|
+
"required_verification_count": { "type": "integer", "minimum": 0 }
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"surface": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"additionalProperties": false,
|
|
105
|
+
"required": [
|
|
106
|
+
"id",
|
|
107
|
+
"kind",
|
|
108
|
+
"surface_type",
|
|
109
|
+
"path",
|
|
110
|
+
"line",
|
|
111
|
+
"trigger",
|
|
112
|
+
"confidence",
|
|
113
|
+
"evidence",
|
|
114
|
+
"required_verification",
|
|
115
|
+
"manual_gates"
|
|
116
|
+
],
|
|
117
|
+
"properties": {
|
|
118
|
+
"id": { "type": "string", "minLength": 1 },
|
|
119
|
+
"kind": {
|
|
120
|
+
"enum": [
|
|
121
|
+
"deploy_config",
|
|
122
|
+
"github_actions_workflow",
|
|
123
|
+
"package_metadata",
|
|
124
|
+
"package_script"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"surface_type": {
|
|
128
|
+
"enum": [
|
|
129
|
+
"cloudflare",
|
|
130
|
+
"container",
|
|
131
|
+
"generic_deploy",
|
|
132
|
+
"github_pages",
|
|
133
|
+
"github_release",
|
|
134
|
+
"netlify",
|
|
135
|
+
"npm_publish",
|
|
136
|
+
"package_release",
|
|
137
|
+
"vercel"
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
"path": { "type": "string", "minLength": 1 },
|
|
141
|
+
"line": { "type": ["integer", "null"], "minimum": 1 },
|
|
142
|
+
"trigger": { "type": ["string", "null"] },
|
|
143
|
+
"confidence": { "enum": ["low", "medium", "high"] },
|
|
144
|
+
"evidence": { "$ref": "#/$defs/evidence" },
|
|
145
|
+
"required_verification": {
|
|
146
|
+
"type": "array",
|
|
147
|
+
"items": { "type": "string", "minLength": 1 }
|
|
148
|
+
},
|
|
149
|
+
"manual_gates": {
|
|
150
|
+
"type": "array",
|
|
151
|
+
"items": { "type": "string", "minLength": 1 }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"evidence": {
|
|
156
|
+
"type": "object",
|
|
157
|
+
"additionalProperties": false,
|
|
158
|
+
"required": ["path", "line", "match"],
|
|
159
|
+
"properties": {
|
|
160
|
+
"path": { "type": "string", "minLength": 1 },
|
|
161
|
+
"line": { "type": ["integer", "null"], "minimum": 1 },
|
|
162
|
+
"match": { "type": "string", "minLength": 1 }
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"finding": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"required": [
|
|
169
|
+
"code",
|
|
170
|
+
"severity",
|
|
171
|
+
"message",
|
|
172
|
+
"path",
|
|
173
|
+
"json_pointer",
|
|
174
|
+
"metric",
|
|
175
|
+
"actual",
|
|
176
|
+
"expected"
|
|
177
|
+
],
|
|
178
|
+
"properties": {
|
|
179
|
+
"code": { "const": "deploy_surface_detected" },
|
|
180
|
+
"severity": { "enum": ["low", "medium", "high", "critical"] },
|
|
181
|
+
"message": { "type": "string" },
|
|
182
|
+
"path": { "type": "string", "minLength": 1 },
|
|
183
|
+
"json_pointer": { "type": ["string", "null"] },
|
|
184
|
+
"metric": { "type": ["string", "null"] },
|
|
185
|
+
"actual": { "type": ["number", "null"] },
|
|
186
|
+
"expected": { "type": ["number", "null"] }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mustflow.github.io/schemas/security-pattern-scan-report.schema.json",
|
|
4
|
+
"title": "mustflow security-pattern-scan report",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"command",
|
|
10
|
+
"pack_id",
|
|
11
|
+
"script_id",
|
|
12
|
+
"script_ref",
|
|
13
|
+
"action",
|
|
14
|
+
"status",
|
|
15
|
+
"ok",
|
|
16
|
+
"mustflow_root",
|
|
17
|
+
"policy",
|
|
18
|
+
"input_hash",
|
|
19
|
+
"targets",
|
|
20
|
+
"summary",
|
|
21
|
+
"truncated",
|
|
22
|
+
"findings",
|
|
23
|
+
"issues"
|
|
24
|
+
],
|
|
25
|
+
"properties": {
|
|
26
|
+
"schema_version": { "const": "1" },
|
|
27
|
+
"command": { "const": "script-pack" },
|
|
28
|
+
"pack_id": { "const": "repo" },
|
|
29
|
+
"script_id": { "const": "security-pattern-scan" },
|
|
30
|
+
"script_ref": { "const": "repo/security-pattern-scan" },
|
|
31
|
+
"action": { "const": "scan" },
|
|
32
|
+
"status": { "enum": ["passed", "failed", "error"] },
|
|
33
|
+
"ok": { "type": "boolean" },
|
|
34
|
+
"mustflow_root": { "type": "string" },
|
|
35
|
+
"policy": { "$ref": "#/$defs/policy" },
|
|
36
|
+
"input_hash": { "$ref": "#/$defs/sha256" },
|
|
37
|
+
"targets": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": { "$ref": "#/$defs/target" }
|
|
40
|
+
},
|
|
41
|
+
"summary": { "$ref": "#/$defs/summary" },
|
|
42
|
+
"truncated": { "type": "boolean" },
|
|
43
|
+
"findings": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"items": { "$ref": "#/$defs/finding" }
|
|
46
|
+
},
|
|
47
|
+
"issues": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": { "type": "string" }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"$defs": {
|
|
53
|
+
"sha256": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"pattern": "^sha256:[a-f0-9]{64}$"
|
|
56
|
+
},
|
|
57
|
+
"fingerprint": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"pattern": "^sha256:[a-f0-9]{16}$"
|
|
60
|
+
},
|
|
61
|
+
"stringArray": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": { "type": "string" }
|
|
64
|
+
},
|
|
65
|
+
"policy": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"additionalProperties": false,
|
|
68
|
+
"required": [
|
|
69
|
+
"max_file_bytes",
|
|
70
|
+
"max_files",
|
|
71
|
+
"max_findings",
|
|
72
|
+
"extensions",
|
|
73
|
+
"ignored_directories",
|
|
74
|
+
"evidence_mode"
|
|
75
|
+
],
|
|
76
|
+
"properties": {
|
|
77
|
+
"max_file_bytes": { "type": "integer", "minimum": 1 },
|
|
78
|
+
"max_files": { "type": "integer", "minimum": 1 },
|
|
79
|
+
"max_findings": { "type": "integer", "minimum": 1 },
|
|
80
|
+
"extensions": { "$ref": "#/$defs/stringArray" },
|
|
81
|
+
"ignored_directories": { "$ref": "#/$defs/stringArray" },
|
|
82
|
+
"evidence_mode": { "const": "metadata_only" }
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"target": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"required": ["input", "path", "exists", "kind"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"input": { "type": "string" },
|
|
91
|
+
"path": { "type": "string" },
|
|
92
|
+
"exists": { "type": ["boolean", "null"] },
|
|
93
|
+
"kind": { "enum": ["file", "directory", "missing", "other", "unknown"] }
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"summary": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"additionalProperties": false,
|
|
99
|
+
"required": [
|
|
100
|
+
"target_count",
|
|
101
|
+
"file_count",
|
|
102
|
+
"finding_count",
|
|
103
|
+
"high_or_critical_count",
|
|
104
|
+
"category_count"
|
|
105
|
+
],
|
|
106
|
+
"properties": {
|
|
107
|
+
"target_count": { "type": "integer", "minimum": 0 },
|
|
108
|
+
"file_count": { "type": "integer", "minimum": 0 },
|
|
109
|
+
"finding_count": { "type": "integer", "minimum": 0 },
|
|
110
|
+
"high_or_critical_count": { "type": "integer", "minimum": 0 },
|
|
111
|
+
"category_count": { "type": "integer", "minimum": 0 }
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"detector": {
|
|
115
|
+
"enum": [
|
|
116
|
+
"client_controlled_authority",
|
|
117
|
+
"cors_origin_reflection_with_credentials",
|
|
118
|
+
"dynamic_regex",
|
|
119
|
+
"eval_execution",
|
|
120
|
+
"fs_call_non_literal_path",
|
|
121
|
+
"insecure_cookie_options",
|
|
122
|
+
"local_storage_token",
|
|
123
|
+
"mass_assignment",
|
|
124
|
+
"native_deserialization",
|
|
125
|
+
"path_join_user_input",
|
|
126
|
+
"postmessage_missing_origin_check",
|
|
127
|
+
"postmessage_wildcard_target",
|
|
128
|
+
"raw_sensitive_request_logging",
|
|
129
|
+
"server_fetch_user_url",
|
|
130
|
+
"shell_true",
|
|
131
|
+
"sql_template_interpolation",
|
|
132
|
+
"tls_verification_disabled",
|
|
133
|
+
"unsafe_yaml_load"
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"category": {
|
|
137
|
+
"enum": [
|
|
138
|
+
"access_control",
|
|
139
|
+
"browser",
|
|
140
|
+
"command",
|
|
141
|
+
"crypto_transport",
|
|
142
|
+
"filesystem",
|
|
143
|
+
"injection",
|
|
144
|
+
"logging",
|
|
145
|
+
"parser",
|
|
146
|
+
"token_session"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"finding": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"additionalProperties": false,
|
|
152
|
+
"required": ["code", "severity", "message", "path"],
|
|
153
|
+
"properties": {
|
|
154
|
+
"code": {
|
|
155
|
+
"enum": [
|
|
156
|
+
"security_pattern_client_controlled_authority",
|
|
157
|
+
"security_pattern_cors_origin_reflection_with_credentials",
|
|
158
|
+
"security_pattern_dynamic_regex",
|
|
159
|
+
"security_pattern_eval_execution",
|
|
160
|
+
"security_pattern_file_too_large",
|
|
161
|
+
"security_pattern_fs_call_non_literal_path",
|
|
162
|
+
"security_pattern_insecure_cookie_options",
|
|
163
|
+
"security_pattern_local_storage_token",
|
|
164
|
+
"security_pattern_mass_assignment",
|
|
165
|
+
"security_pattern_max_files_exceeded",
|
|
166
|
+
"security_pattern_max_findings_exceeded",
|
|
167
|
+
"security_pattern_native_deserialization",
|
|
168
|
+
"security_pattern_path_join_user_input",
|
|
169
|
+
"security_pattern_path_outside_root",
|
|
170
|
+
"security_pattern_postmessage_missing_origin_check",
|
|
171
|
+
"security_pattern_postmessage_wildcard_target",
|
|
172
|
+
"security_pattern_raw_sensitive_request_logging",
|
|
173
|
+
"security_pattern_server_fetch_user_url",
|
|
174
|
+
"security_pattern_shell_true",
|
|
175
|
+
"security_pattern_sql_template_interpolation",
|
|
176
|
+
"security_pattern_tls_verification_disabled",
|
|
177
|
+
"security_pattern_unreadable_path",
|
|
178
|
+
"security_pattern_unsafe_yaml_load"
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"severity": { "enum": ["low", "medium", "high", "critical"] },
|
|
182
|
+
"message": { "type": "string" },
|
|
183
|
+
"path": { "type": "string" },
|
|
184
|
+
"line": { "type": "integer", "minimum": 1 },
|
|
185
|
+
"detector": { "$ref": "#/$defs/detector" },
|
|
186
|
+
"category": { "$ref": "#/$defs/category" },
|
|
187
|
+
"review_focus": { "type": "string" },
|
|
188
|
+
"fingerprint": { "$ref": "#/$defs/fingerprint" },
|
|
189
|
+
"json_pointer": { "type": ["string", "null"] },
|
|
190
|
+
"metric": { "type": ["string", "null"] },
|
|
191
|
+
"actual": { "type": ["number", "null"] },
|
|
192
|
+
"expected": { "type": ["number", "null"] }
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -86,7 +86,7 @@ translations = {}
|
|
|
86
86
|
[documents."skill.api-contract-change"]
|
|
87
87
|
source = "locales/en/.mustflow/skills/api-contract-change/SKILL.md"
|
|
88
88
|
source_locale = "en"
|
|
89
|
-
revision =
|
|
89
|
+
revision = 3
|
|
90
90
|
translations = {}
|
|
91
91
|
|
|
92
92
|
[documents."skill.backend-reliability-change"]
|
|
@@ -116,7 +116,7 @@ translations = {}
|
|
|
116
116
|
[documents."skill.ai-generated-code-hardening"]
|
|
117
117
|
source = "locales/en/.mustflow/skills/ai-generated-code-hardening/SKILL.md"
|
|
118
118
|
source_locale = "en"
|
|
119
|
-
revision =
|
|
119
|
+
revision = 3
|
|
120
120
|
translations = {}
|
|
121
121
|
|
|
122
122
|
[documents."skill.quality-gaming-guard"]
|
|
@@ -194,13 +194,13 @@ translations = {}
|
|
|
194
194
|
[documents."skill.hot-path-performance-review"]
|
|
195
195
|
source = "locales/en/.mustflow/skills/hot-path-performance-review/SKILL.md"
|
|
196
196
|
source_locale = "en"
|
|
197
|
-
revision =
|
|
197
|
+
revision = 2
|
|
198
198
|
translations = {}
|
|
199
199
|
|
|
200
200
|
[documents."skill.api-request-performance-review"]
|
|
201
201
|
source = "locales/en/.mustflow/skills/api-request-performance-review/SKILL.md"
|
|
202
202
|
source_locale = "en"
|
|
203
|
-
revision =
|
|
203
|
+
revision = 2
|
|
204
204
|
translations = {}
|
|
205
205
|
|
|
206
206
|
[documents."skill.api-failure-triage"]
|
|
@@ -326,7 +326,7 @@ translations = {}
|
|
|
326
326
|
[documents."skill.quadratic-scan-review"]
|
|
327
327
|
source = "locales/en/.mustflow/skills/quadratic-scan-review/SKILL.md"
|
|
328
328
|
source_locale = "en"
|
|
329
|
-
revision =
|
|
329
|
+
revision = 2
|
|
330
330
|
translations = {}
|
|
331
331
|
|
|
332
332
|
[documents."skill.type-state-modeling-review"]
|
|
@@ -568,6 +568,12 @@ source_locale = "en"
|
|
|
568
568
|
revision = 1
|
|
569
569
|
translations = {}
|
|
570
570
|
|
|
571
|
+
[documents."skill.idea-triage"]
|
|
572
|
+
source = "locales/en/.mustflow/skills/idea-triage/SKILL.md"
|
|
573
|
+
source_locale = "en"
|
|
574
|
+
revision = 1
|
|
575
|
+
translations = {}
|
|
576
|
+
|
|
571
577
|
[documents."skill.astro-code-change"]
|
|
572
578
|
source = "locales/en/.mustflow/skills/astro-code-change/SKILL.md"
|
|
573
579
|
source_locale = "en"
|
|
@@ -673,7 +679,7 @@ translations = {}
|
|
|
673
679
|
[documents."skill.react-code-change"]
|
|
674
680
|
source = "locales/en/.mustflow/skills/react-code-change/SKILL.md"
|
|
675
681
|
source_locale = "en"
|
|
676
|
-
revision =
|
|
682
|
+
revision = 2
|
|
677
683
|
translations = {}
|
|
678
684
|
|
|
679
685
|
[documents."skill.python-code-change"]
|
|
@@ -769,7 +775,13 @@ translations = {}
|
|
|
769
775
|
[documents."skill.completion-evidence-gate"]
|
|
770
776
|
source = "locales/en/.mustflow/skills/completion-evidence-gate/SKILL.md"
|
|
771
777
|
source_locale = "en"
|
|
772
|
-
revision =
|
|
778
|
+
revision = 5
|
|
779
|
+
translations = {}
|
|
780
|
+
|
|
781
|
+
[documents."skill.next-action-menu"]
|
|
782
|
+
source = "locales/en/.mustflow/skills/next-action-menu/SKILL.md"
|
|
783
|
+
source_locale = "en"
|
|
784
|
+
revision = 3
|
|
773
785
|
translations = {}
|
|
774
786
|
|
|
775
787
|
[documents."skill.evidence-stall-breaker"]
|
|
@@ -1080,7 +1092,7 @@ translations = {}
|
|
|
1080
1092
|
[documents."skill.vertical-slice-tdd"]
|
|
1081
1093
|
source = "locales/en/.mustflow/skills/vertical-slice-tdd/SKILL.md"
|
|
1082
1094
|
source_locale = "en"
|
|
1083
|
-
revision =
|
|
1095
|
+
revision = 2
|
|
1084
1096
|
translations = {}
|
|
1085
1097
|
|
|
1086
1098
|
[documents."skill.llm-service-ux-review"]
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
mustflow_doc: skill.ai-generated-code-hardening
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 3
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: ai-generated-code-hardening
|
|
9
|
-
description: Apply this skill when AI-generated, assistant-authored, vibe-coded, or broad code changes need evidence-backed hardening against symptom-only fixes, pinpoint hardcoding, duplicate helpers or shapes, hidden coupling, weak tests, swallowed errors, excessive complexity, and boundary drift.
|
|
9
|
+
description: Apply this skill when AI-generated, assistant-authored, vibe-coded, or broad code changes need evidence-backed hardening against symptom-only fixes, pinpoint hardcoding, duplicate helpers or shapes, hidden coupling, fake small-sample performance confidence, weak tests, swallowed errors, excessive complexity, and boundary drift.
|
|
10
10
|
metadata:
|
|
11
11
|
mustflow_schema: "1"
|
|
12
12
|
mustflow_kind: procedure
|
|
@@ -33,8 +33,8 @@ Use this skill to turn agent-written code from "looks plausible" into maintainab
|
|
|
33
33
|
repository code. The goal is not style cleanup. The goal is to catch the failure
|
|
34
34
|
modes that appear when an agent forgets the repository between sessions: symptom-only
|
|
35
35
|
patches, pinpoint hardcoding, duplicate helpers, duplicate shapes, hidden coupling,
|
|
36
|
-
|
|
37
|
-
files.
|
|
36
|
+
fake confidence from tiny fixtures, hidden repeated work, weak tests, swallowed errors,
|
|
37
|
+
accidental public surfaces, and oversized functions or files.
|
|
38
38
|
|
|
39
39
|
<!-- mustflow-section: use-when -->
|
|
40
40
|
## Use When
|
|
@@ -51,6 +51,9 @@ files.
|
|
|
51
51
|
re-export drift.
|
|
52
52
|
- Tests were added or changed and may only check strings, function names, snapshots,
|
|
53
53
|
mocks, or implementation details instead of observable behavior.
|
|
54
|
+
- The code looks clean on sample data but may hide repeated scans, repeated copying,
|
|
55
|
+
repeated I/O, unbounded fan-out, allocation churn, or response-size growth under
|
|
56
|
+
realistic data.
|
|
54
57
|
- Error handling, fallback paths, defensive guards, or default values were added in
|
|
55
58
|
multiple callers instead of one boundary.
|
|
56
59
|
- New or changed functions/files are becoming hard to review because of excessive
|
|
@@ -189,7 +192,23 @@ files.
|
|
|
189
192
|
- Split a god file only when the new module has a stable owner, direction, and
|
|
190
193
|
verification path.
|
|
191
194
|
|
|
192
|
-
8.
|
|
195
|
+
8. Check small-sample performance traps.
|
|
196
|
+
- Treat fixture-sized success as weak evidence when the path handles users,
|
|
197
|
+
orders, comments, logs, rows, files, permissions, relations, or rendered list
|
|
198
|
+
items that can grow.
|
|
199
|
+
- Search AI-authored code for `map`, `filter`, `find`, `findIndex`, `includes`,
|
|
200
|
+
`indexOf`, `reduce`, `sort`, `slice`, `splice`, `shift`, spread accumulation,
|
|
201
|
+
`concat`, `cloneDeep`, `JSON.stringify`, `parse`, `validate`, `sanitize`,
|
|
202
|
+
`normalize`, and helper names such as `isAllowed`, `canAccess`, `resolve`,
|
|
203
|
+
`build`, or `format` in repeated paths.
|
|
204
|
+
- Escalate concrete hidden O(N^2), allocation churn, or request fan-out evidence
|
|
205
|
+
to `quadratic-scan-review`, `hot-path-performance-review`, or
|
|
206
|
+
`api-request-performance-review` instead of burying it as style feedback.
|
|
207
|
+
- Do not claim a performance improvement from static review alone. Mark it as
|
|
208
|
+
static complexity risk unless configured tests, query counts, traces, profiles,
|
|
209
|
+
or benchmarks support the claim.
|
|
210
|
+
|
|
211
|
+
9. Harden tests against fake confidence.
|
|
193
212
|
- Verify behavior and side effects, not only function names, strings, snapshots,
|
|
194
213
|
or the presence of files.
|
|
195
214
|
- For bug fixes, add at least one nearby negative or sibling case when feasible so
|
|
@@ -203,7 +222,7 @@ files.
|
|
|
203
222
|
- If production code gained defensive fallback only to satisfy a brittle test,
|
|
204
223
|
fix the test or move the fallback to the owning boundary.
|
|
205
224
|
|
|
206
|
-
|
|
225
|
+
10. Use enforcement evidence without inventing enforcement.
|
|
207
226
|
- Run existing configured lint, build, and related test intents when they cover
|
|
208
227
|
the risk.
|
|
209
228
|
- If the repository lacks dependency-boundary, complexity, max-depth,
|
|
@@ -212,7 +231,7 @@ files.
|
|
|
212
231
|
- Never paste outside plugin commands, package-manager commands, or CI recipes
|
|
213
232
|
into mustflow command contracts without command-contract review.
|
|
214
233
|
|
|
215
|
-
|
|
234
|
+
11. Decide fix now, defer, or report.
|
|
216
235
|
- Fix now when the issue is in the touched code, small, directly tied to the
|
|
217
236
|
current behavior, and verifiable with configured commands.
|
|
218
237
|
- Defer when the issue needs broad architecture work, new dependencies, new CI
|
|
@@ -235,6 +254,8 @@ files.
|
|
|
235
254
|
duplicated guard/fallback risk is documented.
|
|
236
255
|
- Tests exercise behavior and meaningful side effects, with edge and failure paths
|
|
237
256
|
covered where relevant to the change.
|
|
257
|
+
- Sample-data performance confidence has been checked against realistic data-growth,
|
|
258
|
+
repeated-work, allocation, and I/O fan-out risks where relevant.
|
|
238
259
|
|
|
239
260
|
<!-- mustflow-section: verification -->
|
|
240
261
|
## Verification
|
|
@@ -281,5 +302,7 @@ Include:
|
|
|
281
302
|
found or ruled out.
|
|
282
303
|
- Error-handling and fallback decisions.
|
|
283
304
|
- Test hardening: behavior assertions, side effects, edge cases, and mock boundary.
|
|
305
|
+
- Small-sample performance traps: hidden repeated scans, copy churn, repeated I/O,
|
|
306
|
+
unbounded fan-out, or response growth fixed, escalated, or reported.
|
|
284
307
|
- Configured verification intents run and their result.
|
|
285
308
|
- Deferred enforcement, lint, or CI guard suggestions, clearly marked as not added.
|