@mycodemap/mycodemap 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CHANGELOG.md +92 -3
  2. package/README.md +117 -46
  3. package/dist/ai/claude.d.ts +38 -0
  4. package/dist/ai/claude.d.ts.map +1 -0
  5. package/dist/ai/claude.js +169 -0
  6. package/dist/ai/claude.js.map +1 -0
  7. package/dist/ai/codex.d.ts +38 -0
  8. package/dist/ai/codex.d.ts.map +1 -0
  9. package/dist/ai/codex.js +169 -0
  10. package/dist/ai/codex.js.map +1 -0
  11. package/dist/ai/factory.d.ts +48 -0
  12. package/dist/ai/factory.d.ts.map +1 -0
  13. package/dist/ai/factory.js +95 -0
  14. package/dist/ai/factory.js.map +1 -0
  15. package/dist/ai/index.d.ts +12 -0
  16. package/dist/ai/index.d.ts.map +1 -0
  17. package/dist/ai/index.js +29 -0
  18. package/dist/ai/index.js.map +1 -0
  19. package/dist/ai/provider.d.ts +70 -0
  20. package/dist/ai/provider.d.ts.map +1 -0
  21. package/dist/ai/provider.js +31 -0
  22. package/dist/ai/provider.js.map +1 -0
  23. package/dist/ai/subagent-caller.d.ts +90 -0
  24. package/dist/ai/subagent-caller.d.ts.map +1 -0
  25. package/dist/ai/subagent-caller.js +280 -0
  26. package/dist/ai/subagent-caller.js.map +1 -0
  27. package/dist/ai/types.d.ts +70 -0
  28. package/dist/ai/types.d.ts.map +1 -0
  29. package/dist/ai/types.js +5 -0
  30. package/dist/ai/types.js.map +1 -0
  31. package/dist/cli/commands/design.d.ts +47 -0
  32. package/dist/cli/commands/design.d.ts.map +1 -0
  33. package/dist/cli/commands/design.js +268 -0
  34. package/dist/cli/commands/design.js.map +1 -0
  35. package/dist/cli/commands/server.d.ts +9 -0
  36. package/dist/cli/commands/server.d.ts.map +1 -0
  37. package/dist/cli/commands/server.js +65 -0
  38. package/dist/cli/commands/server.js.map +1 -0
  39. package/dist/cli/commands/ship/pipeline.d.ts.map +1 -1
  40. package/dist/cli/commands/ship/pipeline.js +8 -1
  41. package/dist/cli/commands/ship/pipeline.js.map +1 -1
  42. package/dist/cli/commands/ship/publisher.d.ts +9 -1
  43. package/dist/cli/commands/ship/publisher.d.ts.map +1 -1
  44. package/dist/cli/commands/ship/publisher.js +149 -6
  45. package/dist/cli/commands/ship/publisher.js.map +1 -1
  46. package/dist/cli/design-contract-loader.d.ts +15 -0
  47. package/dist/cli/design-contract-loader.d.ts.map +1 -0
  48. package/dist/cli/design-contract-loader.js +175 -0
  49. package/dist/cli/design-contract-loader.js.map +1 -0
  50. package/dist/cli/design-contract-schema.d.ts +11 -0
  51. package/dist/cli/design-contract-schema.d.ts.map +1 -0
  52. package/dist/cli/design-contract-schema.js +75 -0
  53. package/dist/cli/design-contract-schema.js.map +1 -0
  54. package/dist/cli/design-handoff-builder.d.ts +15 -0
  55. package/dist/cli/design-handoff-builder.d.ts.map +1 -0
  56. package/dist/cli/design-handoff-builder.js +345 -0
  57. package/dist/cli/design-handoff-builder.js.map +1 -0
  58. package/dist/cli/design-scope-resolver.d.ts +8 -0
  59. package/dist/cli/design-scope-resolver.d.ts.map +1 -0
  60. package/dist/cli/design-scope-resolver.js +712 -0
  61. package/dist/cli/design-scope-resolver.js.map +1 -0
  62. package/dist/cli/design-verification-builder.d.ts +8 -0
  63. package/dist/cli/design-verification-builder.d.ts.map +1 -0
  64. package/dist/cli/design-verification-builder.js +369 -0
  65. package/dist/cli/design-verification-builder.js.map +1 -0
  66. package/dist/cli/index.js +2 -0
  67. package/dist/cli/index.js.map +1 -1
  68. package/dist/cli-new/commands/server.d.ts +13 -0
  69. package/dist/cli-new/commands/server.d.ts.map +1 -0
  70. package/dist/cli-new/commands/server.js +90 -0
  71. package/dist/cli-new/commands/server.js.map +1 -0
  72. package/dist/generator/ai-overview.d.ts +51 -0
  73. package/dist/generator/ai-overview.d.ts.map +1 -0
  74. package/dist/generator/ai-overview.js +160 -0
  75. package/dist/generator/ai-overview.js.map +1 -0
  76. package/dist/infrastructure/storage/StorageFactory.d.ts +12 -5
  77. package/dist/infrastructure/storage/StorageFactory.d.ts.map +1 -1
  78. package/dist/infrastructure/storage/StorageFactory.js +55 -14
  79. package/dist/infrastructure/storage/StorageFactory.js.map +1 -1
  80. package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts +41 -0
  81. package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts.map +1 -0
  82. package/dist/infrastructure/storage/adapters/Neo4jStorage.js +162 -0
  83. package/dist/infrastructure/storage/adapters/Neo4jStorage.js.map +1 -0
  84. package/dist/interface/types/design-contract.d.ts +68 -0
  85. package/dist/interface/types/design-contract.d.ts.map +1 -0
  86. package/dist/interface/types/design-contract.js +7 -0
  87. package/dist/interface/types/design-contract.js.map +1 -0
  88. package/dist/interface/types/design-handoff.d.ts +68 -0
  89. package/dist/interface/types/design-handoff.d.ts.map +1 -0
  90. package/dist/interface/types/design-handoff.js +4 -0
  91. package/dist/interface/types/design-handoff.js.map +1 -0
  92. package/dist/interface/types/design-mapping.d.ts +51 -0
  93. package/dist/interface/types/design-mapping.d.ts.map +1 -0
  94. package/dist/interface/types/design-mapping.js +4 -0
  95. package/dist/interface/types/design-mapping.js.map +1 -0
  96. package/dist/interface/types/design-verification.d.ts +49 -0
  97. package/dist/interface/types/design-verification.d.ts.map +1 -0
  98. package/dist/interface/types/design-verification.js +4 -0
  99. package/dist/interface/types/design-verification.js.map +1 -0
  100. package/dist/interface/types/index.d.ts +4 -0
  101. package/dist/interface/types/index.d.ts.map +1 -1
  102. package/dist/orchestrator/ai-feed-generator.d.ts +210 -0
  103. package/dist/orchestrator/ai-feed-generator.d.ts.map +1 -0
  104. package/dist/orchestrator/ai-feed-generator.js +377 -0
  105. package/dist/orchestrator/ai-feed-generator.js.map +1 -0
  106. package/docs/ai-guide/COMMANDS.md +73 -0
  107. package/docs/ai-guide/OUTPUT.md +415 -0
  108. package/docs/ai-guide/PATTERNS.md +14 -4
  109. package/docs/ai-guide/PROMPTS.md +12 -6
  110. package/docs/archive/test-report-symbol-search.md +384 -0
  111. package/docs/archive/test-scenario-4-complexity-analysis.md +460 -0
  112. package/docs/archive/test_report_scenario5.md +615 -0
  113. package/docs/archive/test_scenario_3_impact_analysis_report.md +520 -0
  114. package/docs/product-specs/DESIGN_CONTRACT_TEMPLATE.md +79 -0
  115. package/docs/product-specs/README.md +2 -1
  116. package/docs/rules/engineering-with-codex-openai.md +6 -2
  117. package/docs/rules/validation.md +9 -6
  118. package/package.json +1 -1
  119. package/scripts/experiments/arcadedb-http-smoke.mjs +90 -0
  120. package/scripts/validate-docs.js +247 -0
