mdkg 0.3.7 → 0.3.8

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 (37) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/CLI_COMMAND_MATRIX.md +81 -22
  3. package/README.md +50 -25
  4. package/dist/cli.js +70 -34
  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/new.js +12 -3
  11. package/dist/commands/spec.js +76 -17
  12. package/dist/commands/subgraph.js +7 -4
  13. package/dist/commands/upgrade.js +70 -6
  14. package/dist/commands/validate.js +106 -3
  15. package/dist/commands/work.js +12 -5
  16. package/dist/graph/agent_file_types.js +59 -20
  17. package/dist/graph/capabilities_indexer.js +45 -3
  18. package/dist/graph/indexer.js +5 -0
  19. package/dist/graph/template_schema.js +37 -17
  20. package/dist/graph/validate_graph.js +11 -5
  21. package/dist/init/AGENT_START.md +5 -5
  22. package/dist/init/CLI_COMMAND_MATRIX.md +29 -16
  23. package/dist/init/README.md +11 -9
  24. package/dist/init/init-manifest.json +59 -4
  25. package/dist/init/templates/default/manifest.md +45 -0
  26. package/dist/init/templates/specs/agent.MANIFEST.md +80 -0
  27. package/dist/init/templates/specs/api.MANIFEST.md +33 -0
  28. package/dist/init/templates/specs/base.MANIFEST.md +120 -0
  29. package/dist/init/templates/specs/capability.MANIFEST.md +45 -0
  30. package/dist/init/templates/specs/integration.MANIFEST.md +25 -0
  31. package/dist/init/templates/specs/model.MANIFEST.md +21 -0
  32. package/dist/init/templates/specs/project.MANIFEST.md +39 -0
  33. package/dist/init/templates/specs/runtime-agent.MANIFEST.md +49 -0
  34. package/dist/init/templates/specs/runtime-image.MANIFEST.md +21 -0
  35. package/dist/init/templates/specs/tool.MANIFEST.md +25 -0
  36. package/dist/util/argparse.js +3 -0
  37. package/package.json +17 -3
@@ -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;
@@ -29,8 +29,8 @@ Agent operating prompt:
29
29
  - Treat goal `required_checks` as report-only guidance from mdkg. Run commands yourself, then record evidence in the goal or active work item.
30
30
  - Record skill improvement candidates during normal goal execution; edit `SKILL.md` only when the active node is explicit skill-maintenance work.
31
31
  - 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.
