mustflow 2.18.7 → 2.18.21

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 (32) hide show
  1. package/README.md +4 -0
  2. package/dist/cli/commands/dashboard.js +68 -12
  3. package/dist/cli/commands/init.js +20 -20
  4. package/dist/cli/commands/run.js +1 -8
  5. package/dist/cli/commands/update.js +6 -11
  6. package/dist/cli/commands/verify.js +45 -15
  7. package/dist/cli/lib/dashboard-preferences.js +8 -6
  8. package/dist/cli/lib/filesystem.js +11 -1
  9. package/dist/cli/lib/git-changes.js +7 -1
  10. package/dist/cli/lib/local-index/index.js +31 -31
  11. package/dist/cli/lib/manifest-lock.js +38 -12
  12. package/dist/core/change-classification.js +24 -2
  13. package/dist/core/command-classification.js +0 -16
  14. package/dist/core/command-contract-rules.js +23 -3
  15. package/dist/core/run-write-drift.js +4 -0
  16. package/package.json +1 -1
  17. package/templates/default/i18n.toml +42 -6
  18. package/templates/default/locales/en/.mustflow/skills/INDEX.md +11 -5
  19. package/templates/default/locales/en/.mustflow/skills/cli-output-contract-review/SKILL.md +146 -0
  20. package/templates/default/locales/en/.mustflow/skills/command-contract-authoring/SKILL.md +121 -0
  21. package/templates/default/locales/en/.mustflow/skills/cross-platform-filesystem-safety/SKILL.md +137 -0
  22. package/templates/default/locales/en/.mustflow/skills/dependency-reality-check/SKILL.md +19 -6
  23. package/templates/default/locales/en/.mustflow/skills/external-prompt-injection-defense/SKILL.md +26 -10
  24. package/templates/default/locales/en/.mustflow/skills/llm-service-ux-review/SKILL.md +139 -0
  25. package/templates/default/locales/en/.mustflow/skills/process-execution-safety/SKILL.md +120 -0
  26. package/templates/default/locales/en/.mustflow/skills/routes.toml +38 -2
  27. package/templates/default/locales/en/.mustflow/skills/search-ad-content-authoring/SKILL.md +148 -0
  28. package/templates/default/locales/en/.mustflow/skills/security-privacy-review/SKILL.md +46 -12
  29. package/templates/default/locales/en/.mustflow/skills/security-regression-tests/SKILL.md +43 -12
  30. package/templates/default/locales/en/.mustflow/skills/ui-quality-gate/SKILL.md +34 -14
  31. package/templates/default/manifest.toml +23 -1
  32. package/dist/cli/commands/run/builtin-dispatch.js +0 -92
@@ -5,6 +5,7 @@ import { isRecord, readCommandContract, readString, readStringArray } from '../c
5
5
  import { listFilesRecursive, toPosixPath } from '../filesystem.js';
6
6
  import { readTomlFile } from '../toml.js';
7
7
  import { collectSourceAnchorIndexRecords, hasHighRiskSourceAnchorRiskTags, } from '../../../core/source-anchor-status.js';
8
+ import { listSourceAnchorFiles } from '../../../core/source-anchors.js';
8
9
  import { normalizeCommandEffects } from '../../../core/command-effects.js';
9
10
  import { listChangeClassificationRuleDescriptors } from '../../../core/change-classification.js';
10
11
  import { DEFAULT_DATABASE_RELATIVE_PATH, DEFAULT_PROMPT_CACHE_STABLE_READ, DEFAULT_PROMPT_CACHE_TASK_SOURCES, DEFAULT_PROMPT_CACHE_VOLATILE_SOURCES, INDEX_CONFIG_RELATIVE_PATH, LOCAL_INDEX_CONTENT_MODE, LOCAL_INDEX_EXCLUDED_RAW_DATA_KINDS, LOCAL_INDEX_PARSER_VERSION, LOCAL_INDEX_SCHEMA_VERSION, LOCAL_INDEX_STORE_FULL_CONTENT, LATEST_RUN_STATE_RELATIVE_PATH, MAX_SEARCH_MATCH_SNIPPET_CHARS, MAX_SNIPPET_BYTES_PER_DOCUMENT, MUSTFLOW_RELATIVE_PATH, SEARCH_BACKEND_FTS5, SEARCH_BACKEND_TABLE_SCAN, SEARCH_MATCH_CONTEXT_AFTER_CHARS, SEARCH_MATCH_CONTEXT_BEFORE_CHARS, SEARCH_MATCH_TRUNCATION_MARKER, SEARCH_NGRAM_MAX_GRAMS_PER_TARGET, SEARCH_NGRAM_MAX_LENGTH, SEARCH_NGRAM_MAX_TOKEN_CHARS, SEARCH_NGRAM_MIN_LENGTH, SOURCE_INDEX_MAX_FILE_BYTES, TEST_DISABLE_FTS5_ENV, } from './constants.js';
@@ -308,12 +309,13 @@ function readIndexedFileMetadataRecord(projectRoot, relativePath, sourceScope) {
308
309
  mtimeMs: Math.round(stats.mtimeMs),
309
310
  };
310
311
  }
