mdkg 0.3.7 → 0.3.9

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 (53) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/CLI_COMMAND_MATRIX.md +85 -24
  3. package/README.md +51 -26
  4. package/dist/cli.js +72 -35
  5. package/dist/command-contract.json +354 -9
  6. package/dist/commands/capability.js +1 -0
  7. package/dist/commands/doctor.js +7 -7
  8. package/dist/commands/format.js +40 -1
  9. package/dist/commands/handoff.js +6 -0
  10. package/dist/commands/init.js +84 -3
  11. package/dist/commands/new.js +12 -3
  12. package/dist/commands/skill.js +1 -1
  13. package/dist/commands/skill_mirror.js +22 -17
  14. package/dist/commands/skill_support.js +1 -1
  15. package/dist/commands/spec.js +76 -17
  16. package/dist/commands/subgraph.js +7 -4
  17. package/dist/commands/upgrade.js +137 -30
  18. package/dist/commands/validate.js +106 -3
  19. package/dist/commands/work.js +12 -5
  20. package/dist/core/config.js +132 -0
  21. package/dist/graph/agent_file_types.js +59 -20
  22. package/dist/graph/capabilities_indexer.js +45 -3
  23. package/dist/graph/indexer.js +5 -0
  24. package/dist/graph/template_schema.js +37 -17
  25. package/dist/graph/validate_graph.js +11 -5
  26. package/dist/init/AGENT_START.md +10 -9
  27. package/dist/init/CLI_COMMAND_MATRIX.md +30 -17
  28. package/dist/init/README.md +11 -9
  29. package/dist/init/config.json +15 -0
  30. package/dist/init/core/COLLABORATION.md +45 -0
  31. package/dist/init/core/HUMAN.md +7 -1
  32. package/dist/init/core/core.md +1 -0
  33. package/dist/init/core/rule-1-mdkg-conventions.md +3 -0
  34. package/dist/init/core/rule-3-cli-contract.md +5 -5
  35. package/dist/init/init-manifest.json +78 -13
  36. package/dist/init/llms.txt +2 -1
  37. package/dist/init/skills/default/author-mdkg-skill/SKILL.md +211 -0
  38. package/dist/init/skills/default/pursue-mdkg-goal/SKILL.md +10 -0
  39. package/dist/init/skills/default/select-work-and-ground-context/SKILL.md +8 -0
  40. package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +73 -9
  41. package/dist/init/templates/default/manifest.md +45 -0
  42. package/dist/init/templates/specs/agent.MANIFEST.md +80 -0
  43. package/dist/init/templates/specs/api.MANIFEST.md +33 -0
  44. package/dist/init/templates/specs/base.MANIFEST.md +120 -0
  45. package/dist/init/templates/specs/capability.MANIFEST.md +45 -0
  46. package/dist/init/templates/specs/integration.MANIFEST.md +25 -0
  47. package/dist/init/templates/specs/model.MANIFEST.md +21 -0
  48. package/dist/init/templates/specs/project.MANIFEST.md +39 -0
  49. package/dist/init/templates/specs/runtime-agent.MANIFEST.md +49 -0
  50. package/dist/init/templates/specs/runtime-image.MANIFEST.md +21 -0
  51. package/dist/init/templates/specs/tool.MANIFEST.md +25 -0
  52. package/dist/util/argparse.js +3 -0
  53. package/package.json +19 -3
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_SKILL_MIRROR_TARGETS = void 0;
7
+ exports.defaultCustomizationConfig = defaultCustomizationConfig;
6
8
  exports.validateConfigSchema = validateConfigSchema;
7
9
  exports.loadConfig = loadConfig;
8
10
  const fs_1 = __importDefault(require("fs"));
@@ -30,6 +32,7 @@ const DEFAULT_ARCHIVE_LARGE_CACHE_WARNING_BYTES = 26214400;
30
32
  const DEFAULT_SQLITE_COMMIT_WARNING_BYTES = 52428800;
31
33
  const DEFAULT_LOCK_TIMEOUT_MS = 10000;
32
34
  const DEFAULT_SUBGRAPH_MAX_STALE_SECONDS = 3600;