32
+ - Use `mdkg capability list/search/show` for deterministic skills, `MANIFEST.md` / legacy `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
33
+ - Use `mdkg manifest list/show/validate` for focused optional `MANIFEST.md` capability records; `mdkg spec ...` remains a legacy alias for one compatibility release.
34
34
  - Use `mdkg index` to refresh JSON compatibility caches and `.mdkg/index/mdkg.sqlite` when SQLite mode is enabled.
35
35
  - Treat `.mdkg/db` as project application state; use `mdkg db init` to create
36
36
  the generic scaffold and enable `db.enabled` without creating an active
@@ -111,9 +111,9 @@ Capability discovery:
111
111
  - `mdkg capability list --kind skill --json`
112
112
  - `mdkg capability search "<query>" --kind spec --json`
113
113
  - `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`
114
+ - `mdkg manifest list --json`
115
+ - `mdkg manifest show <id-or-qid-or-alias> --json`
116
+ - `mdkg manifest validate <id-or-qid-or-alias> --json`
117
117
 
118
118
  Conventions:
119
119
  - `AGENTS.md` is the Codex/OpenAI-oriented wrapper doc.
@@ -6,8 +6,9 @@ Verify live help with:
6
6
  - `mdkg --help`
7
7
  - `mdkg help <command>`
8
8
 
9
- Optional reusable SPEC capability records are accessed through `mdkg spec ...`.
10
- Repos without SPEC files remain valid.
9
+ Optional reusable manifest capability records are accessed through `mdkg manifest ...`.
10
+ Repos without MANIFEST/SPEC files remain valid. `mdkg spec ...` remains a
11
+ legacy alias for one compatibility release.
11
12
 
12
13
  Primary commands:
13
14
  - `mdkg init`
@@ -20,6 +21,7 @@ Primary commands:
20
21
  - `mdkg handoff create <id-or-qid> [--ws <alias>] [--depth <n>] [--out <path>] [--json]`
21
22
  - `mdkg skill`
22
23
  - `mdkg capability`
24
+ - `mdkg manifest`
23
25
  - `mdkg spec`
24
26
  - `mdkg archive`
25
27
  - `mdkg bundle`
@@ -118,9 +120,11 @@ Project database commands:
118
120
  - active `.mdkg/db/runtime/` files and `.mdkg/db` WAL/SHM/journal/lock/temp files are ignored by default
119
121
 
120
122
  Validation commands:
121
- - `mdkg validate [--out <path>] [--quiet] [--changed-only] [--json]`
123
+ - `mdkg validate [--out <path>] [--json-out <path>] [--quiet] [--changed-only] [--summary] [--limit <n>] [--json]`
122
124
  - `--changed-only` filters warning presentation to changed `.mdkg` files while full graph errors still run
123
- - JSON receipts include `warning_diagnostics` with warning ids, categories, severity, paths, refs, and remediation text
125
+ - `--summary` emits bounded warning samples for agent/CI logs; `--limit <n>` controls the sample size
126
+ - `--out <path>` writes the compatibility text report; `--json-out <path>` writes a clean full JSON receipt
127
+ - JSON receipts include `warning_summary` and `warning_diagnostics` with warning ids, categories, severity, paths, refs, and remediation text
124
128
 
125
129
  Node creation commands:
126
130
  - `mdkg new <type> "<title>" [options] [--json]`
@@ -128,19 +132,21 @@ Node creation commands:
128
132
  - `mdkg new spike "<research question>" [options] [--json]`
129
133
 
130
134
  Agent workflow file type creation:
131
- - `mdkg new spec "<title>" [options] [--json]`
135
+ - `mdkg new manifest "<title>" [options] [--json]`
132
136
  - `mdkg new work "<title>" [options] [--json]`
133
137
  - `mdkg new work_order "<title>" [options] [--json]`
134
138
  - `mdkg new receipt "<title>" [options] [--json]`
135
139
  - `mdkg new feedback "<title>" [options] [--json]`
136
140
  - `mdkg new dispute "<title>" [options] [--json]`
137
141
  - `mdkg new proposal "<title>" [options] [--json]`
138
- - `mdkg new spec "image worker" --id agent.image-worker`
142
+ - `mdkg new spec "<title>" [options] [--json]` is a deprecated alias for
143
+ `mdkg new manifest` and creates `MANIFEST.md` with `type: manifest`
144
+ - `mdkg new manifest "image worker" --id agent.image-worker`
139
145
  - `mdkg new work "generate image" --id work.generate-image`
140
146
 
141
147
  Agent workflow notes:
142
148
  - `--id <portable-id>` is only for agent workflow file types.
143
- - `spec` and `work` scaffold as validation-clean standalone docs.
149
+ - `manifest` and `work` scaffold as validation-clean standalone docs.
144
150
  - `work_order`, `receipt`, `feedback`, `dispute`, and `proposal` need real refs before strict `mdkg validate` passes.
145
151
  - `goal` nodes capture recursive objective state and required checks, but normal `mdkg next` does not select them.
146
152
  - `spike` nodes are actionable research/planning work under `.mdkg/work/`; use `mdkg task start|update|done` for lifecycle state.
@@ -195,18 +201,25 @@ Capability discovery:
195
201
  - `mdkg capability resolve [query] [--requires <capability>] [--fresh-only] [--json]`
196
202
  - capability records are deterministic cache projections from Markdown
197
203
  - records include source hash, headings, refs, and `indexed_at`
198
- - SPEC and WORK capability records include read-only `linkage` arrays for related SPECs, work contracts, work orders, and receipts when those graph mirrors exist
204
+ - MANIFEST/SPEC and WORK capability records include read-only `linkage` arrays for related manifests, work contracts, work orders, and receipts when those graph mirrors exist
199
205
  - normal task, epic, feat, bug, test, spike, and checkpoint nodes are intentionally excluded
200
206
 
201
- Spec capability records:
207
+ Manifest capability records:
208
+ - `mdkg manifest list [--json]`
209
+ - `mdkg manifest show <id-or-qid-or-alias> [--json]`
210
+ - `mdkg manifest validate [<id-or-qid-or-alias>] [--json]`
211
+ - `MANIFEST.md` is optional; repos with no manifest files still validate
212
+ - manifest records describe reusable capability surfaces, not general planning notes
213
+ - `mdkg manifest validate` with no ref validates the graph and all optional manifest records
214
+ - `mdkg manifest validate <ref>` also checks that the target manifest reference exists
215
+ - `mdkg manifest ...` is the focused manifest command family; `mdkg capability ...` remains broader skill/manifest/work/core/design discovery
216
+
217
+ Legacy spec capability records:
202
218
  - `mdkg spec list [--json]`
203
219
  - `mdkg spec show <id-or-qid-or-alias> [--json]`
204
220
  - `mdkg spec validate [<id-or-qid-or-alias>] [--json]`
205
- - `SPEC.md` is optional; repos with no SPEC files still validate
206
- - SPEC records describe reusable capability surfaces, not general planning notes
207
- - `mdkg spec validate` with no ref validates the graph and all optional SPEC records
208
- - `mdkg spec validate <ref>` also checks that the target SPEC reference exists
209
- - `mdkg spec ...` is the focused SPEC command family; `mdkg capability ...` remains broader skill/spec/work/core/design discovery
221
+ - `mdkg spec ...` is a deprecated alias for `mdkg manifest ...` during the compatibility bridge
222
+ - legacy `SPEC.md` files remain valid for one compatibility release
210
223
 
211
224
  Archive sidecars:
212
225
  - `mdkg archive add <file> [--id <archive.id>] [--kind source|artifact] [--visibility private|internal|public] [--title <title>] [--refs <...>] [--relates <...>] [--json]`
@@ -281,8 +294,8 @@ Work semantic mirrors:
281
294
  - `mdkg work receipt verify <id-or-qid> [--json]`
282
295
  - `mdkg work receipt update <id-or-qid> [--receipt-status <status>] [--add-artifacts <...>] [--add-proof-refs <...>] [--add-attestation-refs <...>] [--json]`
283
296
  - `mdkg work artifact add <order-or-receipt-id-or-qid> <file> [--id <archive.id>] [--kind source|artifact] [--json]`
284
- - `mdkg work validate [<id-or-qid>] [--type spec|work|work_order|receipt|feedback|dispute|proposal] [--json]`
285
- - `work trigger` accepts a `WORK.md` ref directly or a `SPEC.md` capability ref with exactly one resolvable work contract; it creates a submitted order mirror and never executes work
297
+ - `mdkg work validate [<id-or-qid>] [--type manifest|spec|work|work_order|receipt|feedback|dispute|proposal] [--json]`
298
+ - `work trigger` accepts a `WORK.md` ref directly or a `MANIFEST.md` / legacy `SPEC.md` capability ref with exactly one resolvable work contract; it creates a submitted order mirror and never executes work
286
299
  - example: `mdkg work trigger work.example --id order.example-1 --requester user://example --json`
