mustflow 2.115.1 → 2.115.4
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/lib/local-index/constants.js +1 -1
- package/dist/cli/lib/local-index/freshness.js +65 -35
- package/dist/cli/lib/local-index/index.js +26 -9
- package/dist/cli/lib/local-index/populate.js +4 -1
- package/dist/cli/lib/local-index/schema.js +10 -0
- package/dist/cli/lib/local-index/source-index.js +43 -11
- package/package.json +1 -1
- package/templates/default/i18n.toml +3 -3
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +3 -3
- package/templates/default/locales/en/.mustflow/skills/dependency-reality-check/SKILL.md +83 -10
- package/templates/default/locales/en/.mustflow/skills/module-boundary-review/SKILL.md +66 -7
- package/templates/default/locales/en/.mustflow/skills/routes.toml +2 -2
- package/templates/default/manifest.toml +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const LOCAL_INDEX_SCHEMA_VERSION = '
|
|
1
|
+
export const LOCAL_INDEX_SCHEMA_VERSION = '21';
|
|
2
2
|
export const LOCAL_INDEX_PARSER_VERSION = '1';
|
|
3
3
|
export const DEFAULT_DATABASE_RELATIVE_PATH = '.mustflow/cache/mustflow.sqlite';
|
|
4
4
|
export const LATEST_RUN_STATE_RELATIVE_PATH = '.mustflow/state/runs/latest.json';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { LOCAL_INDEX_SCHEMA_VERSION } from './constants.js';
|
|
1
|
+
import { DEFAULT_DATABASE_RELATIVE_PATH, LOCAL_INDEX_SCHEMA_VERSION } from './constants.js';
|
|
2
2
|
import { hasTable, queryRows, readMetadataValue, toSearchString } from './database-read.js';
|
|
3
|
-
import { normalizeIndexedFileSourceScope, readIndexedFileRecord } from './source-index.js';
|
|
3
|
+
import { collectSourceAnchorCandidatePaths, getSourceScopeHash, normalizeIndexedFileSourceScope, readIndexedFileRecord, readLocalIndexSourceConfig, } from './source-index.js';
|
|
4
4
|
import { collectDocuments } from './workflow-documents.js';
|
|
5
5
|
export function readStoredSchemaVersion(database) {
|
|
6
6
|
return readMetadataValue(database, 'schema_version');
|
|
@@ -11,46 +11,76 @@ export function getStalePaths(projectRoot, database, options = {}) {
|
|
|
11
11
|
if (schemaVersion !== LOCAL_INDEX_SCHEMA_VERSION) {
|
|
12
12
|
return ['.mustflow/cache/mustflow.sqlite'];
|
|
13
13
|
}
|
|
14
|
-
if (hasTable(database, 'indexed_files')
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
if (!hasTable(database, 'indexed_files') ||
|
|
15
|
+
!hasTable(database, 'indexed_source_candidates') ||
|
|
16
|
+
!hasTable(database, 'source_anchors') ||
|
|
17
|
+
!hasTable(database, 'source_anchor_status')) {
|
|
18
|
+
return [DEFAULT_DATABASE_RELATIVE_PATH];
|
|
19
|
+
}
|
|
20
|
+
const stalePaths = new Set();
|
|
21
|
+
const indexedRows = queryRows(database, 'SELECT path, source_scope, content_hash FROM indexed_files');
|
|
22
|
+
const indexedPaths = new Set(indexedRows.map((row) => toSearchString(row.path)));
|
|
23
|
+
const indexedSourcePaths = new Set(queryRows(database, 'SELECT path FROM indexed_source_candidates').map((row) => toSearchString(row.path)));
|
|
24
|
+
for (const sourcePath of indexedSourcePaths) {
|
|
25
|
+
if (!indexedPaths.has(sourcePath)) {
|
|
26
|
+
stalePaths.add(sourcePath);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const row of indexedRows) {
|
|
30
|
+
const indexedPath = toSearchString(row.path);
|
|
31
|
+
const sourceScope = normalizeIndexedFileSourceScope(toSearchString(row.source_scope));
|
|
32
|
+
if (!includeState && sourceScope === 'state') {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const current = readIndexedFileRecord(projectRoot, indexedPath, sourceScope);
|
|
37
|
+
if (current.contentHash !== toSearchString(row.content_hash)) {
|
|
31
38
|
stalePaths.add(indexedPath);
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
stalePaths.add(document.path);
|
|
37
|
-
}
|
|
41
|
+
catch {
|
|
42
|
+
stalePaths.add(indexedPath);
|
|
38
43
|
}
|
|
39
|
-
return Array.from(stalePaths).sort((left, right) => left.localeCompare(right));
|
|
40
44
|
}
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const currentHashes = new Map(currentDocuments.map((document) => [document.path, document.contentHash]));
|
|
45
|
-
const stalePaths = new Set();
|
|
46
|
-
for (const [indexedPath, indexedHash] of indexedHashes) {
|
|
47
|
-
if (currentHashes.get(indexedPath) !== indexedHash) {
|
|
48
|
-
stalePaths.add(indexedPath);
|
|
45
|
+
for (const document of collectDocuments(projectRoot)) {
|
|
46
|
+
if (!indexedPaths.has(document.path)) {
|
|
47
|
+
stalePaths.add(document.path);
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const sourceIndexEnabledValue = readMetadataValue(database, 'source_index_enabled');
|
|
51
|
+
if (sourceIndexEnabledValue !== 'true' && sourceIndexEnabledValue !== 'false') {
|
|
52
|
+
stalePaths.add(DEFAULT_DATABASE_RELATIVE_PATH);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const sourceIndexEnabled = sourceIndexEnabledValue === 'true';
|
|
56
|
+
const hasIndexedSourceScope = indexedRows.some((row) => normalizeIndexedFileSourceScope(toSearchString(row.source_scope)) === 'source_anchor');
|
|
57
|
+
const hasSourceAnchorRows = hasTable(database, 'source_anchors') && queryRows(database, 'SELECT id FROM source_anchors LIMIT 1').length > 0;
|
|
58
|
+
if (!sourceIndexEnabled && (indexedSourcePaths.size > 0 || hasIndexedSourceScope || hasSourceAnchorRows)) {
|
|
59
|
+
stalePaths.add(DEFAULT_DATABASE_RELATIVE_PATH);
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const sourceConfig = readLocalIndexSourceConfig(projectRoot);
|
|
63
|
+
const storedSourceScopeHash = readMetadataValue(database, 'source_scope_hash');
|
|
64
|
+
const currentSourceScopeHash = getSourceScopeHash(sourceIndexEnabled, sourceConfig);
|
|
65
|
+
if (storedSourceScopeHash !== currentSourceScopeHash) {
|
|
66
|
+
stalePaths.add(DEFAULT_DATABASE_RELATIVE_PATH);
|
|
67
|
+
}
|
|
68
|
+
if (sourceIndexEnabled) {
|
|
69
|
+
const currentSourcePaths = new Set(collectSourceAnchorCandidatePaths(projectRoot, sourceConfig));
|
|
70
|
+
for (const sourcePath of currentSourcePaths) {
|
|
71
|
+
if (!indexedSourcePaths.has(sourcePath)) {
|
|
72
|
+
stalePaths.add(sourcePath);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const sourcePath of indexedSourcePaths) {
|
|
76
|
+
if (!currentSourcePaths.has(sourcePath)) {
|
|
77
|
+
stalePaths.add(sourcePath);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
stalePaths.add(DEFAULT_DATABASE_RELATIVE_PATH);
|
|
54
84
|
}
|
|
55
85
|
}
|
|
56
86
|
return Array.from(stalePaths).sort((left, right) => left.localeCompare(right));
|
|
@@ -158,6 +158,14 @@ function indexedFilesMatch(database, currentFiles) {
|
|
|
158
158
|
}
|
|
159
159
|
return true;
|
|
160
160
|
}
|
|
161
|
+
function indexedSourceCandidatesMatch(database, currentPaths) {
|
|
162
|
+
if (!hasTable(database, 'indexed_source_candidates')) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
const storedPaths = new Set(queryRows(database, 'SELECT path FROM indexed_source_candidates').map((row) => toSearchString(row.path)));
|
|
166
|
+
const currentPathSet = new Set(currentPaths);
|
|
167
|
+
return storedPaths.size === currentPathSet.size && [...storedPaths].every((storedPath) => currentPathSet.has(storedPath));
|
|
168
|
+
}
|
|
161
169
|
const INDEXED_FILE_MTIME_TOLERANCE_MS = 1;
|
|
162
170
|
function indexedFileMtimeMsEqual(storedMtimeMs, currentMtimeMs) {
|
|
163
171
|
return storedMtimeMs !== null && Math.abs(storedMtimeMs - currentMtimeMs) <= INDEXED_FILE_MTIME_TOLERANCE_MS;
|
|
@@ -183,8 +191,8 @@ function indexedFileMetadataMatch(database, currentFiles) {
|
|
|
183
191
|
}
|
|
184
192
|
return true;
|
|
185
193
|
}
|
|
186
|
-
async function readIncrementalPreflightReuse(SQL, databasePath, projectRoot, currentFiles, sourceScopeHash, dryRun, indexMode) {
|
|
187
|
-
if (!currentFiles) {
|
|
194
|
+
async function readIncrementalPreflightReuse(SQL, databasePath, projectRoot, currentFiles, currentSourceCandidatePaths, sourceScopeHash, dryRun, indexMode) {
|
|
195
|
+
if (!currentFiles || !currentSourceCandidatePaths) {
|
|
188
196
|
return { result: null, rebuildReason: null };
|
|
189
197
|
}
|
|
190
198
|
if (!existsSync(databasePath)) {
|
|
@@ -205,6 +213,9 @@ async function readIncrementalPreflightReuse(SQL, databasePath, projectRoot, cur
|
|
|
205
213
|
if (!hasTable(database, 'indexed_files')) {
|
|
206
214
|
return { result: null, rebuildReason: 'indexed_files_missing' };
|
|
207
215
|
}
|
|
216
|
+
if (!indexedSourceCandidatesMatch(database, currentSourceCandidatePaths)) {
|
|
217
|
+
return { result: null, rebuildReason: 'source_scope_mismatch' };
|
|
218
|
+
}
|
|
208
219
|
if (!indexedFileMetadataMatch(database, currentFiles)) {
|
|
209
220
|
return { result: null, rebuildReason: 'file_fingerprint_mismatch' };
|
|
210
221
|
}
|
|
@@ -225,7 +236,7 @@ async function readIncrementalPreflightReuse(SQL, databasePath, projectRoot, cur
|
|
|
225
236
|
database?.close();
|
|
226
237
|
}
|
|
227
238
|
}
|
|
228
|
-
async function readIncrementalReuseDecision(SQL, databasePath, currentFiles, sourceScopeHash) {
|
|
239
|
+
async function readIncrementalReuseDecision(SQL, databasePath, currentFiles, currentSourceCandidatePaths, sourceScopeHash) {
|
|
229
240
|
if (!existsSync(databasePath)) {
|
|
230
241
|
return { reusable: false, rebuildReason: 'missing_index', capabilities: null };
|
|
231
242
|
}
|
|
@@ -244,6 +255,9 @@ async function readIncrementalReuseDecision(SQL, databasePath, currentFiles, sou
|
|
|
244
255
|
if (!hasTable(database, 'indexed_files')) {
|
|
245
256
|
return { reusable: false, rebuildReason: 'indexed_files_missing', capabilities: null };
|
|
246
257
|
}
|
|
258
|
+
if (!indexedSourceCandidatesMatch(database, currentSourceCandidatePaths)) {
|
|
259
|
+
return { reusable: false, rebuildReason: 'source_scope_mismatch', capabilities: null };
|
|
260
|
+
}
|
|
247
261
|
if (!indexedFilesMatch(database, currentFiles)) {
|
|
248
262
|
return { reusable: false, rebuildReason: 'file_fingerprint_mismatch', capabilities: null };
|
|
249
263
|
}
|
|
@@ -284,7 +298,7 @@ export async function createLocalIndex(projectRoot, options = {}) {
|
|
|
284
298
|
capabilityDatabase.close();
|
|
285
299
|
if (incremental) {
|
|
286
300
|
const preflightFiles = collectFastPreflightIndexedFileMetadataRecords(projectRoot, includeSource, sourceConfig);
|
|
287
|
-
const preflightReuse = await readIncrementalPreflightReuse(SQL, databasePath, projectRoot, preflightFiles, sourceScopeHash, dryRun, indexMode);
|
|
301
|
+
const preflightReuse = await readIncrementalPreflightReuse(SQL, databasePath, projectRoot, preflightFiles?.records ?? null, preflightFiles?.sourceCandidatePaths ?? null, sourceScopeHash, dryRun, indexMode);
|
|
288
302
|
if (preflightReuse.result) {
|
|
289
303
|
return preflightReuse.result;
|
|
290
304
|
}
|
|
@@ -307,16 +321,16 @@ export async function createLocalIndex(projectRoot, options = {}) {
|
|
|
307
321
|
const verificationEvidence = createVerificationEvidenceIndex(projectRoot);
|
|
308
322
|
const indexedFiles = collectIndexedFileRecords(projectRoot, documents, sourceAnchors, sourceAnchorCandidatePaths);
|
|
309
323
|
if (incremental) {
|
|
310
|
-
const reuseDecision = await readIncrementalReuseDecision(SQL, databasePath, indexedFiles, sourceScopeHash);
|
|
324
|
+
const reuseDecision = await readIncrementalReuseDecision(SQL, databasePath, indexedFiles, sourceAnchorCandidatePaths, sourceScopeHash);
|
|
311
325
|
reusedExisting = reuseDecision.reusable;
|
|
312
|
-
rebuildReason = reuseDecision.rebuildReason ?? rebuildReason;
|
|
326
|
+
rebuildReason = reuseDecision.reusable ? null : (reuseDecision.rebuildReason ?? rebuildReason);
|
|
313
327
|
capabilities = reuseDecision.capabilities ?? capabilities;
|
|
314
328
|
}
|
|
315
329
|
if (!dryRun && !reusedExisting) {
|
|
316
330
|
const database = new SQL.Database();
|
|
317
331
|
try {
|
|
318
332
|
createSchema(database, capabilities);
|
|
319
|
-
populateDatabase(database, capabilities, documents, skills, skillRoutes, commandIntents, sourceAnchors, indexedFiles, verificationEvidence, indexMode, sourceScopeHash, includeSource, new Date().toISOString());
|
|
333
|
+
populateDatabase(database, capabilities, documents, skills, skillRoutes, commandIntents, sourceAnchors, indexedFiles, sourceAnchorCandidatePaths, verificationEvidence, indexMode, sourceScopeHash, includeSource, new Date().toISOString());
|
|
320
334
|
writeFileInsideWithoutSymlinks(projectRoot, databasePath, database.export());
|
|
321
335
|
}
|
|
322
336
|
finally {
|
|
@@ -702,10 +716,13 @@ export async function readLocalSourceAnchorCheckWarnings(projectRoot) {
|
|
|
702
716
|
if (readMetadataValue(database, 'source_index_enabled') !== 'true') {
|
|
703
717
|
return [];
|
|
704
718
|
}
|
|
705
|
-
if (!hasTable(database, 'indexed_files') ||
|
|
719
|
+
if (!hasTable(database, 'indexed_files') ||
|
|
720
|
+
!hasTable(database, 'indexed_source_candidates') ||
|
|
721
|
+
!hasTable(database, 'source_anchors') ||
|
|
722
|
+
!hasTable(database, 'source_anchor_status')) {
|
|
706
723
|
return ['source anchor local index is missing source-anchor tables; refresh with mf index --source'];
|
|
707
724
|
}
|
|
708
|
-
const indexedSourcePaths = new Set(queryRows(database, 'SELECT path FROM
|
|
725
|
+
const indexedSourcePaths = new Set(queryRows(database, 'SELECT path FROM indexed_source_candidates')
|
|
709
726
|
.map((row) => toSearchString(row.path))
|
|
710
727
|
.filter(Boolean));
|
|
711
728
|
const staleSourcePaths = getStalePaths(projectRoot, database, { includeState: false }).filter((stalePath) => indexedSourcePaths.has(stalePath));
|
|
@@ -172,7 +172,7 @@ function rollbackTransaction(database) {
|
|
|
172
172
|
// Keep the original indexing failure as the actionable error.
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
export function populateDatabase(database, capabilities, documents, skills, skillRoutes, commandIntents, sourceAnchors, indexedFiles, verificationEvidence, indexMode, sourceScopeHash, sourceIndexEnabled, indexedAt) {
|
|
175
|
+
export function populateDatabase(database, capabilities, documents, skills, skillRoutes, commandIntents, sourceAnchors, indexedFiles, indexedSourceCandidates, verificationEvidence, indexMode, sourceScopeHash, sourceIndexEnabled, indexedAt) {
|
|
176
176
|
const sourceAnchorRiskSignals = createSourceAnchorRiskSignals(sourceAnchors);
|
|
177
177
|
database.run('BEGIN TRANSACTION');
|
|
178
178
|
try {
|
|
@@ -223,6 +223,9 @@ export function populateDatabase(database, capabilities, documents, skills, skil
|
|
|
223
223
|
LOCAL_INDEX_PARSER_VERSION,
|
|
224
224
|
]);
|
|
225
225
|
}
|
|
226
|
+
for (const sourceCandidatePath of indexedSourceCandidates) {
|
|
227
|
+
database.run('INSERT INTO indexed_source_candidates (path) VALUES (?)', [sourceCandidatePath]);
|
|
228
|
+
}
|
|
226
229
|
for (const document of documents) {
|
|
227
230
|
database.run('INSERT INTO documents (path, type, title, locale, revision, content_hash, content_snippet) VALUES (?, ?, ?, ?, ?, ?, ?)', [
|
|
228
231
|
document.path,
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { SEARCH_BACKEND_FTS5 } from './constants.js';
|
|
2
2
|
export function createSchema(database, capabilities) {
|
|
3
|
+
database.run('PRAGMA foreign_keys = ON');
|
|
4
|
+
const [foreignKeyResult] = database.exec('PRAGMA foreign_keys');
|
|
5
|
+
if (foreignKeyResult?.values[0]?.[0] !== 1) {
|
|
6
|
+
throw new Error('SQLite foreign-key enforcement is unavailable for the local index.');
|
|
7
|
+
}
|
|
3
8
|
database.run(`
|
|
4
9
|
CREATE TABLE metadata (
|
|
5
10
|
key TEXT PRIMARY KEY,
|
|
@@ -17,6 +22,11 @@ CREATE TABLE indexed_files (
|
|
|
17
22
|
parser_version TEXT NOT NULL
|
|
18
23
|
);
|
|
19
24
|
|
|
25
|
+
CREATE TABLE indexed_source_candidates (
|
|
26
|
+
path TEXT PRIMARY KEY,
|
|
27
|
+
FOREIGN KEY (path) REFERENCES indexed_files(path) ON UPDATE RESTRICT ON DELETE RESTRICT
|
|
28
|
+
);
|
|
29
|
+
|
|
20
30
|
CREATE TABLE documents (
|
|
21
31
|
path TEXT PRIMARY KEY,
|
|
22
32
|
type TEXT NOT NULL,
|
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
import { existsSync,
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { isRecord, readStringArray } from '../command-contract.js';
|
|
4
|
+
import { MUSTFLOW_TEXT_MAX_BYTES, mustflowProjectPath } from '../mustflow-read.js';
|
|
4
5
|
import { readMustflowTomlFile } from '../toml.js';
|
|
6
|
+
import { ensureInsideWithoutSymlinks, readFileInsideWithoutSymlinks } from '../../../core/safe-filesystem.js';
|
|
5
7
|
import { listSourceAnchorFiles } from '../../../core/source-anchors.js';
|
|
6
8
|
import { INDEX_CONFIG_RELATIVE_PATH, LATEST_RUN_STATE_RELATIVE_PATH, MUSTFLOW_RELATIVE_PATH, SOURCE_INDEX_MAX_FILE_BYTES, } from './constants.js';
|
|
7
9
|
import { sha256Bytes, sha256Text } from './hashing.js';
|
|
8
10
|
import { getExistingIndexablePaths } from './workflow-documents.js';
|
|
11
|
+
function indexedProjectPath(projectRoot, relativePath) {
|
|
12
|
+
if (relativePath.length === 0 ||
|
|
13
|
+
relativePath.includes('\0') ||
|
|
14
|
+
relativePath.includes('\\') ||
|
|
15
|
+
path.posix.isAbsolute(relativePath) ||
|
|
16
|
+
path.win32.isAbsolute(relativePath)) {
|
|
17
|
+
throw new Error(`Indexed file path must be a canonical project-relative path: ${relativePath}`);
|
|
18
|
+
}
|
|
19
|
+
const segments = relativePath.split('/');
|
|
20
|
+
if (segments.some((segment) => segment.length === 0 || segment === '.' || segment === '..')) {
|
|
21
|
+
throw new Error(`Indexed file path must be a canonical project-relative path: ${relativePath}`);
|
|
22
|
+
}
|
|
23
|
+
const fullPath = mustflowProjectPath(projectRoot, relativePath);
|
|
24
|
+
ensureInsideWithoutSymlinks(projectRoot, fullPath);
|
|
25
|
+
return fullPath;
|
|
26
|
+
}
|
|
27
|
+
function readIndexedFileBytes(projectRoot, relativePath) {
|
|
28
|
+
return readFileInsideWithoutSymlinks(projectRoot, indexedProjectPath(projectRoot, relativePath), {
|
|
29
|
+
maxBytes: MUSTFLOW_TEXT_MAX_BYTES,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
9
32
|
function readIndexToml(projectRoot) {
|
|
10
33
|
const indexConfigPath = path.join(projectRoot, ...INDEX_CONFIG_RELATIVE_PATH.split('/'));
|
|
11
34
|
if (!existsSync(indexConfigPath)) {
|
|
@@ -69,13 +92,13 @@ export function readIndexedFileRecord(projectRoot, relativePath, sourceScope, co
|
|
|
69
92
|
const metadata = readIndexedFileMetadataRecord(projectRoot, relativePath, sourceScope);
|
|
70
93
|
return {
|
|
71
94
|
...metadata,
|
|
72
|
-
contentHash: contentHash ?? sha256Bytes(
|
|
95
|
+
contentHash: contentHash ?? sha256Bytes(readIndexedFileBytes(projectRoot, relativePath)),
|
|
73
96
|
};
|
|
74
97
|
}
|
|
75
98
|
function hashIndexedFileMetadataRecord(projectRoot, metadata) {
|
|
76
99
|
return {
|
|
77
100
|
...metadata,
|
|
78
|
-
contentHash: sha256Bytes(
|
|
101
|
+
contentHash: sha256Bytes(readIndexedFileBytes(projectRoot, metadata.path)),
|
|
79
102
|
};
|
|
80
103
|
}
|
|
81
104
|
function tryHashIndexedFileMetadataRecord(projectRoot, metadata) {
|
|
@@ -92,8 +115,11 @@ export function hashIndexedFileMetadataRecords(projectRoot, metadataRecords) {
|
|
|
92
115
|
.filter((record) => Boolean(record));
|
|
93
116
|
}
|
|
94
117
|
export function readIndexedFileMetadataRecord(projectRoot, relativePath, sourceScope) {
|
|
95
|
-
const fullPath =
|
|
118
|
+
const fullPath = indexedProjectPath(projectRoot, relativePath);
|
|
96
119
|
const stats = statSync(fullPath);
|
|
120
|
+
if (!stats.isFile()) {
|
|
121
|
+
throw new Error(`Indexed path must be a regular file: ${relativePath}`);
|
|
122
|
+
}
|
|
97
123
|
return {
|
|
98
124
|
path: relativePath,
|
|
99
125
|
sourceScope,
|
|
@@ -117,10 +143,7 @@ export function collectIndexedFileRecords(projectRoot, documents, sourceAnchors,
|
|
|
117
143
|
const sourcePaths = new Set([...sourceAnchorCandidatePaths, ...sourceAnchors.map((anchor) => anchor.path)]);
|
|
118
144
|
for (const anchorPath of [...sourcePaths].sort((left, right) => left.localeCompare(right))) {
|
|
119
145
|
if (!records.has(anchorPath)) {
|
|
120
|
-
|
|
121
|
-
if (record) {
|
|
122
|
-
records.set(anchorPath, record);
|
|
123
|
-
}
|
|
146
|
+
records.set(anchorPath, readIndexedFileRecord(projectRoot, anchorPath, 'source_anchor'));
|
|
124
147
|
}
|
|
125
148
|
}
|
|
126
149
|
if (existsSync(path.join(projectRoot, ...LATEST_RUN_STATE_RELATIVE_PATH.split('/')))) {
|
|
@@ -132,19 +155,25 @@ export function collectIndexedFileRecords(projectRoot, documents, sourceAnchors,
|
|
|
132
155
|
return [...records.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
133
156
|
}
|
|
134
157
|
export function collectSourceAnchorCandidatePaths(projectRoot, sourceConfig) {
|
|
135
|
-
|
|
158
|
+
const paths = listSourceAnchorFiles(projectRoot, {
|
|
136
159
|
...sourceConfig,
|
|
137
160
|
excludeGeneratedOrVendor: true,
|
|
138
161
|
});
|
|
162
|
+
for (const relativePath of paths) {
|
|
163
|
+
indexedProjectPath(projectRoot, relativePath);
|
|
164
|
+
}
|
|
165
|
+
return paths;
|
|
139
166
|
}
|
|
140
167
|
export function collectFastPreflightIndexedFileMetadataRecords(projectRoot, includeSource, sourceConfig) {
|
|
141
168
|
const records = new Map();
|
|
169
|
+
let sourceCandidatePaths = [];
|
|
142
170
|
for (const relativePath of getExistingIndexablePaths(projectRoot)) {
|
|
143
171
|
records.set(relativePath, readIndexedFileMetadataRecord(projectRoot, relativePath, 'workflow'));
|
|
144
172
|
}
|
|
145
173
|
if (includeSource) {
|
|
146
174
|
try {
|
|
147
|
-
|
|
175
|
+
sourceCandidatePaths = collectSourceAnchorCandidatePaths(projectRoot, sourceConfig);
|
|
176
|
+
for (const sourcePath of sourceCandidatePaths) {
|
|
148
177
|
if (!records.has(sourcePath)) {
|
|
149
178
|
records.set(sourcePath, readIndexedFileMetadataRecord(projectRoot, sourcePath, 'source_anchor'));
|
|
150
179
|
}
|
|
@@ -157,5 +186,8 @@ export function collectFastPreflightIndexedFileMetadataRecords(projectRoot, incl
|
|
|
157
186
|
if (existsSync(path.join(projectRoot, ...LATEST_RUN_STATE_RELATIVE_PATH.split('/')))) {
|
|
158
187
|
records.set(LATEST_RUN_STATE_RELATIVE_PATH, readIndexedFileMetadataRecord(projectRoot, LATEST_RUN_STATE_RELATIVE_PATH, 'state'));
|
|
159
188
|
}
|
|
160
|
-
return
|
|
189
|
+
return {
|
|
190
|
+
records: [...records.values()].sort((left, right) => left.path.localeCompare(right.path)),
|
|
191
|
+
sourceCandidatePaths,
|
|
192
|
+
};
|
|
161
193
|
}
|
package/package.json
CHANGED
|
@@ -62,7 +62,7 @@ translations = {}
|
|
|
62
62
|
[documents."skills.index"]
|
|
63
63
|
source = "locales/en/.mustflow/skills/INDEX.md"
|
|
64
64
|
source_locale = "en"
|
|
65
|
-
revision =
|
|
65
|
+
revision = 228
|
|
66
66
|
translations = {}
|
|
67
67
|
|
|
68
68
|
[documents."skill.adapter-boundary"]
|
|
@@ -146,7 +146,7 @@ translations = {}
|
|
|
146
146
|
[documents."skill.module-boundary-review"]
|
|
147
147
|
source = "locales/en/.mustflow/skills/module-boundary-review/SKILL.md"
|
|
148
148
|
source_locale = "en"
|
|
149
|
-
revision =
|
|
149
|
+
revision = 5
|
|
150
150
|
translations = {}
|
|
151
151
|
|
|
152
152
|
[documents."skill.change-blast-radius-review"]
|
|
@@ -589,7 +589,7 @@ translations = {}
|
|
|
589
589
|
[documents."skill.dependency-reality-check"]
|
|
590
590
|
source = "locales/en/.mustflow/skills/dependency-reality-check/SKILL.md"
|
|
591
591
|
source_locale = "en"
|
|
592
|
-
revision =
|
|
592
|
+
revision = 9
|
|
593
593
|
translations = {}
|
|
594
594
|
|
|
595
595
|
[documents."skill.dependency-upgrade-review"]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
mustflow_doc: skills.index
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 228
|
|
6
6
|
authority: router
|
|
7
7
|
lifecycle: mustflow-owned
|
|
8
8
|
---
|
|
@@ -547,7 +547,7 @@ routes. Event routes stay inactive until their event occurs.
|
|
|
547
547
|
| Browser automation, UI automation, Playwright, Selenium, Puppeteer, WebDriver, computer-use or browser-driving agents, visual browser verification, flaky selectors, page readiness, authentication state, CAPTCHA or anti-bot handling, rate limits, screenshot checks, retry, timeout, human approval, or browser automation observability is created, changed, reviewed, triaged, or reported | `.mustflow/skills/browser-automation-reliability-review/SKILL.md` | Automation intent ledger, state ledger, readiness ledger, selector and action ledger, auth and identity ledger, external pressure ledger, verification ledger, agent and approval ledger, changed files, and command contract entries | Browser automation state machines, locator contracts, test IDs, accessible names, readiness assertions, frame and popup handlers, input verification, auth fixtures, per-worker account isolation, retry classification, timeout hierarchy, idempotency checks, rate-limit handling, approval gates, manual fallback states, traces, screenshots, redaction, cleanup, tests, docs, route metadata, and directly synchronized templates | sleep-as-readiness, `networkidle` faith, flaky selector string patch, hidden duplicate DOM, skeleton-as-content, stale element handle, force-click default, shared mutable account, CAPTCHA bypass, anti-bot evasion, retry storm, non-idempotent replay, timeout layer mismatch, screenshot-as-business-proof, unredacted trace data, page prompt injection, stale approval resume, coordinate click drift, or unverified browser success claim | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Browser automation surface reviewed, browser-versus-API boundary, automation owner, state/readiness/locator/actionability/auth/rate-limit/retry/timeout/idempotency decisions, screenshot and business-success evidence, agent page-content trust, approval and resume checks, verification, and remaining browser automation reliability risk |
|
|
548
548
|
| Agent evaluation loops, trace or trajectory grading, LLM judges, verifier agents, outcome scoring, tool-call prechecks or postchecks, eval datasets, golden or dirty sets, pass@k or pass^k metrics, shadow environments, production-monitoring-to-eval pipelines, or agent regression gates are created, changed, reviewed, or reported | `.mustflow/skills/agent-eval-integrity-review/SKILL.md` | Outcome ledger, trace ledger, oracle ledger, tool-boundary ledger, dataset ledger, metric ledger, environment ledger, monitoring ledger, privacy ledger, changed files, and command contract entries | Outcome oracles, trace schemas, trajectory graders, deterministic checkers, model-judge rubrics, human-review sampling, tool prechecks and postchecks, tool-result evidence packets, eval fixtures, golden and dirty sets, shadow-environment adapters, monitoring-to-eval candidate flows, tests, docs, route metadata, and directly synchronized templates | final-answer-only scoring, LLM judge as sole oracle, reasoning claim treated as evidence, self-reflection certifying success, missing final environment state, ungraded unsafe trajectory, missing tool precheck or postcheck, brittle exact tool-order assertion, uncalibrated judge drift, pass@k masking unreliable pass^k, dirty set gating flakiness, raw trace data leak, or production failure not entering evals | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Agent eval-integrity surface reviewed, outcome oracle, final-state and trajectory checks, deterministic/model/human oracle split, tool boundary evidence, golden/dirty/capability/regression metrics, shadow environment, monitoring-to-eval loop, trace privacy, verification, and remaining agent eval-integrity risk |
|
|
549
549
|
| Code review or implementation needs abstraction-boundary triage for deciding whether a helper, interface, adapter, service, policy object, strategy, mapper, DTO, base class, component, or shared module should exist, stay duplicated, be inlined, move side effects out of the core path, preserve layer import contracts, or delete generated boilerplate after refactoring | `.mustflow/skills/abstraction-boundary-review/SKILL.md` | User goal, current diff or target files, change-reason ledger, future-change scenarios, domain vocabulary, ownership map, candidate boundary ledger, public-promise ledger, side-effect ledger, test-shape ledger, layer-contract ledger, layer-integrity ledger, type-existence ledger, public-contract ledger, existing helpers or patterns, and configured command intents | Local abstractions, deliberate duplication, policy owners, adapters, mappers, result or variant types, side-effect shells, capability-named ports, interface narrowing, pass-through layer removal, import-direction repair, DTO or ORM boundary repair, exception translation, transaction-owner clarification, boilerplate deletion, behavior-focused tests, route metadata, and directly synchronized docs or templates | visual-duplication DRY, different domain meanings merged, one-caller interface theater, vague Service, Manager, Helper, Util, Common, Base, or Abstract names, future-only interfaces, fake DDD for CRUD, mode flag helper, excessive DTO conversion, provider error erasure, DI or config larger than logic, hidden proxy or event-bus work, scattered business rule, external SDK or DB row leakage, full-server policy tests, raw payloads deep in app code, provider errors leaking outward, hardcoded policy values, dependency direction inversion, domain importing infrastructure, application importing concrete infrastructure, presentation calling repositories or gateways directly, public contract drift, transaction owner drift, or mocks on private choreography | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `test_audit`, `docs_validate_fast`, `test_release`, `mustflow_check` | Abstraction boundary reviewed, change reason and future scenarios, same-concept gate, candidates compared, public promise and owners, layer dependency contract, layer-integrity report, type-existence and deletion-pass result, over- and under-abstraction findings, test shape, verification, and remaining reversibility risk |
|
|
550
|
-
| Code review or implementation needs module-boundary triage for change spread, change axes, stability direction, co-change clusters, data ownership, policy ownership, failure ownership, import direction, circular dependencies, DTO leakage, shared/common/utils growth, mock-heavy tests, repeated policy conditions, enum interpretation, repository business logic, anemic domain, domain-to-I/O leakage, transaction boundary mismatch, technical event names, public module API bloat, caller sequencing, premature common helpers, bug/fix distance, config ownership, log responsibility, exception translation, cache invalidation ownership, repeated authorization checks, frontend/backend policy leakage, time policy, batch or worker bypass, shallow modules, or temporary-code accumulation | `.mustflow/skills/module-boundary-review/SKILL.md` | Change reason, change-axis ledger, changed-file spread, co-change evidence, module graph evidence, stability evidence, change-simulation evidence, ownership evidence, test evidence, and configured command intents | Policy ownership, DTO boundaries, mapper boundaries, module public APIs, import direction, config injection, exception translation, cache invalidation ownership, authorization checks, event facts, worker entrypoints, stability-direction repair, shallow-wrapper removal, focused tests, and directly synchronized docs or templates | layer-name theater, role-sliced files that always change together, technical layer split mistaken for change unit,
|
|
550
|
+
| Code review or implementation needs module-boundary triage for change spread, change axes, stability direction, co-change clusters, monorepo package direction, package roles, workspace tags, TypeScript path alias boundaries, compile-success versus allowed-dependency confusion, data ownership, policy ownership, failure ownership, import direction, cross-package deep imports, package exports, circular dependencies, DTO leakage, shared/common/utils growth, mock-heavy tests, repeated policy conditions, enum interpretation, repository business logic, anemic domain, domain-to-I/O leakage, transaction boundary mismatch, technical event names, public module API bloat, caller sequencing, premature common helpers, bug/fix distance, config ownership, log responsibility, exception translation, cache invalidation ownership, repeated authorization checks, frontend/backend policy leakage, time policy, batch or worker bypass, shallow modules, or temporary-code accumulation | `.mustflow/skills/module-boundary-review/SKILL.md` | Change reason, change-axis ledger, changed-file spread, co-change evidence, module and package graph evidence, package role and platform tags, `tsconfig.paths`, bundler and test resolver aliases, affected build/test graph evidence, deploy or prune artifact expectations, stability evidence, change-simulation evidence, ownership evidence, test evidence, and configured command intents | Policy ownership, DTO boundaries, mapper boundaries, module public APIs, package `exports`, import direction, workspace dependency direction, package tag constraints, path-alias reach-through repair, config injection, exception translation, cache invalidation ownership, authorization checks, event facts, worker entrypoints, stability-direction repair, shallow-wrapper removal, focused tests, and directly synchronized docs or templates | layer-name theater, role-sliced files that always change together, technical layer split mistaken for change unit, TypeScript path alias mistaken for an architecture boundary, compiling import treated as an authorized dependency, relative sibling package reach-through, app package imported by reusable code, stable package importing volatile app, route, database, provider, or UI details, feature-to-feature internal import, UI kit knowing business state, package deep import, broad export map, root barrel cycle, circular dependency, DTO infection, ownerless shared helper, broad `types` bucket, broad noun module, thin forwarding files, public API wider than hidden behavior, mock-heavy rule tests, copied policy condition, enum rule scatter, repository-owned business rule, service-only domain, domain I/O coupling, cross-owner transaction, table-change event, exposed internals, caller order dependency, unsafe reuse, repeated temporary branch, bug/fix distance, config chaos, misleading logs, leaked provider or DB errors, stale cache owner drift, copied auth checks, frontend reconstructing backend policy, inconsistent time rules, worker bypass, or random capability loss when a module is removed | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Module boundary reviewed, change-spread and co-change evidence, monorepo package graph evidence, resolver graph evidence, change simulations, stability direction, owner and import findings, shallow module findings, boundary fixes or recommendation, evidence level, verification, and remaining module-boundary risk |
|
|
551
551
|
| Code review or implementation needs change-blast-radius triage for maintainability risk from unpredictable next-change spread, historical co-change spread, one change reason scattered across files, multiple change reasons in one file, controller workflow leakage, junk-drawer service names, boolean mode flags, trash-can option objects, scattered domain rules, scattered authorization, hidden state transitions, direct time or randomness, unclear transaction boundaries, external API and DB coupling, retry without idempotency, cache-as-truth decisions, config flag combinations, tenant or partner hardcoding, legacy branches in the core path, DTO/entity/view model mixing, ambiguous nullable values, swallowed exceptions, low-context logs, implementation-coupled tests, mock-heavy tests, decorative abstractions, premature DRY, hidden ordering dependency, invisible event contracts, migration/runtime compatibility, or hard-to-delete features | `.mustflow/skills/change-blast-radius-review/SKILL.md` | User goal, current diff or target files, change-reason ledger, historical co-change ledger, blast-radius ledger, ownership ledger, deleteability ledger, test and operations evidence, and configured command intents | Policy ownership, workflow boundaries, explicit modes, option-object narrowing, authorization owner, state-transition owner, transaction and retry/idempotency boundaries, cache truth boundary, config and tenant variation isolation, legacy adapters, DTO mapping ownership, result types, traceable logs, behavior-focused tests, event contracts, migration compatibility notes, and directly synchronized docs or templates | clean-code theater, unpredictable edit spread, repeated cross-repo co-change, unrelated reasons in one file, controller as boss, junk-drawer service, boolean maze, option combinatorics, copied policy, copied auth, scattered status writes, hidden time or random, partial data after failure, duplicate side effect, stale cache authority, untested flag product, hardcoded customer branch, legacy core pollution, object-language mixing, nullable ambiguity, false success, useless logs, brittle process tests, five-mock class, decorative interface, wrong DRY, order-sensitive line shuffle, ghost event coupling, deploy gamble, or feature that cannot be deleted cleanly | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `test_audit`, `docs_validate_fast`, `test_release`, `mustflow_check` | Change blast radius reviewed, next likely change and owner, historical co-change evidence, spread and deletion path, maintainability findings, fixes or recommendation, verification, and remaining change-spread risk |
|
|
552
552
|
| Code review or implementation needs business-rule-leakage triage for money, permission, ownership, state, settlement, discount, coupon, refund, inventory, notification, subscription, visibility, eligibility, expiry, price, tax, fee, points, reports, tenant scope, UI-only guards, controller eligibility checks, direct status assignment, query predicates as policy, list/detail scope mismatch, admin path bypass, batch hidden policy, tests at the wrong layer, duplicated business constants, date or timezone policy drift, ambiguous `isActive` or `canUse`, authentication/authorization/eligibility mixing, ownership boundary drift, broad update DTOs, PATCH null semantics, mapper logic, default-value drift, misleading error messages, swallowed business failures, transaction/action mismatch, event timing, duplicate requests, webhook trust, out-of-order events, cache-as-rule, search index drift, report or settlement SQL, public text drift, or other bypass entrances | `.mustflow/skills/business-rule-leakage-review/SKILL.md` | User goal, current diff or target files, rule ledger, entrypoint ledger, enforcement ledger, consistency ledger, state/transaction/event/idempotency/default/error evidence, and configured command intents | Shared policy/domain/application/database rule owner, server-side enforcement, reusable query scopes, list/detail consistency, update field restrictions, PATCH intent models, mechanical mappers, default ownership, visible failures, transaction and event boundaries, idempotency, webhook verification, search/detail rechecks, report calculation owners, focused tests, and directly synchronized docs or templates | clean code with leaked money rule, client-only rule, controller judge, scattered status assignment, missing query predicate, URL detail bypass, admin bypass, batch bypass, misplaced test, magic policy number, timezone cutoff drift, vague helper meaning, auth/eligibility blur, user-vs-tenant ownership hole, mass update, PATCH null corruption, mapper policy, default mismatch, error-text lie, false success, half-committed business action, pre-commit event, duplicate refund or coupon use, trusted webhook, stale event transition, wrong cache viewer, dead search result, settlement query drift, support macro drift, or uninspected entrypoint | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `test_audit`, `docs_validate_fast`, `test_release`, `mustflow_check` | Business rule leakage reviewed, source of truth and entrypoints, enforcement and bypass findings, consistency notes, fixes or recommendation, verification, and remaining rule-leakage risk |
|
|
553
553
|
| Payment, checkout, authorization, capture, refund, partial refund, subscription, invoice, credit note, receipt, tax document, trial, grace period, coupon, promotion, inventory reservation, fulfillment, entitlement, settlement, fee, payout, chargeback, dispute, fraud review, card testing, provider webhook, payment session, payment link, payment-provider integration, admin manual payment change, payment log, PCI-sensitive data handling, or payment-related test needs payment-integrity triage for duplicate, late, out-of-order, wrong-actor, wrong-amount, wrong-currency, timeout, retry, idempotency, ledger, reconciliation, or audit risk | `.mustflow/skills/payment-integrity-review/SKILL.md` | User goal, current diff or target files, money-event ledger, provider interaction ledger, state-transition ledger, idempotency and uniqueness ledger, amount and currency ledger, invoice/receipt/tax ledger, dispute and fraud ledger, ownership ledger, fulfillment and entitlement ledger, webhook and retry ledger, audit and sensitive-data ledger, existing tests, and configured command intents | Payment state machines, server-side amount calculation, invoice and line-item snapshots, minor-unit money handling, tax snapshots and reversals, receipt delivery tracking, object ownership checks, idempotency keys, provider ID uniqueness, webhook raw-body signature verification, webhook event dedupe, queue handoff, one-time fulfillment, async payment handling, authorization/capture distinctions, refund/dispute/subscription transitions, inventory and coupon reservation, timeout and retry classification, payout reconciliation, append-only ledgers, secret and payment-data redaction, fraud and card-testing defenses, admin audit trails, stale payment endpoint cleanup notes, focused nightmare-path tests, and directly synchronized docs or templates | paid-boolean shortcut, client-trusted amount, wrong-owner order/payment/refund/subscription ID, amount drift, float money math, missing idempotency, per-retry UUID idempotency, missing provider uniqueness, duplicate webhook, out-of-order webhook, JSON-parsed webhook signature breakage, disabled webhook signature, success-page-as-proof, double fulfillment, async payment premature fulfillment, authorized-treated-as-captured, double refund, missing refund-dispute collision policy, missing tax reversal, receipt delivery gap, chargeback evidence gap, subscription period-only active check, inventory oversell, coupon double spend or lost coupon, timeout-treated-as-failure, blind retry, mutable ledger, payout-as-revenue confusion, card testing exposure, card data logging, test/live secret mix, unaudited admin override, stale payment API, or happy-path-only payment tests | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `test_audit`, `docs_validate_fast`, `test_release`, `mustflow_check` | Payment integrity reviewed, money-event/provider/state/idempotency/amount/invoice/receipt/tax/ownership/fulfillment/webhook/dispute/fraud/payout/audit map, findings, fixes or recommendation, nightmare-path evidence, verification, and remaining payment-integrity risk |
|
|
@@ -671,7 +671,7 @@ routes. Event routes stay inactive until their event occurs.
|
|
|
671
671
|
| Keyword search, full-text search, Elasticsearch, OpenSearch, Lucene-style indexing, search APIs, indexing pipelines, source maps, metadata taxonomy, negative metadata, exact keyword fields, aliases, bulk indexing, refresh visibility, analyzers, mappings, synonyms, autocomplete, pagination, shard failures, search quality, or search performance are created, changed, reviewed, or failing | `.mustflow/skills/search-index-integrity-review/SKILL.md` | Symptom classification, source-to-search ledger, query contract ledger, index contract ledger with taxonomy/source-map fields, metadata key budget, stable source/doc/chunk ids, lifecycle and effective-date fields, quality ledger, performance ledger, privacy ledger, changed files, and command contract entries | Search canaries, indexing ledgers, bulk item error handling, alias checks, mapping and analyzer fixtures, metadata taxonomy checks, frontmatter schema checks, controlled-vocabulary fixtures, exact-keyword fixtures, negative-metadata filters, filter-only versus LLM-visible metadata checks, exact-versus-full-text tests, tenant and permission filters, golden-set tests, synonym regression tests, pagination guards, query and miss-log metrics, docs, and directly synchronized templates | cluster-green theater, batch-level bulk success, source/index count illusion, write alias drift, partial shard result, direct/API/UI mismatch, wrong keyword/text field, analyzer drift, uncontrolled tag vocabulary, unbounded metadata keys, file path treated as status, synonym regression, negative metadata ignored, missing source map, stale index hash, rank eyeballing, profile misuse, query fingerprint leak, shard fan-out, cache-only benchmark, refresh overuse, segment merge backlog, disk watermark write block, deep pagination, oversized fetch, or private query/document leak | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Search index integrity reviewed, source-to-search/query/index/quality/performance/privacy ledgers, taxonomy/metadata-budget/exact-keyword/source-map/query-log findings, fix or recommendation, evidence level, verification, and remaining search-index risk |
|
|
672
672
|
| Vector search, semantic search, RAG retrieval, embedding generation, preprocessing, chunking, contextual headers, synthetic questions, chunk text variants, vector schema, collection, namespace, tenant, named vector, metadata payload, filter, ANN index, exact-versus-approximate search, hybrid search, reranking, recall, latency, quantization, HNSW, IVF, pgvector, Qdrant, Milvus, Weaviate, OpenSearch kNN, or retrieval golden-set behavior is created, changed, reviewed, or failing | `.mustflow/skills/vector-search-integrity-review/SKILL.md` | Retrieval symptom, query contract ledger, ingestion ledger with stable source/doc/chunk ids, parent document genealogy, text variants and hashes, quality ledger, performance ledger, privacy ledger, changed files, and command contract entries | Embedding, preprocessing, and chunker versioning, vector validation, deterministic ids, contextual retrieval headers, synthetic question fields, original/index/prompt/embedding text separation, namespace and tenant selection, metadata payload field typing, metadata indexes, ACL prefilters, filter construction, exact-search checks, ANN parameters, lexical safeguards for exact identifiers, hybrid score ledgers, RRF or MMR settings, reranker candidates, golden-set tests, synthetic fixtures, metrics, docs, and directly synchronized templates | vector-DB scapegoating, wrong embedding dimension, model revision drift, contextual retrieval text treated as source, synthetic question cited as evidence, unstable source/doc/chunk lineage, tiny chunk subject loss, huge chunk semantic averaging, overlap top-k duplication, filter post-candidate loss, metadata type drift, ACL applied after retrieval, tenant leak, duplicate chunk ids, stale deletes, content hash or embedding hash drift, metric or normalization mismatch, ANN tuning before exact-search proof, quantization recall loss, reranker candidate starvation, hybrid score misuse, exact identifiers smoothed into embedding-only text, deep ANN pagination, raw vector or document leak, or unmeasured p95 latency | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Vector search integrity reviewed, retrieval/query/ingestion/quality/performance/privacy ledgers, exact-versus-ANN/filter/text-variant/contextual-header/lineage/hybrid/rerank findings, fix or recommendation, evidence level, verification, and remaining vector-search risk |
|
|
673
673
|
| Dependency versions, lockfiles, package-manager metadata, workspace constraints, runtime engines, peer dependencies, optional dependencies, security advisory fixes, vulnerability scanner alerts, generated dependency output, framework plugins, dev servers, test runners, TypeScript compiler tracks, CI actions, Docker base images, package manager behavior, or toolchain versions are upgraded, downgraded, pinned, widened, regenerated, reviewed, or reported | `.mustflow/skills/dependency-upgrade-review/SKILL.md` | Dependency name, old and new versions or ranges, direct or transitive path, ecosystem and package manager, declaration files, lockfiles, runtime or toolchain files, advisory or release-note evidence, exploit preconditions, generated outputs, callers, docs, package output, Docker, CI, dev-server or test-UI exposure, protocol role, or TypeScript compiler-track surfaces, and command contract entries | Package declarations, lockfiles, generated outputs, compatibility code, tests, docs, package metadata, Docker or CI files, dev-server/test-runner config notes, TypeScript compiler-track notes, and directly synchronized examples | lockfile churn, hidden transitive replacement, peer or engine break, module-format drift, native or optional package break, framework or generator output drift, devDependency advisory dismissed despite exposure, unsafe broad security update, weakened tests, Docker or CI runtime drift, protocol DoS misclassified, TS7 RC over-adoption, TS7 nightly over-adoption, or unreviewed supply-chain change | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `docs_validate_fast`, `test_release`, `mustflow_check` | Upgrade reason, ecosystem surface, direct and transitive graph changes, compatibility classification, runtime/peer/engine/module/feature/platform/generated-output/compiler-track risks, advisory exploit preconditions, synchronized surfaces, verification, and remaining dependency-upgrade risk |
|
|
674
|
-
| Dependency, package, runtime, framework, tool, command, plugin, service, platform capability, supported-version policy, security patch path, ecosystem maturity claim, maintainer-risk assumption, runtime portability claim, edge or serverless compatibility claim, critical-path library choice, package script, lifecycle hook, binary download, lockfile, audit result, or supply-chain-sensitive dependency surface is assumed, added, removed, imported, invoked, installed, audited, or documented | `.mustflow/skills/dependency-reality-check/SKILL.md` | Assumed dependency or capability, declaration files, version or feature expectation, role criticality, supported-version or end-of-life evidence, patchability expectation, runtime compatibility boundary, maintainer and ecosystem evidence when available, lockfile entry, package script or lifecycle hook, audit or provenance evidence, and relevant command intents | Package metadata, lockfiles, imports, scripts, command contracts, docs, tests, runtime policy notes, portability notes, and reports | unavailable dependency, hallucinated or lookalike package, fragile single-maintainer core dependency, experimental technology in a survival path, unsupported runtime, unclear security patch path, runtime-specific API leakage into core logic, 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, ecosystem and maintainer-risk boundary reviewed, supported-version, patchability, and runtime-portability boundary reviewed, supply-chain surface reviewed, declarations synchronized, verification, and remaining dependency risk |
|
|
674
|
+
| Dependency, package, workspace package contract, `package.json` dependency role, runtime, framework, tool, command, plugin, service, platform capability, package `exports`, package `imports`, public type dependency, peer host contract, optional integration, workspace protocol range, TypeScript path alias, build graph edge, test graph edge, deploy or prune package edge, release graph edge, supported-version policy, security patch path, ecosystem maturity claim, maintainer-risk assumption, runtime portability claim, edge or serverless compatibility claim, critical-path library choice, package script, lifecycle hook, binary download, lockfile, audit result, or supply-chain-sensitive dependency surface is assumed, added, removed, imported, invoked, installed, audited, or documented | `.mustflow/skills/dependency-reality-check/SKILL.md` | Assumed dependency or capability, package role, declaration files, emitted JS imports, public declaration files, `dependencies`/`devDependencies`/`peerDependencies`/optional metadata, workspace ranges, package `exports` and `imports`, `tsconfig.paths`, bundler and test resolver aliases, package manager graph, affected build/test graph evidence, deploy or prune artifact expectations, release graph evidence, version or feature expectation, role criticality, supported-version or end-of-life evidence, patchability expectation, runtime compatibility boundary, maintainer and ecosystem evidence when available, lockfile entry, package script or lifecycle hook, audit or provenance evidence, and relevant command intents | Package metadata, lockfiles, imports, scripts, command contracts, docs, tests, package entrypoints, public declaration files, boundary lint rules, task graph inputs, deploy or prune smoke surfaces, release graph notes, runtime policy notes, portability notes, and reports | unavailable dependency, hallucinated or lookalike package, TypeScript path alias hiding a missing package dependency, source alias bypassing package `exports`, package manager graph mismatch, affected build or test cache false green, pruned or deployed artifact missing a dependency, root-hoisted undeclared dependency, transitive dependency use, runtime import hidden in `devDependencies`, public type dependency hidden from consumers, host singleton installed as a direct dependency, peer missing local dev dependency, optional integration dragging unused hosts, broad package export, workspace range too tight for publish policy, fragile single-maintainer core dependency, experimental technology in a survival path, unsupported runtime, unclear security patch path, runtime-specific API leakage into core logic, 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, package contract and public API boundary reviewed, resolver/build/test/deploy/release graph alignment reviewed, ecosystem and maintainer-risk boundary reviewed, supported-version, patchability, and runtime-portability boundary reviewed, supply-chain surface reviewed, declarations synchronized, verification, and remaining dependency risk |
|
|
675
675
|
| Generated or edited code, configuration, CI workflows, package metadata, install instructions, examples, Docker images, framework setup, runtime declarations, toolchain declarations, TypeScript compiler-track references, Go release or framework references, Java/JDK GA, LTS, JEP, JVM, GC, or toolchain references, Rust release or MSRV references, or migration-sensitive snippets introduce explicit external version references, action refs, package ranges, runtime versions, framework majors, Docker image tags, or scaffold commands that may be stale | `.mustflow/skills/version-freshness-check/SKILL.md` | Versioned reference, owning files, repository version policy, approved freshness source, compatibility context, migration risk, TypeScript compiler track, Go toolchain/framework track, Java JDK/toolchain/bytecode/JEP track, or Rust MSRV/toolchain track when relevant, and command contract entries | Package metadata, lockfiles, CI workflows, Dockerfiles, runtime files, framework config, docs, examples, templates, tests, and version-decision reports | stale default version, false latest claim, accidental major migration, repository policy mismatch, unsupported generated example, TypeScript RC/nightly/API-track confusion, Java latest-GA/LTS/runtime/JEP/preview/incubator confusion, Rust stable/nightly/MSRV confusion, floating-tag drift, or unverified security/support claim | `changes_status`, `changes_diff_summary`, `build`, `test_related`, `docs_validate_fast`, `test_release`, `mustflow_check` | Versioned surfaces checked, repository policy and freshness source, selected version track, compatibility classification, TypeScript stable/RC/nightly/API-track, Go runtime/framework, Java GA/LTS/runtime/JEP/toolchain, and Rust stable/nightly/MSRV split when relevant, approval need, synchronized surfaces, verification, and remaining version-freshness risk |
|
|
676
676
|
| External systems, protocols, SDKs, databases, webhooks, queues, files, object storage, signed upload or download URLs, caches, API response models, framework requests or responses, server actions, route handlers, edge functions, worker handlers, AI models, browser storage, search engines, analytics tools, email platforms, no-code tools, observability backends, trace or request context, provider data, or volatile component implementations cross the core boundary or need stable port/adapter translation, change isolation, error mapping, timeout, retry, circuit-breaker, bulkhead, idempotency, reconciliation, security, core-state ownership, vendor portability, or observability handling | `.mustflow/skills/adapter-boundary/SKILL.md` | External system or protocol, inbound/outbound direction, delivery boundary, internal use case, local port/adapter patterns, provider risk, provider failure policy, core-state ownership risk, vendor portability risk, observability identifier policy, API contract risk, change-isolation ledger, preserved consumer contract, changed files, and command contract entries | Ports, adapters, mappers, controllers, workers, stores, gateways, response mappers, telemetry mappers, timeout and retry policies, circuit breakers, bulkhead boundaries, tests, fixtures, assembly wiring, and directly synchronized docs or templates | provider leakage, caller churn from adapter-only changes, framework business-rule leakage, telemetry backend leakage, storage-key leakage, screen-shaped API coupling, pass-through wrapper, SaaS dashboard as truth source, search or analytics policy leakage, queue contract leakage, unclassified external failure, duplicate side effect, unsafe retry, missing timeout, missing circuit breaker, missing bulkhead, unresolved unknown provider outcome, broken identifier propagation, 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, change-isolation ledger, preserved consumer contract, delivery adapter responsibility, internal port, provider containment, core-state ownership, vendor portability, validation and mapping, API response mapping, observability identifier flow, timeout/retry/circuit-breaker/bulkhead/idempotency handling, reconciliation behavior, security notes, verification, and remaining provider risk |
|
|
677
677
|
| Third-party SDK or external API integration, review, debugging, upgrade, webhook handling, auth scope change, sandbox or production setup, provider SDK version change, API version migration, rate-limit handling, retry policy, idempotency key usage, pagination, provider error mapping, request id logging, changelog review, deprecation response, or provider operational-readiness test needs production integration review | `.mustflow/skills/third-party-api-integration-review/SKILL.md` | Provider and SDK/API ledger, source-of-truth docs, auth and scope ledger, operation and side-effect ledger, webhook ledger, error and observability ledger, changelog or migration evidence, existing fakes or sandbox tests, and configured command intents | Provider adapters, wrappers, typed request and response models, error mappers, timeout and retry policies, rate-limit handling, idempotency key handling, pagination handling, webhook signature verification and dedupe, redacted observability, sandbox tests, fixtures, runbooks, migration notes, and directly synchronized docs or templates | demo-only integration, stale provider docs, SDK/API drift, sandbox-production mixup, hardcoded secret, overbroad scope, token refresh gap, missing timeout, infinite retry, retrying permanent errors, mutating retry without idempotency, per-attempt idempotency key, 429 retry storm, ignored Retry-After, offset pagination assumption, raw provider error leak, string-only provider error, missing request id, trusted webhook payload, JSON-parsed signature breakage, duplicate webhook side effect, event-order assumption, success redirect as proof, unhandled unknown provider outcome, dashboard-only setting, untested SDK upgrade, or happy-path-only sandbox test | `changes_status`, `changes_diff_summary`, `lint`, `build`, `test_related`, `test`, `test_audit`, `docs_validate_fast`, `test_release`, `mustflow_check` | Third-party integration reviewed, provider source-of-truth and SDK/API version evidence, auth/environment/scope decisions, timeout/retry/rate-limit/idempotency/pagination decisions, webhook delivery and dedupe checks, error and observability mapping, tests or missing evidence, verification, and remaining provider operational risk |
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
mustflow_doc: skill.dependency-reality-check
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 9
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: dependency-reality-check
|
|
9
|
-
description: Apply this skill when a task assumes, adds, removes, imports, invokes, installs, audits, or documents a package, runtime, framework, tool, command, service, platform capability, supported-version policy, security patch path, ecosystem maturity claim, maintainer-risk assumption, runtime portability claim, edge or serverless compatibility claim, critical-path dependency choice, or experimental technology placement, especially for AI-suggested dependencies, core backend stack choices, or supply-chain-sensitive changes.
|
|
9
|
+
description: Apply this skill when a task assumes, adds, removes, imports, invokes, installs, audits, or documents a package, runtime, framework, tool, command, service, platform capability, workspace package contract, package.json dependency role, peer dependency contract, public type dependency, export/import boundary, TypeScript path alias, build/test/release package graph edge, supported-version policy, security patch path, ecosystem maturity claim, maintainer-risk assumption, runtime portability claim, edge or serverless compatibility claim, critical-path dependency choice, or experimental technology placement, especially for AI-suggested dependencies, monorepo package metadata, core backend stack choices, or supply-chain-sensitive changes.
|
|
10
10
|
metadata:
|
|
11
11
|
mustflow_schema: "1"
|
|
12
12
|
mustflow_kind: procedure
|
|
@@ -31,6 +31,13 @@ Prevent code, docs, tests, and final reports from assuming unavailable packages,
|
|
|
31
31
|
## Use When
|
|
32
32
|
|
|
33
33
|
- A change adds, removes, renames, imports, invokes, or documents a dependency, tool, runtime, command, plugin, service, or platform feature.
|
|
34
|
+
- A JavaScript or TypeScript workspace package changes `package.json`, `exports`, `imports`,
|
|
35
|
+
`dependencies`, `devDependencies`, `peerDependencies`, `peerDependenciesMeta`,
|
|
36
|
+
`optionalDependencies`, workspace protocol ranges, public declaration types, package entrypoints,
|
|
37
|
+
or package-boundary import rules.
|
|
38
|
+
- A JavaScript or TypeScript change relies on `tsconfig.paths`, bundler aliases, test resolver
|
|
39
|
+
aliases, TypeScript project references, task graph selection, affected builds, package pruning,
|
|
40
|
+
deploy output, or release tooling to prove that an import is valid.
|
|
34
41
|
- An AI-generated patch, assistant suggestion, copied snippet, or generated docs introduce a package name that could be hallucinated, misspelled, abandoned, lookalike, or unnecessary.
|
|
35
42
|
- A change adds package-manager scripts, package lifecycle hooks, build downloads, binary installers, lockfile changes, audit suppression, vulnerability scanner output, or CI dependency gates.
|
|
36
43
|
- A solution relies on a package manager, binary, environment variable, browser API, operating-system command, hosted service, or optional integration.
|
|
@@ -57,6 +64,14 @@ Prevent code, docs, tests, and final reports from assuming unavailable packages,
|
|
|
57
64
|
|
|
58
65
|
- The dependency, tool, command, runtime, service, or platform capability being assumed.
|
|
59
66
|
- Package, lock, config, import, script, command-intent, or documentation files that declare or reference it.
|
|
67
|
+
- For JavaScript or TypeScript monorepos: package role (app, library, plugin, tooling package),
|
|
68
|
+
package-manager workspace protocol, package boundary, package `exports` and `imports`, public
|
|
69
|
+
declaration files, emitted JavaScript imports, peer host package, and whether the package is
|
|
70
|
+
published, packed, bundled, deployed, or only used inside the repository.
|
|
71
|
+
- TypeScript, bundler, and test resolver evidence when aliases are involved: `baseUrl`, `paths`,
|
|
72
|
+
package self-reference, project references, Vite/Jest/Vitest/Webpack aliases, and whether emitted
|
|
73
|
+
JavaScript, declarations, package manager installs, task graphs, and release tools resolve the
|
|
74
|
+
same package edge.
|
|
60
75
|
- The minimum version, capability, or availability claim if one is required.
|
|
61
76
|
- Registry name, package scope, lockfile entry, provenance or maintainer expectation, install script risk, and whether the dependency is runtime, development, fixture-only, transitive, or optional.
|
|
62
77
|
- Dependency role criticality: decorative utility, product-experience feature, operational support, or survival path such as identity, money, durable data, permissions, security, migrations, deployment, queues, or file ownership.
|
|
@@ -87,7 +102,30 @@ Prevent code, docs, tests, and final reports from assuming unavailable packages,
|
|
|
87
102
|
|
|
88
103
|
1. Name the assumed dependency or capability and where the task relies on it.
|
|
89
104
|
2. Check the repository declarations first: package metadata, lockfiles, config files, imports, command intents, docs, and templates.
|
|
105
|
+
- In monorepos, treat each package's `package.json` as that package's external contract, not as
|
|
106
|
+
a convenience install list. Check the package that owns the import, not only the workspace root.
|
|
107
|
+
- Classify the package before classifying its dependencies: final app, published library,
|
|
108
|
+
framework/plugin package, internal package, tooling package, or test/fixture-only package.
|
|
109
|
+
- For package-boundary changes, inspect emitted JS imports, generated declaration files,
|
|
110
|
+
`exports`, `imports`, self-reference tests or examples, workspace ranges, and package manager
|
|
111
|
+
behavior for pack/publish/deploy output.
|
|
112
|
+
- Treat `tsconfig.paths` as a TypeScript resolver hint, not as a dependency declaration, package
|
|
113
|
+
manager edge, runtime rewrite, or public boundary rule. If a path alias points at a sibling
|
|
114
|
+
package's `src/`, the package graph may be lying even when typecheck is green.
|
|
90
115
|
3. Decide whether the dependency is present, absent, optional, transitive, host-provided, or external.
|
|
116
|
+
- If emitted JavaScript imports a package, it is normally a runtime dependency of the emitting
|
|
117
|
+
package unless it is bundled, externalized by a documented host contract, or intentionally peer.
|
|
118
|
+
- If a public `.d.ts` type references an external package, consumers need that type dependency
|
|
119
|
+
through `dependencies` or a documented `peerDependencies` contract. Do not hide public type
|
|
120
|
+
requirements in `devDependencies`.
|
|
121
|
+
- If the dependency is a host singleton such as React, Vue, ESLint, Vite, Webpack, Fastify,
|
|
122
|
+
NestJS, Prisma, a bundler plugin host, or another framework/runtime host, prefer a
|
|
123
|
+
`peerDependencies` contract plus local `devDependencies` for this package's tests and builds.
|
|
124
|
+
- If the package supports optional host integrations, prefer optional peer metadata for
|
|
125
|
+
consumer-provided hosts. Use `optionalDependencies` only for direct runtime dependencies that
|
|
126
|
+
the code can safely conditionally load and survive without.
|
|
127
|
+
- If a package imports a dependency only because another dependency currently brings it transitively,
|
|
128
|
+
treat that as an undeclared dependency bug rather than a valid declaration.
|
|
91
129
|
4. For AI-suggested names, check for hallucination and lookalike risk before accepting the import: exact package name, namespace, known local precedent, lockfile presence, and whether an existing dependency already solves the need.
|
|
92
130
|
5. If present, verify that the requested capability and version expectation match the declared dependency.
|
|
93
131
|
6. If absent, prefer an existing local alternative. Add a new dependency only when it is necessary, within the task scope, and reflected in the package metadata and lockfile policy.
|
|
@@ -105,14 +143,44 @@ Prevent code, docs, tests, and final reports from assuming unavailable packages,
|
|
|
105
143
|
- Core and application code should not depend on Node-only APIs, Bun or Deno globals, edge-only globals, framework request objects, ORM clients, environment variables, or platform-specific queue and storage clients.
|
|
106
144
|
- Delivery and infrastructure layers may use runtime or framework capabilities, but the choice should be visible as an adapter decision rather than scattered through use cases.
|
|
107
145
|
- Treat Web-standard frameworks or adapters as a portability aid, not as proof that domain code is portable if provider SDKs, ORM clients, filesystem calls, or platform bindings still leak inward.
|
|
108
|
-
12.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
146
|
+
12. For monorepo package contracts, inspect import and export boundaries before accepting the
|
|
147
|
+
dependency shape.
|
|
148
|
+
- Outside a package, imports should use the package name and an explicitly exported entrypoint,
|
|
149
|
+
not relative paths into sibling packages, `src/`, `dist/`, or internal folders.
|
|
150
|
+
- `exports` should expose intentional public entrypoints. Broad globs such as `./*` need a
|
|
151
|
+
package-level reason because they turn internal file layout into public API.
|
|
152
|
+
- Internal package aliases should use package-private `imports` mappings when the runtime and
|
|
153
|
+
toolchain support them. Do not make internal aliases look like public workspace packages.
|
|
154
|
+
- Keep runtime exports and type exports aligned. A subpath that exists at runtime but not in
|
|
155
|
+
declarations, or vice versa, is a consumer contract drift.
|
|
156
|
+
- Treat `export *` barrels as possible public API leaks. Public exports should name the symbols
|
|
157
|
+
the package commits to supporting.
|
|
158
|
+
- Choose `workspace:*`, `workspace:^`, or another workspace range according to release policy:
|
|
159
|
+
lockstep packages can use exact workspace coupling, while independently versioned public
|
|
160
|
+
packages usually need a range that survives publish or pack output.
|
|
161
|
+
- Root overrides and resolutions are emergency graph controls, not a substitute for correcting
|
|
162
|
+
each package's own declarations.
|
|
163
|
+
13. Align package, build, test, deploy, and release graphs before accepting a monorepo import.
|
|
164
|
+
- A compiling import is not proof that the consuming package declared the dependency. Check the
|
|
165
|
+
consuming package's manifest and the package manager workspace graph.
|
|
166
|
+
- Do not rely on root `node_modules`, root `dependencies`, broad `paths`, or transitive installs
|
|
167
|
+
as proof that a package can survive production install, prune, deploy, pack, or publish output.
|
|
168
|
+
- When a package imports another workspace package, prefer the real package name plus
|
|
169
|
+
`workspace:` protocol where the package manager supports it. Plain semver for internal
|
|
170
|
+
packages can hide registry fallback or stale publish behavior.
|
|
171
|
+
- Check whether task selection, affected tests, build cache keys, Docker or package pruning, and
|
|
172
|
+
release tooling can see the same dependency edge. If the edge exists only in TypeScript
|
|
173
|
+
aliases, the graph is incomplete.
|
|
174
|
+
- Keep root dependency declarations for repository tooling unless the root itself is the
|
|
175
|
+
runtime package. Runtime imports belong to the package that emits or bundles them.
|
|
176
|
+
14. Evaluate ecosystem maturity when the task depends on it: production examples, searchable error solutions, migration notes, security-response history, version stability, plugin ecosystem, older issue answers, support availability, and whether the direction is likely to hold over the next release cycles.
|
|
177
|
+
15. For small libraries, accept them only when they are small in role as well as code: simple, understandable, peripheral, safe to fork or reimplement, and not directly touching secrets, personal data, money, permissions, migrations, durable state, or security.
|
|
178
|
+
16. For vulnerability or audit output, separate runtime dependencies from fixture-only or intentionally vulnerable samples. Do not weaken audit gates, delete lockfiles, or add broad suppressions without a repository-owned reason.
|
|
179
|
+
17. For new dependencies, prefer pinned or lockfile-backed versions according to project policy. Avoid widening ranges or removing lockfiles to satisfy generated code.
|
|
180
|
+
18. Do not introduce new package-manager wrappers, vulnerability scanners, registry queries, or install commands inside this skill. Use configured command intents or report the missing verification surface.
|
|
181
|
+
19. If external source material is copied or closely adapted, activate `provenance-license-gate` for source, license, attribution, and copy-extent decisions before preserving the material.
|
|
182
|
+
20. Keep all dependency-facing surfaces aligned: package metadata, lockfiles when intentionally updated, command contract, docs, tests, installation notes, package `exports`, public declaration files, self-reference examples, workspace constraints, boundary lint rules, task graph inputs, deploy/prune smoke surfaces, and release graph evidence.
|
|
183
|
+
21. Run the narrowest configured verification that proves the dependency path used by the change.
|
|
116
184
|
|
|
117
185
|
<!-- mustflow-section: postconditions -->
|
|
118
186
|
## Postconditions
|
|
@@ -122,6 +190,11 @@ Prevent code, docs, tests, and final reports from assuming unavailable packages,
|
|
|
122
190
|
- Runtime and framework choices identify supported-version policy, end-of-life exposure, security patch path, smoke-test surface, deployment and rollback route, and whether experimental choices are isolated from survival paths.
|
|
123
191
|
- Runtime portability claims identify which APIs are confined to delivery or infrastructure and which would force core or application code to change when moving between Node, Bun, Deno, serverless functions, or edge runtime.
|
|
124
192
|
- New dependency requirements are reflected in the appropriate metadata and public documentation.
|
|
193
|
+
- Workspace package contracts reflect real consumers: emitted runtime imports, public type imports,
|
|
194
|
+
peer hosts, optional integrations, workspace ranges, `exports`, and boundary lint rules agree
|
|
195
|
+
instead of relying on root hoisting or transitive dependencies.
|
|
196
|
+
- TypeScript path aliases, bundler aliases, test resolvers, package manager workspace edges, task
|
|
197
|
+
graphs, deploy/prune artifacts, and release tooling agree or the remaining graph drift is named.
|
|
125
198
|
- The final report states whether the dependency was existing, added, optional, unavailable, or intentionally not verified.
|
|
126
199
|
|
|
127
200
|
<!-- mustflow-section: verification -->
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
mustflow_doc: skill.module-boundary-review
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 5
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: module-boundary-review
|
|
9
|
-
description: Apply this skill when code is created, changed, reviewed, or reported and module separation, cohesion, coupling, change axes, stability direction, data ownership, rule ownership, failure ownership, import direction, circular dependency, DTO leakage, shared/common/utils growth, mock-heavy tests, repeated policy conditions, enum interpretation, repository business logic, anemic domain, domain-to-I/O leakage, transaction boundary mismatch, event naming, public API bloat, caller sequencing, premature reuse, co-change history, bug/fix distance, config ownership, log responsibility, exception translation, cache invalidation ownership, repeated authorization checks, frontend/backend policy leakage, time policy, batch or worker bypass, shallow modules, or temporary-code accumulation can make a change spread beyond its real owner.
|
|
9
|
+
description: Apply this skill when code is created, changed, reviewed, or reported and module or monorepo package separation, cohesion, coupling, change axes, stability direction, package dependency direction, TypeScript path alias boundaries, compile-success versus allowed-dependency confusion, data ownership, rule ownership, failure ownership, import direction, circular dependency, DTO leakage, shared/common/utils growth, cross-package deep imports, package exports, workspace boundary rules, mock-heavy tests, repeated policy conditions, enum interpretation, repository business logic, anemic domain, domain-to-I/O leakage, transaction boundary mismatch, event naming, public API bloat, caller sequencing, premature reuse, co-change history, bug/fix distance, config ownership, log responsibility, exception translation, cache invalidation ownership, repeated authorization checks, frontend/backend policy leakage, time policy, batch or worker bypass, shallow modules, or temporary-code accumulation can make a change spread beyond its real owner.
|
|
10
10
|
metadata:
|
|
11
11
|
mustflow_schema: "1"
|
|
12
12
|
mustflow_kind: procedure
|
|
@@ -42,6 +42,10 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
42
42
|
services, repositories, validators, mappers, helpers, shared utilities, DTOs, domain models,
|
|
43
43
|
policies, use cases, workers, batches, events, caches, permissions, config reads, or public module
|
|
44
44
|
APIs.
|
|
45
|
+
- A monorepo package graph, workspace dependency direction, package `exports`, cross-package import,
|
|
46
|
+
deep import, TypeScript `paths` alias, package tag, module-boundary lint rule, TypeScript project
|
|
47
|
+
reference, affected build/test graph, package deploy/prune surface, or shared/common package is
|
|
48
|
+
created, changed, reviewed, or reported.
|
|
45
49
|
- A change touches several folders, layers, or modules for one reason, or several differently named
|
|
46
50
|
files repeatedly change together.
|
|
47
51
|
- A review claims that layering, clean architecture, DDD, modular monolith, feature folders,
|
|
@@ -85,6 +89,12 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
85
89
|
history showing files that usually move together.
|
|
86
90
|
- Module graph evidence: imports, exports, public APIs, call sites, dependency direction, cycles,
|
|
87
91
|
shared helpers, DTO flow, and configuration reads.
|
|
92
|
+
- Monorepo package graph evidence when relevant: each package's role (app, feature, domain, data
|
|
93
|
+
access, UI, util, tooling), domain scope, runtime platform, package `dependencies`,
|
|
94
|
+
`peerDependencies`, `devDependencies`, `exports`, `imports`, TypeScript project references,
|
|
95
|
+
`tsconfig.paths` aliases, bundler and test resolver aliases, package-manager workspace protocol,
|
|
96
|
+
affected build/test graph, deploy or prune artifact expectations, release graph evidence,
|
|
97
|
+
boundary lint constraints, and package-level cycle reports.
|
|
88
98
|
- Stability evidence: which modules many callers rely on, which modules change because external
|
|
89
99
|
details move, and whether dependencies point toward the more stable policy owner rather than the
|
|
90
100
|
more volatile implementation detail.
|
|
@@ -148,6 +158,14 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
148
158
|
- Prefer volatility names and business capabilities, such as pricing policy, payment provider,
|
|
149
159
|
subscription lifecycle, invoice rendering, fraud check, fulfillment handoff, or entitlement
|
|
150
160
|
decision, over role-sliced layer names when those better predict future edits.
|
|
161
|
+
- In monorepos, assign package roles before accepting an edge. Apps assemble and should not be
|
|
162
|
+
imported. Domain or policy packages should not know UI, router, database, provider SDK, or
|
|
163
|
+
framework request details. Infrastructure packages may depend on domain-owned ports or types,
|
|
164
|
+
but domain packages should not depend on infrastructure implementations.
|
|
165
|
+
- Treat `shared`, `common`, `utils`, and broad `types` packages as suspect until their scope,
|
|
166
|
+
layer, and runtime platform are explicit. Split shared concepts by reason to change, such as
|
|
167
|
+
shared-kernel, shared-ui, shared-config, shared-testing, or domain-owned contracts, rather than
|
|
168
|
+
by "used in many places".
|
|
151
169
|
3. Check import direction.
|
|
152
170
|
- Infrastructure or low-level modules should not know high-level business use case names unless
|
|
153
171
|
the repository intentionally uses that inversion.
|
|
@@ -160,6 +178,21 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
160
178
|
- Prefer interfaces or ports owned by the using side when the abstraction protects stable policy
|
|
161
179
|
code from an unstable provider, database, queue, cache, filesystem, network, framework, or UI
|
|
162
180
|
detail.
|
|
181
|
+
- For monorepos, prefer dependency direction from volatile assembly code toward stable policy or
|
|
182
|
+
contract code. A stable package importing a fast-changing app, route, UI flow, database adapter,
|
|
183
|
+
or external API client is a boundary smell even when the folder layout looks layered.
|
|
184
|
+
- Feature packages should not import each other's internals. If two features need to communicate,
|
|
185
|
+
look for a missing contract, event, port, or shared lower-level policy package before accepting
|
|
186
|
+
a direct feature-to-feature edge.
|
|
187
|
+
- UI kit packages should stay ignorant of business state, routes, auth stores, billing enums, API
|
|
188
|
+
error shapes, and domain policies. Feature code owns visibility and policy decisions; UI
|
|
189
|
+
packages render props and callbacks.
|
|
190
|
+
- Treat "the import compiles" as weak evidence. TypeScript path aliases, editor autocomplete, and
|
|
191
|
+
root `node_modules` can make an illegal package edge look available while package ownership,
|
|
192
|
+
deploy output, build cache, and release order remain wrong.
|
|
193
|
+
- If an import crosses a package boundary through a relative path, `src/`, `dist/`, or an alias
|
|
194
|
+
that points at another package's source, review it as a boundary violation candidate even when
|
|
195
|
+
local typecheck and tests pass.
|
|
163
196
|
4. Treat cycles as boundary failure until proven harmless.
|
|
164
197
|
- If A imports B and B imports A, identify the missing concept, ownership decision, event, port, or
|
|
165
198
|
data-flow direction.
|
|
@@ -167,6 +200,11 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
167
200
|
- When the repository declares `.mustflow/config/module-boundaries.toml`, use the read-only
|
|
168
201
|
`code/module-boundary` script-pack report as executable evidence before relying on prose-only
|
|
169
202
|
boundary claims.
|
|
203
|
+
- Workspace dependency cycles, even type-only cycles, are package-boundary evidence. `import type`
|
|
204
|
+
can remove a runtime edge but does not erase architectural knowledge or public declaration
|
|
205
|
+
coupling.
|
|
206
|
+
- If a cycle exists between packages, identify the missing lower-level contract package,
|
|
207
|
+
shared protocol, event, or ownership decision instead of adding a larger shared bucket.
|
|
170
208
|
5. Trace DTO infection.
|
|
171
209
|
- API response DTOs, request DTOs, ORM rows, provider payloads, and UI view models should not
|
|
172
210
|
become domain, repository, batch, worker, or event models by default.
|
|
@@ -221,8 +259,19 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
221
259
|
- A good module should have a small door and a deeper inside. If most files only expose one-line
|
|
222
260
|
forwarding methods, wrapper services, or renamed CRUD calls, treat the split as shallow module
|
|
223
261
|
theater until a real hidden decision or variation point is named.
|
|
224
|
-
|
|
225
|
-
|
|
262
|
+
- A public API wider than the behavior it hides is usually not a boundary; it is implementation
|
|
263
|
+
leakage with extra navigation.
|
|
264
|
+
- For packages, treat `package.json` `exports` as the public API, not the folder tree. External
|
|
265
|
+
callers should use package names and intentional subpath exports, not relative paths into
|
|
266
|
+
sibling packages, `src/`, `dist/`, or internal files.
|
|
267
|
+
- Do not use `tsconfig.paths` as a substitute for `exports`, `imports`, package self-reference,
|
|
268
|
+
workspace dependency declarations, or module-boundary lint rules. Path aliases can shorten
|
|
269
|
+
names inside an app, but they should not define cross-package public API.
|
|
270
|
+
- Broad export maps such as `./*`, root barrels that `export *`, and package-internal code that
|
|
271
|
+
imports its own root barrel are public API leak or cycle signals until proven intentional.
|
|
272
|
+
- Runtime entrypoints and type declarations should expose the same shape. A runtime export with no
|
|
273
|
+
matching type export, or a public type path with no runtime entrypoint, means consumers see a
|
|
274
|
+
different contract in the editor and in production.
|
|
226
275
|
16. Check reuse claims.
|
|
227
276
|
- "Used in many places" is not enough reason to extract a common helper.
|
|
228
277
|
- Reuse is safe only when the callers change for the same reason. Similar code from different
|
|
@@ -264,9 +313,16 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
264
313
|
- Name the three modules or abstractions most likely to rot first.
|
|
265
314
|
- For each, name the change request that would break it, the owner that would cause the change,
|
|
266
315
|
and whether the blast stays inside one module.
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
316
|
+
- Remove or redesign shallow wrappers, central managers, enum-switch strategies, provider-shaped
|
|
317
|
+
"neutral" ports, configuration-driven logic hiding, event-bus call hiding, and CRUD stamp
|
|
318
|
+
modules when they fail the attack.
|
|
319
|
+
- In a monorepo, attack the package graph too: add a new route, swap a provider, change a domain
|
|
320
|
+
rule, split a UI component, or publish a library package. If those changes require deep imports,
|
|
321
|
+
root-hoisted undeclared dependencies, app imports from shared code, or cross-feature internals,
|
|
322
|
+
the package boundary is not carrying its weight.
|
|
323
|
+
- Attack the resolver graph too: remove the root install crutch, pack or prune the target package,
|
|
324
|
+
and ask whether TypeScript, bundler, test runner, task graph, and release tooling still agree on
|
|
325
|
+
the same edge. If only `paths` knows the edge, the boundary is paper-thin.
|
|
270
326
|
24. Decide the smallest response.
|
|
271
327
|
- If evidence is strong and the edit is in scope, make the smallest boundary fix.
|
|
272
328
|
- If the fix would be broad, report the module boundary risk and the first safe split point.
|
|
@@ -287,6 +343,9 @@ who must change, who owns the data, who owns the failure, and who should not nee
|
|
|
287
343
|
- Shallow module signals such as role-sliced CRUD layers, one-line wrappers, provider-shaped ports,
|
|
288
344
|
ownerless managers, event-bus call hiding, config-hidden logic, and public API bloat are removed,
|
|
289
345
|
justified, or reported.
|
|
346
|
+
- Package-boundary signals such as path-alias reach-through, relative sibling imports, deep source
|
|
347
|
+
imports, root-hoisted undeclared dependencies, and compile-only imports are fixed, justified, or
|
|
348
|
+
reported with their graph risk.
|
|
290
349
|
- Any new abstraction hides a named responsibility and reduces caller knowledge, change spread, or
|
|
291
350
|
test mock cost.
|
|
292
351
|
- Behavior, public contracts, permissions, data ownership, and failure semantics remain intact or
|
|
@@ -262,7 +262,7 @@ applies_to_reasons = ["unknown_change", "code_change", "behavior_change", "test_
|
|
|
262
262
|
category = "general_code"
|
|
263
263
|
route_type = "adjunct"
|
|
264
264
|
priority = 70
|
|
265
|
-
applies_to_reasons = ["unknown_change", "code_change", "behavior_change", "test_change", "public_api_change", "performance_change", "security_change", "privacy_change", "data_change"]
|
|
265
|
+
applies_to_reasons = ["unknown_change", "code_change", "behavior_change", "test_change", "public_api_change", "performance_change", "security_change", "privacy_change", "data_change", "package_metadata_change"]
|
|
266
266
|
|
|
267
267
|
[routes."change-blast-radius-review"]
|
|
268
268
|
category = "general_code"
|
|
@@ -856,7 +856,7 @@ applies_to_reasons = ["code_change", "docs_change", "security_change", "package_
|
|
|
856
856
|
category = "data_external"
|
|
857
857
|
route_type = "adjunct"
|
|
858
858
|
priority = 45
|
|
859
|
-
applies_to_reasons = ["code_change", "docs_change", "security_change"]
|
|
859
|
+
applies_to_reasons = ["unknown_change", "code_change", "docs_change", "security_change", "package_metadata_change", "release_risk"]
|
|
860
860
|
|
|
861
861
|
[routes."version-freshness-check"]
|
|
862
862
|
category = "data_external"
|