@@ -0,0 +1,377 @@
1
+ // [META] since:2026-03-02 | owner:orchestrator-team | stable:true
2
+ // [WHY] AI feed generator with date format alignment for JSON serialization
3
+ /**
4
+ * AI Feed Generator
5
+ * Generates structured data for AI consumption (ai-feed.txt)
6
+ * Provides code metadata, dependency complexity, modification heat, etc.
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import { globby } from 'globby';
11
+ /**
12
+ * File header comment scanner
13
+ * Scans [META]/[WHY]/[DEPS] comments at the top of files
14
+ */
15
+ export class FileHeaderScanner {
16
+ /**
17
+ * Scan file header comments
18
+ * Only reads first 10 lines of the file
19
+ *
20
+ * @param filePath - Full file path
21
+ * @returns FileMeta parsing result
22
+ */
23
+ scan(filePath) {
24
+ try {
25
+ const content = fs.readFileSync(filePath, 'utf-8');
26
+ const lines = content.split('\n').slice(0, 10);
27
+ const header = lines.join('\n');
28
+ return this.parseHeader(header);
29
+ }
30
+ catch {
31
+ // Return empty object on read failure
32
+ return {};
33
+ }
34
+ }
35
+ /**
36
+ * Parse file header content string (public for testing)
37
+ * Alias for parseHeaderContent for backward compatibility
38
+ *
39
+ * @param header - File header content (first 10 lines as string)
40
+ * @returns FileMeta parsing result with flat structure
41
+ */
42
+ parseHeader(header) {
43
+ return this.parseHeaderContent(header);
44
+ }
45
+ /**
46
+ * Parse file header content (public for testing)
47
+ * Returns nested structure for backward compatibility with tests
48
+ *
49
+ * @param header - File header content (first 10 lines)
50
+ * @returns FileHeader parsing result with nested meta
51
+ */
52
+ parseHeaderContent(header) {
53
+ const result = {};
54
+ // Parse [META]
55
+ const metaMatch = header.match(/\/\/\s*\[META\]\s*(.+)/);
56
+ if (metaMatch) {
57
+ const metaStr = metaMatch[1];
58
+ result.meta = {
59
+ since: metaStr.match(/since:(\S+)/)?.[1],
60
+ owner: metaStr.match(/owner:(\S+)/)?.[1],
61
+ stable: metaStr.includes('stable:true')
62
+ };
63
+ // Also set flat properties for compatibility
64
+ result.since = result.meta.since;
65
+ result.owner = result.meta.owner;
66
+ result.stable = result.meta.stable;
67
+ }
68
+ // Parse [WHY]
69
+ const whyMatch = header.match(/\/\/\s*\[WHY\]\s*(.+)/);
70
+ if (whyMatch) {
71
+ result.why = whyMatch[1].trim();
72
+ }
73
+ // Parse [DEPS]
74
+ const depsMatch = header.match(/\/\/\s*\[DEPS\]\s*(.+)/);
75
+ if (depsMatch) {
76
+ result.deps = depsMatch[1]
77
+ .split(',')
78
+ .map(d => d.trim())
79
+ .filter(d => d.length > 0);
80
+ }
81
+ return result;
82
+ }
83
+ /**
84
+ * Validate file header completeness
85
+ * Used by CI gateway
86
+ *
87
+ * @param filePath - File path
88
+ * @returns Validation result
89
+ */
90
+ validate(filePath) {
91
+ const meta = this.scan(filePath);
92
+ const missing = [];
93
+ if (!meta.since) {
94
+ missing.push('[META] since');
95
+ }
96
+ if (!meta.why) {
97
+ missing.push('[WHY]');
98
+ }
99
+ return {
100
+ valid: missing.length === 0,
101
+ missing
102
+ };
103
+ }
104
+ }
105
+ /**
106
+ * AI Feed Generator class
107
+ * Generates structured data for AI consumption
108
+ */
109
+ export class AIFeedGenerator {
110
+ gitAnalyzer;
111
+ headerScanner;
112
+ /**
113
+ * Constructor
114
+ *
115
+ * @param gitAnalyzer - GitAnalyzer instance
116
+ */
117
+ constructor(gitAnalyzer) {
118
+ this.gitAnalyzer = gitAnalyzer;
119
+ this.headerScanner = new FileHeaderScanner();
120
+ }
121
+ /**
122
+ * Generate AI feed
123
+ * Integrated into codemap generate command
124
+ *
125
+ * @param projectRoot - Project root directory
126
+ * @param options - Generation options
127
+ * @param options.includeGitHistory - Whether to include Git history analysis (default: false)
128
+ * @returns AIFeed[] feed list (sorted by gravity descending)
129
+ */
130
+ async generate(projectRoot, options) {
131
+ const includeGitHistory = options?.includeGitHistory ?? false;
132
+ // 1. Get all TypeScript files
133
+ const files = await globby(['src/**/*.ts'], {
134
+ cwd: projectRoot,
135
+ ignore: ['**/*.d.ts', '**/node_modules/**', '**/dist/**']
136
+ });
137
+ const feed = [];
138
+ // 2. First pass: collect basic info
139
+ for (const file of files) {
140
+ const fullPath = path.join(projectRoot, file);
141
+ // Skip non-existent files (globby may return deleted files)
142
+ if (!fs.existsSync(fullPath)) {
143
+ continue;
144
+ }
145
+ const header = this.headerScanner.scan(fullPath);
146
+ // Only scan Git history if explicitly enabled
147
+ const heat = includeGitHistory
148
+ ? await this.scanGitHistory(file, projectRoot)
149
+ : { freq30d: 0, lastType: 'unknown', lastDate: null, stability: true };
150
+ feed.push({
151
+ file,
152
+ gravity: 0, // Will be calculated in second pass
153
+ heat,
154
+ meta: {
155
+ since: header.since,
156
+ owner: header.owner,
157
+ stable: header.stable,
158
+ why: header.why
159
+ },
160
+ deps: header.deps ?? [],
161
+ dependents: []
162
+ });
163
+ }
164
+ // 3. Second pass: calculate dependencies
165
+ this.calculateDependencies(feed, projectRoot);
166
+ // 4. Sort by gravity descending
167
+ return feed.sort((a, b) => b.gravity - a.gravity);
168
+ }
169
+ /**
170
+ * Output AI feed file
171
+ *
172
+ * @param feed - AI feed list
173
+ * @param outputPath - Output file path
174
+ */
175
+ writeFeedFile(feed, outputPath) {
176
+ const lines = [
177
+ '# CODEMAP AI FEED',
178
+ `# Generated: ${new Date().toISOString()}`,
179
+ ''
180
+ ];
181
+ for (const f of feed) {
182
+ const lastDateStr = f.heat.lastDate ?? 'never';
183
+ lines.push(`FILE: ${f.file}`);
184
+ lines.push(`GRAVITY: ${f.gravity} | HEAT: ${f.heat.freq30d}/${f.heat.lastType}/${lastDateStr}`);
185
+ lines.push(`META: since=${f.meta.since ?? 'unknown'} stable=${f.meta.stable ?? 'unknown'} why=${f.meta.why ?? 'none'}`);
186
+ lines.push(`IMPACT: ${f.dependents.length} files depend on this`);
187
+ lines.push(`DEPS: ${f.deps.join(', ') || 'none'}`);
188
+ lines.push('---');
189
+ lines.push('');
190
+ }
191
+ // Ensure directory exists
192
+ const outputDir = path.dirname(outputPath);
193
+ if (!fs.existsSync(outputDir)) {
194
+ fs.mkdirSync(outputDir, { recursive: true });
195
+ }
196
+ fs.writeFileSync(outputPath, lines.join('\n'), 'utf-8');
197
+ }
198
+ /**
199
+ * Scan Git history for heat score
200
+ *
201
+ * @param filePath - File path (relative to projectRoot)
202
+ * @param projectRoot - Project root directory
203
+ * @returns HeatScore heat score
204
+ */
205
+ async scanGitHistory(filePath, projectRoot) {
206
+ return this.gitAnalyzer.analyzeFileHeat(filePath, projectRoot);
207
+ }
208
+ /**
209
+ * Calculate dependencies
210
+ * Scan import statements, build dependency graph
211
+ *
212
+ * @param feed - AI feed list
213
+ * @param projectRoot - Project root directory
214
+ */
215
+ calculateDependencies(feed, projectRoot) {
216
+ const fileMap = new Map();
217
+ // Build file map
218
+ for (const item of feed) {
219
+ fileMap.set(item.file, item);
220
+ }
221
+ // Scan import statements for each file
222
+ for (const item of feed) {
223
+ const fullPath = path.join(projectRoot, item.file);
224
+ try {
225
+ const content = fs.readFileSync(fullPath, 'utf-8');
226
+ // Scan import statements, match relative path imports
227
+ // Match: import ... from './path' or import ... from '../path'
228
+ const importMatches = [...content.matchAll(/from\s+['"](\.\.?\/[^'"]+)['"]/g)];
229
+ for (const match of importMatches) {
230
+ const importPath = match[1];
231
+ if (!importPath)
232
+ continue;
233
+ // Resolve import path to path relative to src
234
+ const resolvedPath = this.resolveImportPath(item.file, importPath);
235
+ if (resolvedPath) {
236
+ // Normalize path: convert .js to .ts, or add .ts if no extension
237
+ let normalizedPath;
238
+ if (resolvedPath.endsWith('.ts')) {
239
+ normalizedPath = resolvedPath;
240
+ }
241
+ else if (resolvedPath.endsWith('.js')) {
242
+ normalizedPath = resolvedPath.slice(0, -3) + '.ts';
243
+ }
244
+ else {
245
+ normalizedPath = resolvedPath + '.ts';
246
+ }
247
+ if (!item.deps.includes(normalizedPath)) {
248
+ item.deps.push(normalizedPath);
249
+ }
250
+ // Check if target file exists in feed and add to dependents
251
+ const possiblePaths = [
252
+ resolvedPath,
253
+ resolvedPath.endsWith('.js') ? resolvedPath.slice(0, -3) + '.ts' : resolvedPath + '.ts',
254
+ resolvedPath + '/index.ts'
255
+ ];
256
+ for (const possiblePath of possiblePaths) {
257
+ if (fileMap.has(possiblePath)) {
258
+ // Add to target file's dependents
259
+ const target = fileMap.get(possiblePath);
260
+ if (target && !target.dependents.includes(item.file)) {
261
+ target.dependents.push(item.file);
262
+ }
263
+ break;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
269
+ catch {
270
+ // Skip on read failure
271
+ }
272
+ }
273
+ // Recalculate gravity (out-degree + in-degree)
274
+ for (const item of feed) {
275
+ item.gravity = item.deps.length + item.dependents.length;
276
+ }
277
+ }
278
+ /**
279
+ * Resolve import path to path relative to project root
280
+ *
281
+ * @param currentFile - Current file path
282
+ * @param importPath - Import path from import statement
283
+ * @returns Resolved path, or null if cannot resolve
284
+ */
285
+ resolveImportPath(currentFile, importPath) {
286
+ // Get current file's directory
287
+ const currentDir = path.dirname(currentFile);
288
+ // Resolve relative path
289
+ const resolved = path.normalize(path.join(currentDir, importPath));
290
+ // Ensure path is under src directory
291
+ if (!resolved.startsWith('src/')) {
292
+ return null;
293
+ }
294
+ return resolved;
295
+ }
296
+ /**
297
+ * Scan file header (convenience method)
298
+ * Delegates to FileHeaderScanner
299
+ *
300
+ * @param filePath - File path
301
+ * @returns FileMeta file metadata
302
+ */
303
+ scanFileHeader(filePath) {
304
+ return this.headerScanner.scan(filePath);
305
+ }
306
+ /**
307
+ * Calculate scores for a single feed item
308
+ * Returns normalized scores
309
+ *
310
+ * @param feed - AI feed item
311
+ * @param maxGravity - Maximum gravity value for normalization
312
+ * @param maxImpact - Maximum impact value for normalization
313
+ * @returns Object with gravity, impact, heat scores
314
+ */
315
+ calculateScores(feed, maxGravity = 20, maxImpact = 50) {
316
+ const gravity = feed.deps.length + feed.dependents.length;
317
+ const impact = feed.dependents.length;
318
+ const heat = feed.heat.freq30d;
319
+ return {
320
+ gravity: Math.min(gravity / (maxGravity || 1), 1),
321
+ impact: Math.min(impact / (maxImpact || 1), 1),
322
+ heat: Math.min(heat / 10, 1)
323
+ };
324
+ }
325
+ /**
326
+ * Calculate file risk level
327
+ * Based on REQUIREMENTS section 8.6 risk scoring formula
328
+ *
329
+ * @param feed - Single file AI feed
330
+ * @returns Risk level: 'high' | 'medium' | 'low'
331
+ */
332
+ calculateRisk(feed) {
333
+ const gravity = feed.gravity;
334
+ const heat = feed.heat;
335
+ const impact = feed.dependents.length;
336
+ const stable = feed.meta.stable ?? true;
337
+ return this.gitAnalyzer.calculateRiskLevel(gravity, heat, impact, stable);
338
+ }
339
+ /**
340
+ * Batch calculate risk levels
341
+ *
342
+ * @param feedList - AI feed list
343
+ * @returns Map<file path, risk level>
344
+ */
345
+ calculateRisks(feedList) {
346
+ const result = new Map();
347
+ for (const feed of feedList) {
348
+ result.set(feed.file, this.calculateRisk(feed));
349
+ }
350
+ return result;
351
+ }
352
+ /**
353
+ * Get high risk file list
354
+ *
355
+ * @param feedList - AI feed list
356
+ * @returns High risk file list
357
+ */
358
+ getHighRiskFiles(feedList) {
359
+ return feedList.filter(f => this.calculateRisk(f) === 'high');
360
+ }
361
+ /**
362
+ * Generate JSON format AI feed
363
+ * For programmatic processing
364
+ *
365
+ * @param feed - AI feed list
366
+ * @param outputPath - Output file path
367
+ */
368
+ writeFeedFileJson(feed, outputPath) {
369
+ // Ensure directory exists
370
+ const outputDir = path.dirname(outputPath);
371
+ if (!fs.existsSync(outputDir)) {
372
+ fs.mkdirSync(outputDir, { recursive: true });
373
+ }
374
+ fs.writeFileSync(outputPath, JSON.stringify(feed, null, 2), 'utf-8');
375
+ }
376
+ }
377
+ //# sourceMappingURL=ai-feed-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-feed-generator.js","sourceRoot":"","sources":["../../src/orchestrator/ai-feed-generator.ts"],"names":[],"mappings":"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"}
@@ -214,6 +214,79 @@ mycodemap analyze -i show -t "src/index.ts" --output-mode human
214
214
 
215
215
  ---
216
216
 
217
+ ## design - 设计契约输入、范围映射与验证
218
+
219
+ > `design` 为 human-authored design contract 提供正式输入面。默认文件名是 `mycodemap.design.md`,canonical 模板位于 `docs/product-specs/DESIGN_CONTRACT_TEMPLATE.md`。
220
+
221
+ ### validate
222
+
223
+ ```bash
224
+ # 使用默认文件名
225
+ mycodemap design validate mycodemap.design.md --json
226
+
227
+ # 显式指定文件
228
+ mycodemap design validate docs/designs/login.design.md
229
+ ```
230
+
231
+ ### 必填 sections
232
+
233
+ | Section | 作用 |
234
+ |---------|------|
235
+ | `Goal` | 定义本次要达成的结果 |
236
+ | `Constraints` | 定义边界、兼容性和约束 |
237
+ | `Acceptance Criteria` | 定义可验证的成功标准 |
238
+ | `Non-Goals` | 明确本次不做什么,防止 scope drift |
239
+
240
+ ### 输出与失败语义
241
+
242
+ - `--json` 输出纯结构化 diagnostics
243
+ - 缺失必填 section、重复 section、空 section、未知 heading 都会被显式报告
244
+ - blocker diagnostics 存在时命令返回非零 exit code
245
+
246
+ ### map
247
+
248
+ ```bash
249
+ # 先校验,再映射 candidate scope
250
+ mycodemap design validate mycodemap.design.md --json
251
+ mycodemap design map mycodemap.design.md --json
252
+ ```
253
+
254
+ - `design map` 返回 `summary`、`candidates`、`diagnostics`、`unknowns`
255
+ - `candidates[]` 会同时暴露 `kind`、`path`、`reasons`、`dependencies`、`testImpact`、`risk`、`confidence`
256
+ - blocker diagnostics 包括 `no-candidates`、`over-broad-scope`、`high-risk-scope`
257
+ - 若 diagnostics 中存在 blocker,命令返回非零 exit code
258
+
259
+ ### handoff
260
+
261
+ ```bash
262
+ # 先固定 design input / scope,再生成 handoff package
263
+ mycodemap design validate mycodemap.design.md --json
264
+ mycodemap design map mycodemap.design.md --json
265
+ mycodemap design handoff mycodemap.design.md --json
266
+ ```
267
+
268
+ - `design handoff` 返回 `readyForExecution`、`approvals`、`assumptions`、`openQuestions`
269
+ - human mode 默认写入 `.mycodemap/handoffs/{stem}.handoff.md|json`
270
+ - `--json` 保持纯 JSON,不混入 prose
271
+ - review-needed 通过 `readyForExecution=false` 表达;只有 blocker diagnostics 才返回非零 exit code
272
+
273
+ ### verify
274
+
275
+ ```bash
276
+ # 使用 reviewed handoff truth 做 checklist / drift 校验
277
+ mycodemap design validate mycodemap.design.md --json
278
+ mycodemap design map mycodemap.design.md --json
279
+ mycodemap design handoff mycodemap.design.md --json
280
+ mycodemap design verify mycodemap.design.md --json
281
+ ```
282
+
283
+ - `design verify` 返回 `summary`、`checklist`、`drift`、`diagnostics`
284
+ - `checklist[]` 直接来自 `Acceptance Criteria`,并保留 `status` + `evidenceRefs`
285
+ - `drift[]` 至少区分 `scope-extra`、`acceptance-unverified`、`handoff-missing`
286
+ - review-needed 通过 `readyForExecution=false` + warning diagnostics 表达;只有 `ok=false` 或 blocker diagnostics 才返回非零 exit code
287
+
288
+ ---
289
+
217
290
  ## ci - CI 门禁
218
291
 
219
292
  ### 子命令