35
+ exports.DEFAULT_SKILL_MIRROR_TARGETS = [".agents/skills", ".claude/skills"];
33
36
  const DEFAULT_PROJECT_DB_CONFIG = {
34
37
  enabled: false,
35
38
  schema_version: project_db_1.PROJECT_DB_CONFIG_SCHEMA_VERSION,
@@ -41,6 +44,20 @@ const DEFAULT_PROJECT_DB_CONFIG = {
41
44
  receipts_path: project_db_1.PROJECT_DB_RECEIPTS_DIR,
42
45
  migration_table: project_db_1.PROJECT_DB_MIGRATION_TABLE,
43
46
  };
47
+ function defaultCustomizationConfig() {
48
+ return {
49
+ standards: {
50
+ profile: "default",
51
+ refs: [],
52
+ },
53
+ core_docs: {
54
+ custom_paths: [],
55
+ },
56
+ skill_mirrors: {
57
+ targets: [...exports.DEFAULT_SKILL_MIRROR_TARGETS],
58
+ },
59
+ };
60
+ }
44
61
  function isObject(value) {
45
62
  return typeof value === "object" && value !== null && !Array.isArray(value);
46
63
  }
@@ -171,6 +188,35 @@ function requireKnownLowercaseUniqueStringArray(value, path, allowed, errors, al
171
188
  }
172
189
  return items;
173
190
  }