287
300
  - `work trigger --enqueue <queue>` requires a valid project DB plus an explicitly created active queue, creates a submitted order mirror, and enqueues a local delivery message without executing work
288
301
  - `work order status` is read-only and reports deterministic order state plus linked receipts
@@ -27,7 +27,7 @@ mdkg show <id>
27
27
  mdkg pack <id>
28
28
  mdkg handoff create <id-or-qid> --json
29
29
  mdkg capability search "..."
30
- mdkg spec list --json
30
+ mdkg manifest list --json
31
31
  mdkg archive list
32
32
  mdkg bundle create --profile private
33
33
  mdkg graph clone .mdkg/bundles/private/all.mdkg.zip --target demos/demo-1 --json
@@ -37,14 +37,14 @@ mdkg fix plan --json
37
37
  mdkg validate
38
38
  ```
39
39
 
40
- This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg index` to create or refresh generated graph/skill/capability/subgraph and SQLite caches after init, `mdkg new` to create work, `mdkg new goal "..."` plus `mdkg goal activate/current/next/claim/evaluate` for recursive long-running objectives, `mdkg search`/`mdkg show` to inspect graph state, `mdkg capability ...` to inspect cached skill/spec/work/core/design capabilities, `mdkg spec ...` for focused optional SPEC records, `mdkg capability resolve ...` to rank local and subgraph capabilities, `mdkg archive ...` to register source/artifact sidecars, `mdkg work ...` to create work contract/order/receipt semantic mirrors and deterministic trigger/verification records, `mdkg bundle ...` to create full graph snapshot bundles, `mdkg graph ...` to clone/fork/import authored graph templates, `mdkg subgraph ...` to register read-only child graph planning views, `mdkg pack <id>` to build deterministic context, `mdkg handoff create <id-or-qid> --json` to create a sanitized copy-ready agent handoff prompt, and `mdkg validate` before closeout.
40
+ This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg index` to create or refresh generated graph/skill/capability/subgraph and SQLite caches after init, `mdkg new` to create work, `mdkg new goal "..."` plus `mdkg goal activate/current/next/claim/evaluate` for recursive long-running objectives, `mdkg search`/`mdkg show` to inspect graph state, `mdkg capability ...` to inspect cached skill/manifest/spec/work/core/design capabilities, `mdkg manifest ...` for focused optional manifest records, `mdkg capability resolve ...` to rank local and subgraph capabilities, `mdkg archive ...` to register source/artifact sidecars, `mdkg work ...` to create work contract/order/receipt semantic mirrors and deterministic trigger/verification records, `mdkg bundle ...` to create full graph snapshot bundles, `mdkg graph ...` to clone/fork/import authored graph templates, `mdkg subgraph ...` to register read-only child graph planning views, `mdkg pack <id>` to build deterministic context, `mdkg handoff create <id-or-qid> --json` to create a sanitized copy-ready agent handoff prompt, and `mdkg validate` before closeout.
41
41
 
42
42
  `mdkg handoff create` summarizes goal/work state, included pack nodes, latest
43
43
  checkpoint, boundaries, required checks, next actions, and raw-content marker
44
44
  warnings without copying raw node bodies into the prompt. Use `--out` to write
45
45
  the handoff artifact inside the repo root.
46
46
 
47
- For large historical graphs, `mdkg validate --changed-only --json` keeps warning review focused on changed `.mdkg` files while full graph errors still run. `mdkg format --headings --dry-run --json` previews missing recommended heading additions before `--apply`.
47
+ For large historical graphs, `mdkg validate --changed-only --json` keeps warning review focused on changed `.mdkg` files while full graph errors still run. `mdkg validate --summary --json --limit 20` keeps agent and CI logs bounded, and `--json-out <path>` writes a clean full JSON receipt artifact. `mdkg format --headings --dry-run --summary --json --limit 20` previews missing recommended heading additions with bounded output before `--apply`.
48
48
 
49
49
  Use `mdkg status --json` for a read-only operator summary of Git, graph,
50
50
  selected-goal, project DB, and generated-cache health before mutating work. Use
@@ -80,15 +80,17 @@ intentionally with `mdkg new task ...` or `mdkg new test ...`.
80
80
  Agent workflow docs can use semantic ids:
81
81
 
82
82
  ```bash
83
- mdkg new spec "image worker" --id agent.image-worker
83
+ mdkg new manifest "image worker" --id agent.image-worker
84
84
  mdkg new work "generate image" --id work.generate-image
85
85
  ```
86
86
 
87
- `SPEC.md` is optional. Repos without SPEC files still validate. When present,
88
- SPEC records describe reusable capability surfaces rather than general planning
89
- notes. `mdkg spec list/show/validate` is the focused SPEC command family, while
90
- `mdkg capability ...` remains the broader read-only discovery surface for
91
- skills, SPECs, WORK contracts, core docs, and design docs.
87
+ `MANIFEST.md` is optional. Repos without manifest files still validate. When
88
+ present, manifest records describe reusable capability surfaces rather than
89
+ general planning notes. `SPEC.md` remains a legacy alias for one compatibility
90
+ release, and `mdkg spec list/show/validate` remains a deprecated alias for
91
+ `mdkg manifest list/show/validate`. `mdkg capability ...` remains the broader
92
+ read-only discovery surface for skills, manifests, WORK contracts, core docs,
93
+ and design docs.
92
94
 
93
95
  Read `AGENT_START.md` first when this repo includes it.
94
96