311
- function collectIndexedFileRecords(projectRoot, documents, sourceAnchors) {
312
+ function collectIndexedFileRecords(projectRoot, documents, sourceAnchors, sourceAnchorCandidatePaths = []) {
312
313
  const records = new Map();
313
314
  for (const document of documents) {
314
315
  records.set(document.path, readIndexedFileRecord(projectRoot, document.path, 'workflow', document.contentHash));
315
316
  }
316
- for (const anchorPath of [...new Set(sourceAnchors.map((anchor) => anchor.path))].sort((left, right) => left.localeCompare(right))) {
317
+ const sourcePaths = new Set([...sourceAnchorCandidatePaths, ...sourceAnchors.map((anchor) => anchor.path)]);
318
+ for (const anchorPath of [...sourcePaths].sort((left, right) => left.localeCompare(right))) {
317
319
  if (!records.has(anchorPath)) {
318
320
  records.set(anchorPath, readIndexedFileRecord(projectRoot, anchorPath, 'source_anchor'));
319
321
  }
@@ -323,15 +325,33 @@ function collectIndexedFileRecords(projectRoot, documents, sourceAnchors) {
323
325
  }
324
326
  return [...records.values()].sort((left, right) => left.path.localeCompare(right.path));
325
327
  }
326
- function collectFastPreflightIndexedFileMetadataRecords(projectRoot, includeSource) {
328
+ function collectSourceAnchorCandidatePaths(projectRoot, sourceConfig) {
329
+ return listSourceAnchorFiles(projectRoot, {
330
+ ...sourceConfig,
331
+ excludeGeneratedOrVendor: true,
332
+ });
333
+ }
334
+ function collectFastPreflightIndexedFileRecords(projectRoot, includeSource, sourceConfig) {
335
+ const records = new Map();
336
+ for (const relativePath of getExistingIndexablePaths(projectRoot)) {
337
+ records.set(relativePath, readIndexedFileRecord(projectRoot, relativePath, 'workflow'));
338
+ }
327
339
  if (includeSource) {
328
- return null;
340
+ try {
341
+ for (const sourcePath of collectSourceAnchorCandidatePaths(projectRoot, sourceConfig)) {
342
+ if (!records.has(sourcePath)) {
343
+ records.set(sourcePath, readIndexedFileRecord(projectRoot, sourcePath, 'source_anchor'));
344
+ }
345
+ }
346
+ }
347
+ catch {
348
+ return null;
349
+ }
329
350
  }
330
- const records = getExistingIndexablePaths(projectRoot).map((relativePath) => readIndexedFileMetadataRecord(projectRoot, relativePath, 'workflow'));
331
351
  if (existsSync(path.join(projectRoot, ...LATEST_RUN_STATE_RELATIVE_PATH.split('/')))) {
332
- records.push(readIndexedFileMetadataRecord(projectRoot, LATEST_RUN_STATE_RELATIVE_PATH, 'state'));
352
+ records.set(LATEST_RUN_STATE_RELATIVE_PATH, readIndexedFileRecord(projectRoot, LATEST_RUN_STATE_RELATIVE_PATH, 'state'));
333
353
  }
334
- return records.sort((left, right) => left.path.localeCompare(right.path));
354
+ return [...records.values()].sort((left, right) => left.path.localeCompare(right.path));
335
355
  }
336
356
  function normalizeSearchText(value) {
337
357
  return value.trim().replace(/\s+/g, ' ');
@@ -2033,27 +2053,6 @@ function createStoredLocalIndexResult(projectRoot, databasePath, dryRun, indexMo
2033
2053
  indexed_paths: readStoredIndexedPaths(database),
2034
2054
  };
2035
2055
  }
2036
- function indexedFileMetadataMatch(database, currentFiles) {
2037
- const rows = queryRows(database, 'SELECT path, source_scope, size_bytes, mtime_ms, parser_version FROM indexed_files ORDER BY path');
2038
- if (rows.length !== currentFiles.length) {
2039
- return false;
2040
- }
2041
- const currentByPath = new Map(currentFiles.map((file) => [file.path, file]));
2042
- for (const row of rows) {
2043
- const storedPath = toSearchString(row.path);
2044
- const current = currentByPath.get(storedPath);
2045
- if (!current) {
2046
- return false;
2047
- }
2048
- if (normalizeIndexedFileSourceScope(row.source_scope) !== current.sourceScope ||
2049
- row.size_bytes !== current.sizeBytes ||
2050
- row.mtime_ms !== current.mtimeMs ||
2051
- toSearchString(row.parser_version) !== LOCAL_INDEX_PARSER_VERSION) {
2052
- return false;
2053
- }
2054
- }
2055
- return true;
2056
- }
2057
2056
  function indexedFilesMatch(database, currentFiles) {
2058
2057
  const rows = queryRows(database, 'SELECT path, source_scope, content_hash, parser_version FROM indexed_files ORDER BY path');
2059
2058
  if (rows.length !== currentFiles.length) {
@@ -2096,7 +2095,7 @@ async function readIncrementalPreflightReuse(SQL, databasePath, projectRoot, cur
2096
2095
  if (!hasTable(database, 'indexed_files')) {
2097
2096
  return { result: null, rebuildReason: 'indexed_files_missing' };
2098
2097
  }
2099
- if (!indexedFileMetadataMatch(database, currentFiles)) {
2098
+ if (!indexedFilesMatch(database, currentFiles)) {
2100
2099
  return { result: null, rebuildReason: 'file_fingerprint_mismatch' };
2101
2100
  }
2102
2101
  const capabilities = readStoredSearchCapabilities(database);
@@ -2170,7 +2169,7 @@ export async function createLocalIndex(projectRoot, options = {}) {
2170
2169
  capabilities = detectLocalSearchCapabilities(capabilityDatabase);
2171
2170
  capabilityDatabase.close();
2172
2171
  if (incremental) {
2173
- const preflightFiles = collectFastPreflightIndexedFileMetadataRecords(projectRoot, includeSource);
2172
+ const preflightFiles = collectFastPreflightIndexedFileRecords(projectRoot, includeSource, sourceConfig);
2174
2173
  const preflightReuse = await readIncrementalPreflightReuse(SQL, databasePath, projectRoot, preflightFiles, sourceScopeHash, dryRun, indexMode);
2175
2174
  if (preflightReuse.result) {
2176
2175
  return preflightReuse.result;
@@ -2184,6 +2183,7 @@ export async function createLocalIndex(projectRoot, options = {}) {
2184
2183
  const previousSourceAnchors = includeSource
2185
2184
  ? await readPreviousSourceAnchorSnapshots(databasePath).catch(() => [])
2186
2185
  : [];
2186
+ const sourceAnchorCandidatePaths = includeSource ? collectSourceAnchorCandidatePaths(projectRoot, sourceConfig) : [];
2187
2187
  const sourceAnchors = includeSource
2188
2188
  ? collectSourceAnchorIndexRecords(projectRoot, previousSourceAnchors, {
2189
2189
  ...sourceConfig,
@@ -2191,7 +2191,7 @@ export async function createLocalIndex(projectRoot, options = {}) {
2191
2191
  })
2192
2192
  : [];
2193
2193
  const verificationEvidence = createVerificationEvidenceIndex(projectRoot);
2194
- const indexedFiles = collectIndexedFileRecords(projectRoot, documents, sourceAnchors);
2194
+ const indexedFiles = collectIndexedFileRecords(projectRoot, documents, sourceAnchors, sourceAnchorCandidatePaths);
2195
2195
  if (incremental) {
2196
2196
  const reuseDecision = await readIncrementalReuseDecision(SQL, databasePath, indexedFiles, sourceScopeHash);
2197
2197
  reusedExisting = reuseDecision.reusable;
@@ -1,8 +1,8 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { existsSync } from 'node:fs';
3
3
  import path from 'node:path';
4
- import { ensureInside } from './filesystem.js';
5
- import { readTomlFile, stringifyToml } from './toml.js';
4
+ import { ensureFileTargetInsideWithoutSymlinks, ensureInside, readFileInsideWithoutSymlinks, readUtf8FileInsideWithoutSymlinks, writeUtf8FileInsideWithoutSymlinks, } from './filesystem.js';
5
+ import { parseTomlText, stringifyToml } from './toml.js';
6
6
  export const MANIFEST_LOCK_RELATIVE_PATH = '.mustflow/config/manifest.lock.toml';
7
7
  function isRecord(value) {
8
8
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -48,20 +48,31 @@ function parseManifestLock(raw) {
48
48
  };
49
49
  }
50
50
  export function sha256File(filePath) {
51
- return `sha256:${createHash('sha256').update(readFileSync(filePath)).digest('hex')}`;
51
+ return `sha256:${createHash('sha256')
52
+ .update(readFileInsideWithoutSymlinks(path.dirname(filePath), filePath))
53
+ .digest('hex')}`;
54
+ }
55
+ function sha256ProjectFile(projectRoot, filePath) {
56
+ return `sha256:${createHash('sha256').update(readFileInsideWithoutSymlinks(projectRoot, filePath)).digest('hex')}`;
57
+ }
58
+ export function ensureManifestLockTargetSafe(projectRoot) {
59
+ const lockPath = path.join(projectRoot, MANIFEST_LOCK_RELATIVE_PATH);
60
+ ensureInside(projectRoot, lockPath);
61
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, lockPath, { allowMissingLeaf: true });
62
+ return existsSync(lockPath);
52
63
  }
53
64
  export function markManifestLockFileCustomized(projectRoot, relativePath) {
54
65
  const lockPath = path.join(projectRoot, MANIFEST_LOCK_RELATIVE_PATH);
55
66
  const filePath = path.join(projectRoot, relativePath);
56
- ensureInside(projectRoot, lockPath);
57
67
  ensureInside(projectRoot, filePath);
58
- if (!existsSync(lockPath)) {
68
+ if (!ensureManifestLockTargetSafe(projectRoot)) {
59
69
  return false;
60
70
  }
71
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, filePath, { allowMissingLeaf: true });
61
72
  if (!existsSync(filePath)) {
62
73
  throw new Error(`Cannot refresh manifest lock for missing file: ${relativePath}`);
63
74
  }
64
- const parsed = readTomlFile(lockPath);
75
+ const parsed = parseTomlText(readUtf8FileInsideWithoutSymlinks(projectRoot, lockPath));
65
76
  if (!isRecord(parsed)) {
66
77
  throw new Error(`Invalid manifest lock: ${MANIFEST_LOCK_RELATIVE_PATH} must contain a TOML table`);
67
78
  }
@@ -71,20 +82,27 @@ export function markManifestLockFileCustomized(projectRoot, relativePath) {
71
82
  filesTable[relativePath] = {
72
83
  source: typeof existingTable.source === 'string' ? existingTable.source : 'template_common',
73
84
  last_action: 'customized',
74
- content_hash: sha256File(filePath),
85
+ content_hash: sha256ProjectFile(projectRoot, filePath),
75
86
  };
76
87
  parsed.files = filesTable;
77
- writeFileSync(lockPath, stringifyToml(parsed));
88
+ writeUtf8FileInsideWithoutSymlinks(projectRoot, lockPath, stringifyToml(parsed));
78
89
  return true;
79
90
  }
80
91
  export function readManifestLock(projectRoot) {
81
92
  const lockPath = path.join(projectRoot, MANIFEST_LOCK_RELATIVE_PATH);
82
- ensureInside(projectRoot, lockPath);
93
+ try {
94
+ ensureInside(projectRoot, lockPath);
95
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, lockPath, { allowMissingLeaf: true });
96
+ }
97
+ catch (error) {
98
+ const message = error instanceof Error ? error.message : String(error);
99
+ return { kind: 'invalid', lockPath, message };
100
+ }
83
101
  if (!existsSync(lockPath)) {
84
102
  return { kind: 'missing', lockPath };
85
103
  }
86
104
  try {
87
- return { kind: 'present', lockPath, lock: parseManifestLock(readTomlFile(lockPath)) };
105
+ return { kind: 'present', lockPath, lock: parseManifestLock(parseTomlText(readUtf8FileInsideWithoutSymlinks(projectRoot, lockPath))) };
88
106
  }
89
107
  catch (error) {
90
108
  const message = error instanceof Error ? error.message : String(error);
@@ -121,7 +139,15 @@ export function inspectManifestLock(projectRoot) {
121
139
  issues.push(`Locked file missing: ${lockedFile.relativePath}`);
122
140
  continue;
123
141
  }
124
- const actualHash = sha256File(filePath);
142
+ let actualHash;
143
+ try {
144
+ actualHash = sha256ProjectFile(projectRoot, filePath);
145
+ }
146
+ catch (error) {
147
+ const message = error instanceof Error ? error.message : String(error);
148
+ issues.push(`Locked file cannot be read safely: ${lockedFile.relativePath}: ${message}`);
149
+ continue;
150
+ }
125
151
  if (actualHash !== lockedFile.contentHash) {
126
152
  changedFiles.push(lockedFile.relativePath);
127
153
  issues.push(`Lock hash mismatch: ${lockedFile.relativePath}`);
@@ -46,14 +46,36 @@ function uniqueSorted(values) {
46
46
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
47
47
  }
48
48
  function toPosixPath(value) {
49
- return value.trim().replaceAll('\\', '/');
49
+ return value.replaceAll('\\', '/');
50
50
  }
51
51
  export function normalizeStatusPath(value) {
52
- const pathText = toPosixPath(value);
52
+ const pathText = toPosixPath(value.trim());
53
53
  const renameTarget = pathText.includes(' -> ') ? (pathText.split(' -> ').pop() ?? pathText) : pathText;
54
54
  return renameTarget.replace(/^"|"$/gu, '');
55
55
  }
56
+ function normalizePorcelainStatusPath(value) {
57
+ return toPosixPath(value);
58
+ }
59
+ function parseGitPorcelainStatusOutput(output) {
60
+ const paths = [];
61
+ const parts = output.split('\0').filter((part) => part.length > 0);
62
+ for (let index = 0; index < parts.length; index += 1) {
63
+ const entry = parts[index] ?? '';
64
+ const status = entry.slice(0, 2);
65
+ const filePath = normalizePorcelainStatusPath(entry.slice(3));
66
+ if (filePath.length > 0) {
67
+ paths.push(filePath);
68
+ }
69
+ if (status.includes('R') || status.includes('C')) {
70
+ index += 1;
71
+ }
72
+ }
73
+ return uniqueSorted(paths);
74
+ }
56
75
  export function parseGitStatusOutput(output) {
76
+ if (output.includes('\0')) {
77
+ return parseGitPorcelainStatusOutput(output);
78
+ }
57
79
  const paths = output
58
80
  .split(/\r?\n/u)
59
81
  .map((line) => line.slice(3))
@@ -1,20 +1,4 @@
1
1
  const MUSTFLOW_BIN_NAMES = new Set(['mf', 'mustflow']);
2
- const IN_PROCESS_MUSTFLOW_BUILTIN_COMMANDS = new Set([
3
- 'check',
4
- 'classify',
5
- 'context',
6
- 'doctor',
7
- 'help',
8
- 'impact',
9
- 'line-endings',
10
- 'map',
11
- 'status',
12
- 'update',
13
- 'version-sources',
14
- ]);
15
2
  export function isMustflowBinName(command) {
16
3
  return MUSTFLOW_BIN_NAMES.has(command.toLowerCase());
17
4
  }
18
- export function canRunMustflowBuiltinInProcess(command) {
19
- return command !== undefined && IN_PROCESS_MUSTFLOW_BUILTIN_COMMANDS.has(command);
20
- }
@@ -14,6 +14,7 @@ const INTERPRETER_EVALUATION_FLAGS = new Map([
14
14
  const PACKAGE_SCRIPT_RUNNERS = new Set(['bun', 'npm', 'pnpm', 'yarn']);
15
15
  const LONG_RUNNING_PACKAGE_SCRIPTS = new Set(['dev', 'start', 'serve', 'watch', 'preview']);
16
16
  const LONG_RUNNING_EXECUTABLES = new Set(['nodemon', 'pm2', 'serve', 'http-server', 'live-server', 'webpack-dev-server']);
17
+ const ATTACHED_EVALUATION_FLAGS = new Set(['-command', '-commandwithargs']);
17
18
  export const BACKGROUND_SHELL_PATTERNS = [
18
19
  /(?:^|[^&])&(?!&)\s*$/u,
19
20
  /\bnohup\b/iu,
@@ -48,10 +49,23 @@ export function shellCommandHasBlockedBackgroundPattern(command) {
48
49
  function normalizeExecutableName(value) {
49
50
  return path.basename(value).replace(/\.(?:cmd|exe|ps1)$/iu, '').toLowerCase();
50
51
  }
52
+ function flagAllowsAttachedPayload(flag) {
53
+ return (flag.startsWith('-') && !flag.startsWith('--') && flag.length === 2) || flag === '/c' || ATTACHED_EVALUATION_FLAGS.has(flag);
54
+ }
51
55
  function findFlagPayload(argv, flags) {
52
- for (let index = 1; index < argv.length - 1; index += 1) {
53
- if (flags.has(argv[index].toLowerCase())) {
54
- return argv[index + 1];
56
+ for (let index = 1; index < argv.length; index += 1) {
57
+ const argument = argv[index] ?? '';
58
+ const normalizedArgument = argument.toLowerCase();
59
+ if (flags.has(normalizedArgument)) {
60
+ return argv[index + 1] ?? null;
61
+ }
62
+ for (const flag of flags) {
63
+ if (normalizedArgument.startsWith(`${flag}=`)) {
64
+ return argument.slice(flag.length + 1);
65
+ }
66
+ if (flagAllowsAttachedPayload(flag) && normalizedArgument.startsWith(flag) && argument.length > flag.length) {
67
+ return argument.slice(flag.length);
68
+ }
55
69
  }
56
70
  }
57
71
  return null;
@@ -111,6 +125,12 @@ export function commandIntentBlockedCommandPattern(intent) {
111
125
  detail: 'Shell command contains a blocked long-running or background pattern.',
112
126
  };
113
127
  }
128
+ if (intent.mode === 'shell' && typeof intent.cmd === 'string' && commandTextHasLongRunningPattern(intent.cmd)) {
129
+ return {
130
+ code: 'long_running_command_pattern',
131
+ detail: `Shell command contains a blocked long-running pattern: ${intent.cmd}.`,
132
+ };
133
+ }
114
134
  const argv = readStringArray(intent, 'argv');
115
135
  if (!argv) {
116
136
  return null;
@@ -130,6 +130,10 @@ function listObservedChangedPaths(before, after) {
130
130
  function declaredPathCoversObservedPath(declaredPath, observedPath) {
131
131
  const declaredKey = pathKey(declaredPath);
132
132
  const observedKey = pathKey(observedPath);
133
+ if (declaredKey.endsWith('/**')) {
134
+ const baseKey = declaredKey.slice(0, -3) || '.';
135
+ return baseKey === '.' || observedKey === baseKey || observedKey.startsWith(`${baseKey}/`);
136
+ }
133
137
  return declaredKey === '.' || observedKey === declaredKey || observedKey.startsWith(`${declaredKey}/`);
134
138
  }
135
139
  function truncatePaths(paths) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.18.7",
3
+ "version": "2.18.21",
4
4
  "description": "Agent workflow documents and CLI for mustflow repository roots.",
5
5
  "type": "module",
6
6
  "license": "MIT-0",
@@ -56,7 +56,7 @@ translations = {}
56
56
  [documents."skills.index"]
57
57
  source = "locales/en/.mustflow/skills/INDEX.md"
58
58
  source_locale = "en"
59
- revision = 55
59
+ revision = 60
60
60
  translations = {}
61
61
 
62
62
  [documents."skill.adapter-boundary"]
@@ -116,7 +116,7 @@ translations = {}
116
116
  [documents."skill.dependency-reality-check"]
117
117
  source = "locales/en/.mustflow/skills/dependency-reality-check/SKILL.md"
118
118
  source_locale = "en"
119
- revision = 1
119
+ revision = 3
120
120
  translations = {}
121
121
 
122
122
  [documents."skill.line-ending-hygiene"]
@@ -137,6 +137,12 @@ source_locale = "en"
137
137
  revision = 1
138
138
  translations = {}
139
139
 
140
+ [documents."skill.cli-output-contract-review"]
141
+ source = "locales/en/.mustflow/skills/cli-output-contract-review/SKILL.md"
142
+ source_locale = "en"
143
+ revision = 3
144
+ translations = {}
145
+
140
146
  [documents."skill.composition-over-inheritance"]
141
147
  source = "locales/en/.mustflow/skills/composition-over-inheritance/SKILL.md"
142
148
  source_locale = "en"
@@ -149,6 +155,18 @@ source_locale = "en"
149
155
  revision = 4
150
156
  translations = {}
151
157
 
158
+ [documents."skill.command-contract-authoring"]
159
+ source = "locales/en/.mustflow/skills/command-contract-authoring/SKILL.md"
160
+ source_locale = "en"
161
+ revision = 1
162
+ translations = {}
163
+
164
+ [documents."skill.cross-platform-filesystem-safety"]
165
+ source = "locales/en/.mustflow/skills/cross-platform-filesystem-safety/SKILL.md"
166
+ source_locale = "en"
167
+ revision = 3
168
+ translations = {}
169
+
152
170
  [documents."skill.pure-core-imperative-shell"]
153
171
  source = "locales/en/.mustflow/skills/pure-core-imperative-shell/SKILL.md"
154
172
  source_locale = "en"
@@ -182,7 +200,7 @@ translations = {}
182
200
  [documents."skill.external-prompt-injection-defense"]
183
201
  source = "locales/en/.mustflow/skills/external-prompt-injection-defense/SKILL.md"
184
202
  source_locale = "en"
185
- revision = 3
203
+ revision = 5
186
204
  translations = {}
187
205
 
188
206
  [documents."skill.external-skill-intake"]
@@ -232,6 +250,12 @@ source_locale = "en"
232
250
  revision = 1
233
251
  translations = {}
234
252
 
253
+ [documents."skill.process-execution-safety"]
254
+ source = "locales/en/.mustflow/skills/process-execution-safety/SKILL.md"
255
+ source_locale = "en"
256
+ revision = 1
257
+ translations = {}
258
+
235
259
  [documents."skill.repo-improvement-loop"]
236
260
  source = "locales/en/.mustflow/skills/repo-improvement-loop/SKILL.md"
237
261
  source_locale = "en"
@@ -301,13 +325,19 @@ translations = {}
301
325
  [documents."skill.security-privacy-review"]
302
326
  source = "locales/en/.mustflow/skills/security-privacy-review/SKILL.md"
303
327
  source_locale = "en"
304
- revision = 4
328
+ revision = 7
305
329
  translations = {}
306
330
 
307
331
  [documents."skill.security-regression-tests"]
308
332
  source = "locales/en/.mustflow/skills/security-regression-tests/SKILL.md"
309
333
  source_locale = "en"
310
- revision = 6
334
+ revision = 9
335
+ translations = {}
336
+
337
+ [documents."skill.search-ad-content-authoring"]
338
+ source = "locales/en/.mustflow/skills/search-ad-content-authoring/SKILL.md"
339
+ source_locale = "en"
340
+ revision = 3
311
341
  translations = {}
312
342
 
313
343
  [documents."skill.skill-authoring"]
@@ -334,10 +364,16 @@ source_locale = "en"
334
364
  revision = 1
335
365
  translations = {}
336
366
 
367
+ [documents."skill.llm-service-ux-review"]
368
+ source = "locales/en/.mustflow/skills/llm-service-ux-review/SKILL.md"
369
+ source_locale = "en"
370
+ revision = 2
371
+ translations = {}
372
+
337
373
  [documents."skill.ui-quality-gate"]
338
374
  source = "locales/en/.mustflow/skills/ui-quality-gate/SKILL.md"
339
375
  source_locale = "en"
340
- revision = 3
376
+ revision = 6
341
377
  translations = {}
342
378
 
343
379
  [documents."skill.visual-review-artifact"]
@@ -2,7 +2,7 @@
2
2
  mustflow_doc: skills.index
3
3
  locale: en
4
4
  canonical: true
5
- revision: 55
5
+ revision: 60
6
6
  authority: router
7
7
  lifecycle: mustflow-owned
8
8
  ---
@@ -115,6 +115,7 @@ stay inactive until their event occurs.
115
115
  | Claims, adoption decisions, research notes, methodology recommendations, tool comparisons, or external summaries depend on current, external, dated, versioned, or otherwise drift-prone sources | `.mustflow/skills/source-freshness-check/SKILL.md` | Stale-sensitive claim or recommendation, source text or page, date or version context, source policy, and intended adoption surface | Source wording, documentation, skill procedures, templates, tests, schemas, and freshness report | stale or unverifiable claim, copied external authority, or unsafe adoption | `changes_status`, `docs_validate_fast`, `mustflow_check` | Checked source boundary, research split, adoption decision, wording changes, skipped refreshes, and stale-source risk |
116
116
  | `README.md` is created, restructured, or substantially rewritten | `.mustflow/skills/readme-authoring/SKILL.md` | User request, existing README if any, repository evidence, nearest instructions, and command contracts | `README.md` and directly linked public docs | invented project claims, marketing drift, or loss of human-authored intent | `docs_validate_fast`, `mustflow_check` | Evidence-based README changes, preserved or deferred sections, verification notes |
117
117
  | Release notes, changelog entries, public change summaries, release preparation copy, or package release wording are drafted or revised | `.mustflow/skills/release-notes-authoring/SKILL.md` | User-provided change summary, current diff summary, release audience, public surfaces, version source, and command contract entries | Release notes, changelog entries, release preparation notes, and directly synchronized docs or package metadata | invented release history, inflated public claims, internal noise, stale version or migration notes, or unverified release evidence | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Release audience, categorized notes, excluded internal changes, version or migration checks, verification, skipped release-history checks, and remaining release-note risk |
118
+ | Search-friendly ad-supported articles, blog posts, guides, reviews, comparisons, FAQs, or evergreen content are planned, written, edited, reviewed, or reported | `.mustflow/skills/search-ad-content-authoring/SKILL.md` | Search intent, reader task, content type, source freshness needs, monetization constraints, article draft or outline, and command contract entries | Article outlines, headings, paragraphs, tables, lists, FAQs, images, links, disclosures, content docs, templates, tests, and reports | keyword stuffing, thin filler, misleading ad adjacency, stale policy or ranking claims, unsupported revenue claims, accessibility or layout instability, or copied competitor content | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Search intent, outline shape, content structure checks, source freshness, ad layout and trust checks, omitted or verified claims, verification, and remaining content risk |
118
119
  | Documentation review queue entries need prose cleanup | `.mustflow/skills/docs-prose-review/SKILL.md` | Review queue entry or selected document path, review comment if present, target language, reviewer metadata | Selected documentation file and review ledger entry | meaning drift or stale queue state | `docs_validate`, `mustflow_check` | Prose changes, recorded review status, verification notes |
119
120
  | Documentation changes affect public or workflow docs | `.mustflow/skills/docs-update/SKILL.md` | Changed behavior or field | Relevant docs only | stale public docs | `docs_validate_fast`, `docs_validate`, `mustflow_check` | Doc changes and skipped checks |
120
121
 
@@ -122,17 +123,19 @@ stay inactive until their event occurs.
122
123
 
123
124
  | Trigger | Skill Document | Required Input | Edit Scope | Risk | Verification Intents | Expected Output |
124
125
  | --- | --- | --- | --- | --- | --- | --- |
125
- | Code, configuration, docs, templates, logs, telemetry, credentials, or data flows affect secrets, personal data, authentication, authorization, retention, or external disclosure | `.mustflow/skills/security-privacy-review/SKILL.md` | Changed files, sensitive surfaces, project secret and privacy rules, public or packaged surfaces, and command contract entries | Sensitive data handling, logs, receipts, generated state, docs, templates, package metadata, and reports | secret leak, personal-data exposure, or misleading privacy claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Sensitive surfaces reviewed, disclosure paths checked, redaction or omission changes, related test need, and remaining security or privacy risk |
126
- | Security-sensitive behavior changes need abuse-case regression tests | `.mustflow/skills/security-regression-tests/SKILL.md` | Changed boundary, actors, and expected deny behavior | Test files and related security boundary source | false confidence and unsafe coverage | `test`, `test_related`, `test_audit`, `lint`, `build` | Security boundary, abuse case, tests, and remaining risks |
127
- | Outside text, generated content, logs, issues, webpages, or pasted prompts include instructions that could override repository rules or change scope | `.mustflow/skills/external-prompt-injection-defense/SKILL.md` | External text source, direct user request, repository instruction files, conflicting instruction, and command contract entries | Prompts, fixtures, docs, tests, skills, templates, and reports that handle untrusted text | prompt injection, scope drift, or unsafe command authority | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | External sources reviewed, unsafe instructions neutralized, safe requirements adapted, verification, and remaining prompt-injection risk |
126
+ | Code, configuration, docs, templates, logs, telemetry, credentials, data flows, AI-generated code, authentication, authorization, sessions, tokens, uploads, downloads, external requests, deployment settings, dependencies, cryptography, secure transport, scanner gates, security invariants, or agent configuration affect secrets, personal data, retention, or external disclosure | `.mustflow/skills/security-privacy-review/SKILL.md` | Changed files, sensitive surfaces, actor and resource owner, session or token surface, external target, dependency source, cryptography or transport surface, scanner evidence, agent-tool permission, deployment setting, project secret and privacy rules, public or packaged surfaces, and command contract entries | Sensitive data handling, authorization, sessions, tokens, inputs, files, logs, receipts, generated state, docs, templates, package metadata, deployment settings, and reports | secret leak, personal-data exposure, access-control bypass, unsafe external request, supply-chain drift, weak cryptography, insecure transport, over-privileged agent, or misleading privacy claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Sensitive surfaces reviewed, authorization and disclosure paths checked, dependency, cryptography, transport, scanner, and agent-tool boundaries checked, redaction or omission changes, related test need, and remaining security or privacy risk |
127
+ | Security-sensitive behavior changes need abuse-case regression tests | `.mustflow/skills/security-regression-tests/SKILL.md` | Changed boundary, actors, resource ownership, state-changing route, token, file, cryptography, transport, scanner, or invariant behavior, business rule, and expected deny behavior | Test files and related security boundary source | false confidence, happy-path-only coverage, unsafe authorization, token, file, business-rule, cryptography, transport, deployment, or invariant coverage | `test`, `test_related`, `test_audit`, `lint`, `build` | Security boundary, abuse case, defensive test data, tests added or reused, and remaining risks |
128
+ | Outside text, generated content, logs, issues, webpages, pasted prompts, agent rules, MCP/tool configuration, or AI context sources include instructions that could override repository rules, broaden tool access, leak data, or change scope | `.mustflow/skills/external-prompt-injection-defense/SKILL.md` | External text source, direct user request, repository instruction files, conflicting instruction, context sources, tool permission surface, hidden content evidence, and command contract entries | Prompts, fixtures, docs, tests, skills, templates, agent configs, tool configs, and reports that handle untrusted text | prompt injection, context leakage, scope drift, unsafe command authority, or over-broad tool permission | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | External sources reviewed, unsafe instructions neutralized, context and permission boundaries checked, safe requirements adapted, verification, and remaining prompt-injection risk |
128
129
 
129
130
  ### Data and External Systems
130
131
 
131
132
  | Trigger | Skill Document | Required Input | Edit Scope | Risk | Verification Intents | Expected Output |
132
133
  | --- | --- | --- | --- | --- | --- | --- |
133
134
  | Database schema, query, transaction, ORM model, repository/store, index, cache-backed read model, data retention, pagination, concurrency, idempotency, audit log, or persistence boundary is introduced, changed, reviewed, or reported | `.mustflow/skills/database-change-safety/SKILL.md` | Data role, affected tables or stores, read/write path, transaction boundary, migration or rollback expectations, local DB or ORM patterns, changed files, and command contract entries | Schema, migrations, repositories, stores, queries, transactions, indexes, read models, fixtures, tests, docs, and directly synchronized templates | data loss, stale cache, authorization leak, transaction bug, duplicate side effect, slow query, or unverified migration claim | `changes_status`, `changes_diff_summary`, `test_related`, `test`, `lint`, `build`, `docs_validate_fast`, `test_release`, `mustflow_check` | Data role, schema/query/transaction review, migration and rollback status, index/performance notes, security/retention checks, tests, verification, and remaining database risk |
134
- | Packages, runtimes, tools, commands, services, or platform capabilities are assumed, added, invoked, or documented | `.mustflow/skills/dependency-reality-check/SKILL.md` | Dependency or capability, repository declarations, version or capability claim, and command contract entries | Dependency declarations, imports, command metadata, tests, and docs | invented or unavailable dependency | `changes_status`, `changes_diff_summary`, `build`, `test_release`, `mustflow_check` | Dependency status, synchronized surfaces, verification, and remaining dependency risk |
135
+ | Dependency, package, runtime, tool, command, plugin, service, platform capability, package script, lifecycle hook, binary download, lockfile, audit result, or supply-chain-sensitive dependency surface is assumed, added, removed, imported, invoked, installed, or documented | `.mustflow/skills/dependency-reality-check/SKILL.md` | Assumed dependency or capability, declaration files, version or feature expectation, lockfile entry, package script or lifecycle hook, audit or provenance evidence, and relevant command intents | Package metadata, lockfiles, imports, scripts, command contracts, docs, tests, and reports | unavailable dependency, hallucinated or lookalike package, stale version claim, lifecycle script risk, audit suppression, lockfile drift, or install guidance mismatch | `changes_status`, `changes_diff_summary`, `build`, `test_release`, `mustflow_check` | Dependency checked, supply-chain surface reviewed, declarations synchronized, verification, and remaining dependency risk |
135
136
  | External systems, protocols, SDKs, databases, webhooks, queues, files, caches, framework requests or responses, AI models, browser storage, or provider data cross the core boundary or need port/adapter translation, error mapping, retry, idempotency, security, or observability handling | `.mustflow/skills/adapter-boundary/SKILL.md` | External system or protocol, inbound/outbound direction, internal use case, local port/adapter patterns, provider risk, changed files, and command contract entries | Ports, adapters, mappers, controllers, workers, stores, gateways, tests, fixtures, assembly wiring, and directly synchronized docs or templates | provider leakage, pass-through wrapper, unclassified external failure, duplicate side effect, unsafe retry, missing timeout, secret or personal-data leak, or untested integration drift | `changes_status`, `changes_diff_summary`, `test_related`, `test`, `lint`, `build`, `docs_validate_fast`, `test_release`, `mustflow_check` | Boundary classification, internal port, provider containment, validation and mapping, timeout/retry/idempotency handling, security notes, verification, and remaining provider risk |
137
+ | File paths, directories, symlinks, real paths, traversal, atomic writes, file copies, generated outputs, temporary files, cleanup, or Windows/POSIX filesystem behavior are created, changed, reviewed, or reported | `.mustflow/skills/cross-platform-filesystem-safety/SKILL.md` | Path inputs, base directory, trust boundary, symlink policy, write or cleanup strategy, platform expectations, and command contract entries | Path validation, file helpers, copy/update/delete code, scan bounds, fixtures, tests, docs, and templates | path traversal, symlink escape, unsafe overwrite, platform-only behavior, stale output, or cleanup data loss | `changes_status`, `changes_diff_summary`, `test_related`, `docs_validate_fast`, `test_release`, `mustflow_check` | Path trust classes, root boundary, symlink/write/delete/scan decisions, platform assumptions, verification, and remaining filesystem risk |
138
+ | Child processes, shell or argv execution, built-in command reruns, timeouts, process trees, output limits, streaming, environment policy, command eligibility, or execution receipts are created, changed, reviewed, or reported | `.mustflow/skills/process-execution-safety/SKILL.md` | Execution path, timeout, output limit, stdin, environment, cwd, process tree behavior, receipt and write-tracking expectations, and command contract entries | Process execution code, process-tree helpers, output buffers, environment creation, eligibility checks, receipts, tests, and docs | runaway process, unbounded output, leaked environment, inconsistent JSON/text execution, false cleanup claim, or unreliable receipt | `changes_status`, `changes_diff_summary`, `test_related`, `test_release`, `mustflow_check` | Execution surface, timeout/output/environment/process-tree boundaries, receipt consistency, tests, verification, and remaining process risk |
136
139
  | Core or application logic creates, imports, resolves, or hides external dependencies such as databases, SDKs, clocks, random generators, configuration, loggers, framework objects, filesystems, queues, AI clients, or payment/email providers | `.mustflow/skills/dependency-injection/SKILL.md` | Target code area, hidden dependency, intended business capability, layer ownership, local port/adapter patterns, changed files, and command contract entries | Core logic signatures, ports, adapters, assembly roots, tests, and directly synchronized docs or templates | hidden global state, untestable business logic, provider leakage, lifecycle drift, or service-locator coupling | `changes_status`, `changes_diff_summary`, `test_related`, `test`, `lint`, `build`, `docs_validate_fast`, `test_release`, `mustflow_check` | Dependency boundary, direct dependencies found, injection style, ports/adapters, assembly boundary, tests or fakes, verification, and remaining dependency leakage |
137
140
  | Code, data, schema, configuration, file layout, template, or generated-state migrations are planned, edited, documented, or reported | `.mustflow/skills/migration-safety-check/SKILL.md` | Source state, target state, migration surface owner, idempotency, rollback, dry-run, compatibility, and command contract entries | Migration plans, compatibility notes, lock metadata, docs, tests, templates, generated state, and reports | irreversible migration, data loss, or false migration-success claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Migration surface, source and target state, idempotency, rollback, metadata updates, verification, and remaining migration risk |
138
141
 
@@ -142,6 +145,7 @@ stay inactive until their event occurs.
142
145
  | --- | --- | --- | --- | --- | --- | --- |
143
146
  | Generated artifacts, packaged files, binary assets, reports, or downloadable outputs are created, referenced, or reported | `.mustflow/skills/artifact-integrity-check/SKILL.md` | Artifact paths, source or generation path, package rules, and artifact expectations | Artifact references, package metadata, tests, and documentation | unverified or stale artifact claim | `changes_status`, `changes_diff_summary`, `test_release`, `build`, `mustflow_check` | Artifact evidence, inclusion or format checks, skipped checks, and integrity risk |
144
147
  | A dense plan, suggestion, code explanation, review result, flow map, or decision set would be easier to inspect as a safe static HTML review artifact | `.mustflow/skills/visual-review-artifact/SKILL.md` | User request, artifact goal, target audience, source evidence, output path, and relevant command contract entries | Temporary `.mustflow/state/artifacts/**` output or explicitly requested versioned HTML artifact, plus direct references, docs, or package metadata | unsafe HTML behavior, prompt injection, unverified artifact claim, or mistaken approval authority | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Artifact kind and path, source evidence, review-only boundary, local interactions, verification, skipped checks, and remaining decision risk |
148
+ | Conversational AI, chat, copilot, prompt, multimodal input, streaming generation, citation, feedback, or conversation-history UI is planned, edited, reviewed, or reported | `.mustflow/skills/llm-service-ux-review/SKILL.md` | LLM service surface, user task, interaction mode, input-to-reset path, latency/source/privacy constraints, and command contract entries | Prompt, attachment, generation, output, citation, feedback, history, reset, error, accessibility, docs, templates, and reports | loss of user control, fake progress, unverifiable source claims, hidden privacy risk, decorative prompt UX, or unverified visual claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | LLM UX surface reviewed, input/waiting/output/recovery states checked, control and citation boundaries, skipped checks, and remaining LLM UX risk |
145
149
  | User-facing UI, dashboard, settings, navigation, form, copy, responsive layout, accessibility, or visual state changes are planned, edited, reviewed, or reported | `.mustflow/skills/ui-quality-gate/SKILL.md` | Changed UI surface, user task, interaction path, existing patterns, state combinations, localization rules, and command contract entries | UI controls, labels, states, layout constraints, accessibility attributes, localization hooks, docs, templates, and reports | decorative UI drift, inaccessible controls, layout breakage, or unverified visual claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | UI surface reviewed, states checked, layout/accessibility/localization notes, skipped visual checks, and remaining UI risk |
146
150
  | Web image assets are added, converted, resized, or replaced | `.mustflow/skills/web-asset-optimization/SKILL.md` | Image asset request and target path | Web image assets | asset quality and size | `asset_optimize`, `build` | Optimized asset notes |
147
151
 
@@ -168,6 +172,8 @@ stay inactive until their event occurs.
168
172
  | Multiple AI workers, subagents, external agents, parallel task runners, or worktree-based worker roles are planned or used for one repository task | `.mustflow/skills/multi-agent-work-coordination/SKILL.md` | Task goal, worker roles, write permissions, file ownership, workspace isolation, credential boundary, merge owner, and command contract entries | Coordination plan, worker instructions, ownership boundaries, merge notes, and directly synchronized tests or docs | same-file races, conflicting instructions, leaked credentials, shared auth cache, untrusted worker output, merge drift, or unverified parallel result | `changes_status`, `changes_diff_summary`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Worker limit, role map, write ownership, isolation and credential boundaries, merge owner, verification, skipped checks, and remaining coordination risk |
169
173
  | Repository improvement, audit, prioritization, stabilization, polish, onboarding, contributor-readiness, production-readiness, or iterative improvement is requested without a single predetermined edit | `.mustflow/skills/repo-improvement-loop/SKILL.md` | User goal, improvement mode, repository evidence, candidate risks, current changed files, and command contract entries | Repository diagnosis, ranked candidates, and at most one scoped improvement cycle unless the user explicitly requests analysis-only | idea spam, ungrounded prioritization, autonomous loop drift, broad rewrite, or unverified improvement claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Mode, evidence inspected, scored candidates, selected improvement, files changed or analysis-only note, verification, next improvement question, and stop reason |
170
174
  | Declared behavior must stay aligned across code, schemas, templates, tests, and docs | `.mustflow/skills/contract-sync-check/SKILL.md` | Changed files, intended behavior, source of truth, derived surfaces, and command contract entries | Contract source and required synchronized surfaces | contract drift | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Contract source, synchronized surfaces, deferred surfaces, verification, and drift risk |
175
+ | `.mustflow/config/commands.toml` command intents, resources, effects, timeouts, output limits, environment policies, lifecycle values, run policies, or command-selection metadata are created, changed, reviewed, or removed | `.mustflow/skills/command-contract-authoring/SKILL.md` | Command goal, current command contract, expected reads and writes, side effects, locks, timeout, output, environment, stdin, and verification entries | Command contract, template command contracts, workflow docs, skills, tests, and directly synchronized public docs | accidental command authority, inferred command, unbounded side effect, missing lock, secret exposure, or long-running command approval | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Intent authority decision, side-effect model, environment and timeout boundary, synchronized surfaces, verification, and remaining command-contract risk |
176
+ | CLI text output, JSON output, exit codes, error messages, warnings, deprecations, help text, command aliases, schema-backed reports, or automation-facing command behavior are created, changed, reviewed, or reported | `.mustflow/skills/cli-output-contract-review/SKILL.md` | Affected command, output modes, exit-code expectations, docs examples, schemas, fixtures, consumers, and command contract entries | CLI output code, schemas, fixtures, docs, README examples, package tests, templates, and reports | broken automation, misleading success, schema drift, undocumented deprecation, stale example, or incompatible output change | `changes_status`, `changes_diff_summary`, `test_related`, `docs_validate_fast`, `test_release`, `mustflow_check` | Output surfaces reviewed, status and exit-code semantics, synchronized schemas/docs/tests/templates, verification, and remaining CLI-output risk |
171
177
  | Dates, versions, counts, durations, limits, metrics, benchmarks, prices, percentages, or other numeric facts are created, edited, or reported | `.mustflow/skills/date-number-audit/SKILL.md` | Date or numeric fact, source of truth, dependent surfaces, precision expectation, and command contract entries | Numeric statements, metadata, tests, docs, templates, and reports | invented, stale, or mismatched numeric claim | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Audited values, source of truth, synchronized surfaces, skipped checks, and remaining numeric risk |
172
178
  | Git reports CRLF/LF warnings or tracked text files may need line-ending normalization | `.mustflow/skills/line-ending-hygiene/SKILL.md` | Warning text or changed-file evidence, line-ending policy, changed-file status, and command contract entries | Line-ending policy files, tracked text files, command metadata, tests, and reports | silent working-tree rewrite or policy drift | `line_endings_check`, `changes_status`, `mustflow_check` | Policy found, drift files, normalization status, verification, and remaining line-ending risk |
173
179
  | External `SKILL.md` files, skill packs, awesome lists, GitHub skill repositories, installer recommendations, or third-party skill procedures are reviewed for possible mustflow adoption | `.mustflow/skills/external-skill-intake/SKILL.md` | Source path or URL, license or provenance evidence, external skill files, intended adoption outcome, existing skill overlap, and command contract entries | Skill procedures, skill routes, template metadata, tests, docs, and review notes that adapt the external idea | third-party command bypass, license or provenance gap, unsafe helper script, duplicated skill, stale source claim, or default-profile bloat | `changes_status`, `changes_diff_summary`, `docs_validate_fast`, `test_release`, `mustflow_check` | Source review, overlap decision, safety findings, command-intent mapping, adoption decision, synchronized surfaces, verification, and remaining intake risk |