191
+ function requireUniqueStringArray(value, path, errors, allowEmpty = false) {
192
+ const items = requireStringArray(value, path, errors);
193
+ if (items === undefined) {
194
+ return undefined;
195
+ }
196
+ if (items.length === 0) {
197
+ if (!allowEmpty) {
198
+ errors.push(`${path} must not be empty`);
199
+ }
200
+ return items;
201
+ }
202
+ const seen = new Set();
203
+ for (let i = 0; i < items.length; i += 1) {
204
+ const item = items[i];
205
+ if (item.trim().length === 0) {
206
+ errors.push(`${path}[${i}] must not be empty`);
207
+ continue;
208
+ }
209
+ if (item !== item.trim()) {
210
+ errors.push(`${path}[${i}] must not include surrounding whitespace`);
211
+ }
212
+ if (seen.has(item)) {
213
+ errors.push(`${path} must not contain duplicate value "${item}"`);
214
+ continue;
215
+ }
216
+ seen.add(item);
217
+ }
218
+ return items;
219
+ }
174
220
  function requireObject(value, path, errors) {
175
221
  if (!isObject(value)) {
176
222
  errors.push(`${path} must be an object`);
@@ -213,6 +259,33 @@ function requireContainedPath(value, path, errors) {
213
259
  return undefined;
214
260
  }
215
261
  }
262
+ function requireContainedPathArray(value, path, errors, allowEmpty = true) {
263
+ if (!Array.isArray(value)) {
264
+ errors.push(`${path} must be an array of relative paths`);
265
+ return undefined;
266
+ }
267
+ if (value.length === 0) {
268
+ if (!allowEmpty) {
269
+ errors.push(`${path} must not be empty`);
270
+ }
271
+ return [];
272
+ }
273
+ const items = [];
274
+ const seen = new Set();
275
+ for (let i = 0; i < value.length; i += 1) {
276
+ const normalized = requireContainedPath(value[i], `${path}[${i}]`, errors);
277
+ if (!normalized) {
278
+ continue;
279
+ }
280
+ if (seen.has(normalized)) {
281
+ errors.push(`${path} must not contain duplicate path "${normalized}"`);
282
+ continue;
283
+ }
284
+ seen.add(normalized);
285
+ items.push(normalized);
286
+ }
287
+ return items;
288
+ }
216
289
  function requireSqlIdentifier(value, path, errors) {
217
290
  const raw = requireString(value, path, errors);
218
291
  if (raw === undefined) {
@@ -266,6 +339,10 @@ function validateConfigSchema(raw) {
266
339
  ? { output_dir: ".mdkg/bundles", default_profile: "private" }
267
340
  : requireObject(raw.bundles, "bundles", errors);
268
341
  const dbRaw = raw.db === undefined ? DEFAULT_PROJECT_DB_CONFIG : requireObject(raw.db, "db", errors);
342
+ const customizationDefaults = defaultCustomizationConfig();
343
+ const customizationRaw = raw.customization === undefined
344
+ ? customizationDefaults
345
+ : requireObject(raw.customization, "customization", errors);
269
346
  if (raw.bundle_imports !== undefined && raw.subgraphs !== undefined) {
270
347
  errors.push("config must not define both subgraphs and legacy bundle_imports");
271
348
  }
@@ -370,6 +447,60 @@ function validateConfigSchema(raw) {
370
447
  };
371
448
  }
372
449
  }
450
+ let customization;
451
+ if (customizationRaw) {
452
+ const standardsRaw = customizationRaw.standards === undefined
453
+ ? customizationDefaults.standards
454
+ : requireObject(customizationRaw.standards, "customization.standards", errors);
455
+ const coreDocsRaw = customizationRaw.core_docs === undefined
456
+ ? customizationDefaults.core_docs
457
+ : requireObject(customizationRaw.core_docs, "customization.core_docs", errors);
458
+ const skillMirrorsRaw = customizationRaw.skill_mirrors === undefined
459
+ ? customizationDefaults.skill_mirrors
460
+ : requireObject(customizationRaw.skill_mirrors, "customization.skill_mirrors", errors);
461
+ const standardsProfile = standardsRaw
462
+ ? standardsRaw.profile === undefined
463
+ ? customizationDefaults.standards.profile
464
+ : requireString(standardsRaw.profile, "customization.standards.profile", errors)
465
+ : undefined;
466
+ const standardsRefs = standardsRaw
467
+ ? standardsRaw.refs === undefined
468
+ ? customizationDefaults.standards.refs
469
+ : requireUniqueStringArray(standardsRaw.refs, "customization.standards.refs", errors, true)
470
+ : undefined;
471
+ const coreDocPaths = coreDocsRaw
472
+ ? coreDocsRaw.custom_paths === undefined
473
+ ? customizationDefaults.core_docs.custom_paths
474
+ : requireContainedPathArray(coreDocsRaw.custom_paths, "customization.core_docs.custom_paths", errors, true)
475
+ : undefined;
476
+ const mirrorTargets = skillMirrorsRaw
477
+ ? skillMirrorsRaw.targets === undefined
478
+ ? customizationDefaults.skill_mirrors.targets
479
+ : requireContainedPathArray(skillMirrorsRaw.targets, "customization.skill_mirrors.targets", errors, true)
480
+ : undefined;
481
+ if (standardsProfile !== undefined) {
482
+ if (standardsProfile.trim().length === 0) {
483
+ errors.push("customization.standards.profile must not be empty");
484
+ }
485
+ if (standardsProfile !== standardsProfile.trim()) {
486
+ errors.push("customization.standards.profile must not include surrounding whitespace");
487
+ }
488
+ }
489
+ if (standardsProfile && standardsRefs && coreDocPaths && mirrorTargets) {
490
+ customization = {
491
+ standards: {
492
+ profile: standardsProfile,
493
+ refs: standardsRefs,
494
+ },
495
+ core_docs: {
496
+ custom_paths: coreDocPaths,
497
+ },
498
+ skill_mirrors: {
499
+ targets: mirrorTargets,
500
+ },
501
+ };
502
+ }
503
+ }
373
504
  const packLimitsRaw = packRaw ? requireObject(packRaw.limits, "pack.limits", errors) : undefined;
374
505
  const pack = packRaw
375
506
  ? {
@@ -605,6 +736,7 @@ function validateConfigSchema(raw) {
605
736
  capabilities: capabilities,
606
737
  bundles: bundles,
607
738
  db: db,
739
+ customization: customization,
608
740
  subgraphs,
609
741
  pack: pack,
610
742
  templates: templates,
@@ -3,15 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AGENT_ATTRIBUTE_KEY_ORDER = exports.AGENT_FILE_BASENAMES = exports.AGENT_FILE_TYPES = void 0;
6
+ exports.AGENT_ATTRIBUTE_KEY_ORDER = exports.AGENT_FILE_BASENAMES = exports.AGENT_FILE_TYPES = exports.LEGACY_SPEC_BASENAME = exports.CANONICAL_MANIFEST_BASENAME = void 0;
7
7
  exports.isAgentFileType = isAgentFileType;
8
+ exports.isManifestSemanticType = isManifestSemanticType;
9
+ exports.collectManifestSiblingConflicts = collectManifestSiblingConflicts;
8
10
  exports.validateAgentFileName = validateAgentFileName;
9
11
  exports.validateAgentFrontmatter = validateAgentFrontmatter;
10
12
  exports.extractAgentAttributes = extractAgentAttributes;
11
13
  const path_1 = __importDefault(require("path"));
12
14
  const id_1 = require("../util/id");
13
15
  const refs_1 = require("../util/refs");
16
+ exports.CANONICAL_MANIFEST_BASENAME = "MANIFEST.md";
17
+ exports.LEGACY_SPEC_BASENAME = "SPEC.md";
14
18
  exports.AGENT_FILE_TYPES = [
19
+ "manifest",
15
20
  "spec",
16
21
  "work",
17
22
  "work_order",
@@ -21,7 +26,8 @@ exports.AGENT_FILE_TYPES = [
21
26
  "proposal",
22
27
  ];
23
28
  exports.AGENT_FILE_BASENAMES = {
24
- spec: "SPEC.md",
29
+ manifest: exports.CANONICAL_MANIFEST_BASENAME,
30
+ spec: exports.LEGACY_SPEC_BASENAME,
25
31
  work: "WORK.md",
26
32
  work_order: "WORK_ORDER.md",
27
33
  receipt: "RECEIPT.md",
@@ -29,23 +35,25 @@ exports.AGENT_FILE_BASENAMES = {
29
35
  dispute: "DISPUTE.md",
30
36
  proposal: "PROPOSAL.md",
31
37
  };
38
+ const MANIFEST_ATTRIBUTE_KEYS = [
39
+ "version",
40
+ "spec_kind",
41
+ "role",
42
+ "runtime_mode",
43
+ "work_contracts",
44
+ "requested_capabilities",
45
+ "skill_refs",
46
+ "tool_refs",
47
+ "model_refs",
48
+ "wasm_component_refs",
49
+ "runtime_image_refs",
50
+ "subagent_refs",
51
+ "resource_profile",
52
+ "update_policy",
53
+ ];
32
54
  exports.AGENT_ATTRIBUTE_KEY_ORDER = {
33
- spec: [
34
- "version",
35
- "spec_kind",
36
- "role",
37
- "runtime_mode",
38
- "work_contracts",
39
- "requested_capabilities",
40
- "skill_refs",
41
- "tool_refs",
42
- "model_refs",
43
- "wasm_component_refs",
44
- "runtime_image_refs",
45
- "subagent_refs",
46
- "resource_profile",
47
- "update_policy",
48
- ],
55
+ manifest: MANIFEST_ATTRIBUTE_KEYS,
56
+ spec: MANIFEST_ATTRIBUTE_KEYS,
49
57
  work: [
50
58
  "version",
51
59
  "agent_id",
@@ -207,9 +215,39 @@ function formatError(filePath, message) {
207
215
  function isAgentFileType(type) {
208
216
  return exports.AGENT_FILE_TYPES.includes(type);
209
217
  }
218
+ function isManifestSemanticType(type) {
219
+ return type === "manifest" || type === "spec";
220
+ }
221
+ function collectManifestSiblingConflicts(filePaths, formatDir) {
222
+ const basenamesByDir = new Map();
223
+ for (const filePath of filePaths) {
224
+ const basename = path_1.default.basename(filePath);
225
+ if (basename !== exports.CANONICAL_MANIFEST_BASENAME && basename !== exports.LEGACY_SPEC_BASENAME) {
226
+ continue;
227
+ }
228
+ const dirPath = path_1.default.dirname(filePath);
229
+ const basenames = basenamesByDir.get(dirPath) ?? new Set();
230
+ basenames.add(basename);
231
+ basenamesByDir.set(dirPath, basenames);
232
+ }
233
+ const conflicts = [];
234
+ for (const [dirPath, basenames] of Array.from(basenamesByDir.entries()).sort()) {
235
+ if (basenames.has(exports.CANONICAL_MANIFEST_BASENAME) && basenames.has(exports.LEGACY_SPEC_BASENAME)) {
236
+ conflicts.push(`${formatDir(dirPath)}: MANIFEST.md and SPEC.md cannot both exist in the same logical Omni unit; keep MANIFEST.md and remove the legacy SPEC.md alias`);
237
+ }
238
+ }
239
+ return conflicts;
240
+ }
210
241
  function validateAgentFileName(type, filePath) {
242
+ const basename = path_1.default.basename(filePath);
243
+ if (type === "spec" && basename === exports.CANONICAL_MANIFEST_BASENAME) {
244
+ return;
245
+ }
211
246
  const expected = exports.AGENT_FILE_BASENAMES[type];
212
- if (path_1.default.basename(filePath) !== expected) {
247
+ if (basename !== expected) {
248
+ if (isManifestSemanticType(type)) {
249
+ throw formatError(filePath, `manifest files must be named MANIFEST.md (canonical) or SPEC.md (legacy alias); ${type} files must be named ${expected}`);
250
+ }
213
251
  throw formatError(filePath, `${type} files must be named ${expected}`);
214
252
  }
215
253
  }
@@ -303,7 +341,7 @@ function validateSpecKind(value, filePath) {
303
341
  }
304
342
  const route = DOCUMENTATION_ONLY_SPEC_KIND_ROUTES[value];
305
343
  if (route) {
306
- throw formatError(filePath, `spec_kind ${value} is documentation-only; ${route}. SPEC.md must define a reusable invocable capability surface.`);
344
+ throw formatError(filePath, `spec_kind ${value} is documentation-only; ${route}. MANIFEST.md must define a reusable invocable capability surface; legacy SPEC.md follows the same contract.`);
307
345
  }
308
346
  throw formatError(filePath, `spec_kind must be one of ${Array.from(SPEC_KIND_VALUES).join(", ")}; documentation-only records belong in normal mdkg nodes such as task, test, epic, goal, checkpoint, EDD, PRD, DEC, bug, feedback, dispute, or proposal.`);
309
347
  }
@@ -398,6 +436,7 @@ function validateAgentFrontmatter(type, frontmatter, filePath) {
398
436
  const version = expectString(frontmatter, "version", filePath);
399
437
  requireSemver(version, "version", filePath);
400
438
  switch (type) {
439
+ case "manifest":
401
440
  case "spec": {
402
441
  const specKind = optionalString(frontmatter, "spec_kind", filePath);
403
442
  if (specKind) {
@@ -10,6 +10,7 @@ const crypto_1 = __importDefault(require("crypto"));
10
10
  const fs_1 = __importDefault(require("fs"));
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const indexer_1 = require("./indexer");
13
+ const agent_file_types_1 = require("./agent_file_types");
13
14
  const skills_indexer_1 = require("./skills_indexer");
14
15
  exports.CAPABILITIES_INDEX_RELATIVE_PATH = ".mdkg/index/capabilities.json";
15
16
  exports.CAPABILITY_KINDS = ["skill", "spec", "work", "core", "design"];
@@ -41,7 +42,7 @@ function workspaceMdkgPrefix(entry) {
41
42
  return `${wsPath}${mdkgDir}/`;
42
43
  }
43
44
  function classifyNodeCapability(node, config) {
44
- if (node.type === "spec") {
45
+ if ((0, agent_file_types_1.isManifestSemanticType)(node.type)) {
45
46
  return "spec";
46
47
  }
47
48
  if (node.type === "work") {
@@ -115,7 +116,7 @@ function resolveWorkSpecs(index, workNode) {
115
116
  const candidates = new Map();
116
117
  const workRefs = nodeRefSet(workNode);
117
118
  for (const node of Object.values(index.nodes)) {
118
- if (node.type !== "spec" || node.ws !== workNode.ws) {
119
+ if (!(0, agent_file_types_1.isManifestSemanticType)(node.type) || node.ws !== workNode.ws) {
119
120
  continue;
120
121
  }
121
122
  const agentId = typeof workNode.attributes.agent_id === "string" ? workNode.attributes.agent_id : undefined;
@@ -159,9 +160,49 @@ function buildCapabilityLinkage(index, node, kind) {
159
160
  receipt_qids: receipts.map((receiptNode) => receiptNode.qid),
160
161
  };
161
162
  }
163
+ function manifestCapabilityMetadata(node) {
164
+ if (!(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
165
+ return undefined;
166
+ }
167
+ const sourceBasename = path_1.default.posix.basename(node.path);
168
+ const compatibilityMode = sourceBasename === agent_file_types_1.LEGACY_SPEC_BASENAME
169
+ ? "legacy"
170
+ : node.type === "spec"
171
+ ? "transitional"
172
+ : "canonical";
173
+ return {
174
+ semantic_kind: "manifest",
175
+ source_basename: sourceBasename,
176
+ source_type: node.type,
177
+ canonical_basename: agent_file_types_1.CANONICAL_MANIFEST_BASENAME,
178
+ legacy_basename: agent_file_types_1.LEGACY_SPEC_BASENAME,
179
+ compatibility_mode: compatibilityMode,
180
+ legacy: compatibilityMode !== "canonical",
181
+ deprecated: compatibilityMode !== "canonical",
182
+ command_family: "manifest",
183
+ legacy_command_family: "spec",
184
+ };
185
+ }
186
+ function manifestSearchAliases(metadata) {
187
+ if (!metadata) {
188
+ return [];
189
+ }
190
+ return [
191
+ "manifest",
192
+ "manifest.md",
193
+ "MANIFEST.md",
194
+ "manifest capability",
195
+ "MANIFEST.md legacy SPEC.md",
196
+ "spec.md compatibility alias",
197
+ "legacy spec.md",
198
+ metadata.compatibility_mode,
199
+ metadata.source_basename,
200
+ ];
201
+ }
162
202
  function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
163
203
  const absolutePath = path_1.default.resolve(root, node.path);
164
204
  const content = fs_1.default.readFileSync(absolutePath, "utf8");
205
+ const manifest = kind === "spec" ? manifestCapabilityMetadata(node) : undefined;
165
206
  const record = {
166
207
  kind,
167
208
  workspace: node.ws,
@@ -172,7 +213,7 @@ function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
172
213
  title: node.title,
173
214
  tags: [...node.tags],
174
215
  refs: [...node.refs],
175
- aliases: [...node.aliases],
216
+ aliases: Array.from(new Set([...node.aliases, ...manifestSearchAliases(manifest)])),
176
217
  links: [...node.links],
177
218
  artifacts: [...node.artifacts],
178
219
  updated: node.updated,
@@ -182,6 +223,7 @@ function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
182
223
  node_type: node.type,
183
224
  };
184
225
  if (kind === "spec") {
226
+ record.manifest = manifest;
185
227
  record.spec = pickAttributes(node.attributes, [
186
228
  "version",
187
229
  "spec_kind",
@@ -10,6 +10,7 @@ const node_1 = require("./node");
10
10
  const workspace_files_1 = require("./workspace_files");
11
11
  const validate_graph_1 = require("./validate_graph");
12
12
  const template_schema_1 = require("./template_schema");
13
+ const agent_file_types_1 = require("./agent_file_types");
13
14
  function normalizeEdgeTarget(value, ws) {
14
15
  if (value.includes(":")) {
15
16
  return value;
@@ -48,6 +49,10 @@ function buildIndex(root, config, options = {}) {
48
49
  for (const alias of workspaceAliases) {
49
50
  idsByWorkspace[alias] = new Set();
50
51
  const files = docFilesByAlias[alias];
52
+ const manifestConflicts = (0, agent_file_types_1.collectManifestSiblingConflicts)(files, (dirPath) => path_1.default.relative(root, dirPath).split(path_1.default.sep).join("/") || ".");
53
+ if (manifestConflicts.length > 0 && !tolerant) {
54
+ throw new Error(manifestConflicts[0]);
55
+ }
51
56
  for (const filePath of files) {
52
57
  if (path_1.default.basename(filePath) === "core.md" && path_1.default.basename(path_1.default.dirname(filePath)) === "core") {
53
58
  continue;
@@ -9,6 +9,9 @@ const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const frontmatter_1 = require("./frontmatter");
11
11
  const builtin_1 = require("../templates/builtin");
12
+ const TEMPLATE_SCHEMA_ALIASES = {
13
+ spec: "manifest",
14
+ };
12
15
  function listMarkdownFiles(dir) {
13
16
  if (!fs_1.default.existsSync(dir)) {
14
17
  return [];
@@ -46,6 +49,34 @@ function addKeyToSchema(schema, key, kind, filePath) {
46
49
  schema.listKeys.add(key);
47
50
  }
48
51
  }
52
+ function cloneSchema(schema, type) {
53
+ return {
54
+ type,
55
+ allowedKeys: new Set(schema.allowedKeys),
56
+ keyKinds: { ...schema.keyKinds },
57
+ listKeys: new Set(schema.listKeys),
58
+ };
59
+ }
60
+ function loadBundledSchema(type) {
61
+ const bundledPath = (0, builtin_1.requireBundledTemplatePath)(type);
62
+ const content = fs_1.default.readFileSync(bundledPath, "utf8");
63
+ const { frontmatter } = (0, frontmatter_1.parseFrontmatter)(content, bundledPath);
64
+ const typeValue = frontmatter.type;
65
+ if (typeValue !== type) {
66
+ throw new Error(`bundled template fallback type mismatch for ${type}: ${bundledPath}`);
67
+ }
68
+ const schema = {
69
+ type,
70
+ allowedKeys: new Set(),
71
+ keyKinds: {},
72
+ listKeys: new Set(),
73
+ };
74
+ for (const [key, value] of Object.entries(frontmatter)) {
75
+ const kind = getValueKind(value);
76
+ addKeyToSchema(schema, key, kind, bundledPath);
77
+ }
78
+ return schema;
79
+ }
49
80
  function loadTemplateSchemas(root, config, requiredTypes) {
50
81
  return loadTemplateSchemasWithInfo(root, config, requiredTypes).schemas;
51
82
  }
@@ -84,24 +115,13 @@ function loadTemplateSchemasWithInfo(root, config, requiredTypes) {
84
115
  if (requiredTypes) {
85
116
  const required = Array.from(requiredTypes, (value) => value.toLowerCase());
86
117
  for (const missingType of required.filter((value) => !schemas[value])) {
87
- const bundledPath = (0, builtin_1.requireBundledTemplatePath)(missingType);
88
- const content = fs_1.default.readFileSync(bundledPath, "utf8");
89
- const { frontmatter } = (0, frontmatter_1.parseFrontmatter)(content, bundledPath);
90
- const typeValue = frontmatter.type;
91
- if (typeValue !== missingType) {
92
- throw new Error(`bundled template fallback type mismatch for ${missingType}: ${bundledPath}`);
93
- }
94
- const schema = {
95
- type: missingType,
96
- allowedKeys: new Set(),
97
- keyKinds: {},
98
- listKeys: new Set(),
99
- };
100
- schemas[missingType] = schema;
101
- for (const [key, value] of Object.entries(frontmatter)) {
102
- const kind = getValueKind(value);
103
- addKeyToSchema(schema, key, kind, bundledPath);
118
+ const aliasType = TEMPLATE_SCHEMA_ALIASES[missingType];
119
+ if (aliasType) {
120
+ const aliasSchema = schemas[aliasType] ?? loadBundledSchema(aliasType);
121
+ schemas[missingType] = cloneSchema(aliasSchema, missingType);
122
+ continue;
104
123
  }
124
+ schemas[missingType] = loadBundledSchema(missingType);
105
125
  fallbackTypes.push(missingType);
106
126
  }
107
127
  }
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.collectGraphErrors = collectGraphErrors;
4
4
  exports.validateGraph = validateGraph;
5
+ const agent_file_types_1 = require("./agent_file_types");
5
6
  const refs_1 = require("../util/refs");
7
+ const qid_1 = require("../util/qid");
6
8
  const goal_scope_1 = require("./goal_scope");
7
9
  function pushError(errors, message) {
8
10
  if (errors) {
@@ -147,7 +149,7 @@ function validateAgentWorkflowSpecWorkContracts(index, allowMissing, errors) {
147
149
  });
148
150
  }
149
151
  for (const [qid, node] of Object.entries(index.nodes)) {
150
- if (node.type !== "spec") {
152
+ if (!(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
151
153
  continue;
152
154
  }
153
155
  const workContracts = node.attributes.work_contracts;
@@ -233,7 +235,7 @@ function validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, external
233
235
  function buildSpecRolesByWorkspace(index) {
234
236
  const specRolesByWorkspace = {};
235
237
  for (const node of Object.values(index.nodes)) {
236
- if (node.type !== "spec") {
238
+ if (!(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
237
239
  continue;
238
240
  }
239
241
  if (!specRolesByWorkspace[node.ws]) {
@@ -247,8 +249,12 @@ function buildSpecRolesByWorkspace(index) {
247
249
  return specRolesByWorkspace;
248
250
  }
249
251
  function resolveSpecRole(index, ws, value) {
250
- const node = resolveTypedNodeRef(index, ws, value, "spec");
251
- if (!node) {
252
+ const resolved = (0, qid_1.resolveQid)(index, value, ws);
253
+ if (resolved.status !== "ok") {
254
+ return undefined;
255
+ }
256
+ const node = index.nodes[resolved.qid];
257
+ if (!node || !(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
252
258
  return undefined;
253
259
  }
254
260
  return {
@@ -259,7 +265,7 @@ function resolveSpecRole(index, ws, value) {
259
265
  function validateAgentWorkflowSubagentRefs(index, allowMissing, externalWorkspaces, errors) {
260
266
  const specRolesByWorkspace = buildSpecRolesByWorkspace(index);
261
267
  for (const [qid, node] of Object.entries(index.nodes)) {
262
- if (node.type !== "spec" && node.type !== "work") {
268
+ if (!(0, agent_file_types_1.isManifestSemanticType)(node.type) && node.type !== "work") {
263
269
  continue;
264
270
  }
265
271
  const subagentRefs = node.attributes.subagent_refs;
@@ -6,14 +6,15 @@ mdkg is pre-v1 public alpha software. Treat generated graph, cache, bundle, and
6
6
 
7
7
  Read these files in order:
8
8
  1. `.mdkg/core/SOUL.md` if it exists
9
- 2. `.mdkg/core/HUMAN.md` if it exists
10
- 3. `.mdkg/README.md`
11
- 4. `CLI_COMMAND_MATRIX.md`
9
+ 2. `.mdkg/core/COLLABORATION.md` if it exists
10
+ 3. `.mdkg/core/HUMAN.md` if it exists as a legacy alias
11
+ 4. `.mdkg/README.md`
12
+ 5. `CLI_COMMAND_MATRIX.md`
12
13
 
13
14
  Trust order:
14
15
  - source code
15
16
  - mdkg rules, design docs, decisions, and work nodes
16
- - SOUL/HUMAN collaboration anchors
17
+ - SOUL/COLLABORATION anchors and legacy HUMAN notes
17
18
  - relevant skills
18
19
  - chat history
19
20
 
@@ -29,8 +30,8 @@ Agent operating prompt:
29
30
  - Treat goal `required_checks` as report-only guidance from mdkg. Run commands yourself, then record evidence in the goal or active work item.
30
31
  - Record skill improvement candidates during normal goal execution; edit `SKILL.md` only when the active node is explicit skill-maintenance work.
31
32
  - Use `mdkg skill list`, `mdkg skill search`, and `mdkg skill show <slug>` for skill discovery.
32
- - Use `mdkg capability list/search/show` for deterministic skills, `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
33
- - Use `mdkg spec list/show/validate` for focused optional `SPEC.md` capability records.
33
+ - Use `mdkg capability list/search/show` for deterministic skills, `MANIFEST.md` / legacy `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
34
+ - Use `mdkg manifest list/show/validate` for focused optional `MANIFEST.md` capability records; `mdkg spec ...` remains a legacy alias for one compatibility release.
34
35
  - Use `mdkg index` to refresh JSON compatibility caches and `.mdkg/index/mdkg.sqlite` when SQLite mode is enabled.
35
36
  - Treat `.mdkg/db` as project application state; use `mdkg db init` to create
36
37
  the generic scaffold and enable `db.enabled` without creating an active
@@ -111,9 +112,9 @@ Capability discovery:
111
112
  - `mdkg capability list --kind skill --json`
112
113
  - `mdkg capability search "<query>" --kind spec --json`
113
114
  - `mdkg capability search "<query>" --kind work --json`
114
- - `mdkg spec list --json`
115
- - `mdkg spec show <id-or-qid-or-alias> --json`
116
- - `mdkg spec validate <id-or-qid-or-alias> --json`
115
+ - `mdkg manifest list --json`
116
+ - `mdkg manifest show <id-or-qid-or-alias> --json`
117
+ - `mdkg manifest validate <id-or-qid-or-alias> --json`
117
118
 
118
119
  Conventions:
119
120
  - `AGENTS.md` is the Codex/OpenAI-oriented wrapper doc.