mdkg 0.2.0 → 0.3.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.
@@ -32,6 +32,7 @@ exports.AGENT_FILE_BASENAMES = {
32
32
  exports.AGENT_ATTRIBUTE_KEY_ORDER = {
33
33
  spec: [
34
34
  "version",
35
+ "spec_kind",
35
36
  "role",
36
37
  "runtime_mode",
37
38
  "work_contracts",
@@ -68,7 +69,10 @@ exports.AGENT_ATTRIBUTE_KEY_ORDER = {
68
69
  "requester",
69
70
  "order_status",
70
71
  "request_ref",
72
+ "trigger_ref",
73
+ "payload_hash",
71
74
  "input_refs",
75
+ "queue_refs",
72
76
  "requested_outputs",
73
77
  "constraint_refs",
74
78
  "artifact_policy",
@@ -79,8 +83,10 @@ exports.AGENT_ATTRIBUTE_KEY_ORDER = {
79
83
  "receipt_status",
80
84
  "outcome",
81
85
  "cost_ref",
86
+ "redaction_policy",
82
87
  "proof_refs",
83
88
  "attestation_refs",
89
+ "evidence_hashes",
84
90
  "input_hashes",
85
91
  "output_hashes",
86
92
  ],
@@ -128,6 +134,27 @@ const UPDATE_POLICY_VALUES = new Set([
128
134
  "automatic",
129
135
  "disabled",
130
136
  ]);
137
+ const SPEC_KIND_VALUES = new Set([
138
+ "cli_tool",
139
+ "api",
140
+ "agent",
141
+ "runtime_agent",
142
+ "capability",
143
+ "tool",
144
+ "model",
145
+ "runtime_image",
146
+ "integration",
147
+ "project_service",
148
+ ]);
149
+ const DOCUMENTATION_ONLY_SPEC_KIND_ROUTES = {
150
+ gap_register: "use an EDD, task, checkpoint, or goal for gap registers",
151
+ checkpoint: "use a checkpoint node for checkpoint evidence",
152
+ roadmap: "use an epic, goal, EDD, or PRD for roadmaps",
153
+ audit: "use a task, checkpoint, or EDD for audits",
154
+ go_no_go: "use a DEC, task, or checkpoint for go/no-go notes",
155
+ planning_note: "use an EDD, task, or checkpoint for planning notes",
156
+ launch_checklist: "use a task, test, checkpoint, or DEC for launch checklists",
157
+ };
131
158
  const PRICING_MODEL_VALUES = new Set([
132
159
  "free",
133
160
  "included",
@@ -146,6 +173,11 @@ const ORDER_STATUS_VALUES = new Set([
146
173
  ]);
147
174
  const RECEIPT_STATUS_VALUES = new Set(["recorded", "verified", "rejected", "superseded"]);
148
175
  const OUTCOME_VALUES = new Set(["success", "partial", "failure"]);
176
+ const REDACTION_POLICY_VALUES = new Set([
177
+ "refs_and_hashes_only",
178
+ "redacted_summary",
179
+ "external_private",
180
+ ]);
149
181
  const ARTIFACT_POLICY_VALUES = new Set([
150
182
  "commit_sidecar_and_zip",
151
183
  "external_only",
@@ -265,6 +297,16 @@ function requireEnum(value, key, allowed, filePath) {
265
297
  throw formatError(filePath, `${key} must be one of ${Array.from(allowed).join(", ")}`);
266
298
  }
267
299
  }
300
+ function validateSpecKind(value, filePath) {
301
+ if (SPEC_KIND_VALUES.has(value)) {
302
+ return;
303
+ }
304
+ const route = DOCUMENTATION_ONLY_SPEC_KIND_ROUTES[value];
305
+ if (route) {
306
+ throw formatError(filePath, `spec_kind ${value} is documentation-only; ${route}. SPEC.md must define a reusable invocable capability surface.`);
307
+ }
308
+ 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
+ }
268
310
  function requireLowerToken(value, key, filePath) {
269
311
  if (!LOWER_TOKEN_RE.test(value)) {
270
312
  throw formatError(filePath, `${key} must be lowercase snake/kebab style`);
@@ -290,6 +332,14 @@ function validatePortableRefs(values, key, filePath) {
290
332
  }
291
333
  }
292
334
  }
335
+ function validateWorkInvocationAnchor(requiredCapabilities, refsByKey, filePath) {
336
+ const hasRequiredCapability = requiredCapabilities.length > 0;
337
+ const hasDependencyRef = Object.values(refsByKey).some((values) => values.length > 0);
338
+ if (hasRequiredCapability || hasDependencyRef) {
339
+ return;
340
+ }
341
+ throw formatError(filePath, "WORK.md must include at least one required_capabilities entry or dependency ref in skill_refs, tool_refs, model_refs, wasm_component_refs, runtime_image_refs, or subagent_refs");
342
+ }
293
343
  function validatePortableOrUriRefs(values, key, filePath) {
294
344
  for (const [index, value] of values.entries()) {
295
345
  if (!(0, refs_1.validatePortableOrUriRef)(value)) {
@@ -315,6 +365,11 @@ function validateHashRefs(values, key, filePath) {
315
365
  }
316
366
  }
317
367
  }
368
+ function validateHashRef(value, key, filePath) {
369
+ if (!(0, refs_1.isSha256Ref)(value)) {
370
+ throw formatError(filePath, `${key} must be sha256:<64 lowercase hex chars>`);
371
+ }
372
+ }
318
373
  function validateRelativeMarkdownPaths(values, key, basename, filePath) {
319
374
  for (const [index, value] of values.entries()) {
320
375
  if (path_1.default.isAbsolute(value) || value.split(/[\\/]/).includes("..")) {
@@ -344,6 +399,10 @@ function validateAgentFrontmatter(type, frontmatter, filePath) {
344
399
  requireSemver(version, "version", filePath);
345
400
  switch (type) {
346
401
  case "spec": {
402
+ const specKind = optionalString(frontmatter, "spec_kind", filePath);
403
+ if (specKind) {
404
+ validateSpecKind(specKind, filePath);
405
+ }
347
406
  const role = expectString(frontmatter, "role", filePath);
348
407
  requireEnum(role, "role", ROLE_VALUES, filePath);
349
408
  const runtimeMode = expectString(frontmatter, "runtime_mode", filePath);
@@ -371,13 +430,28 @@ function validateAgentFrontmatter(type, frontmatter, filePath) {
371
430
  requireLowerToken(kind, "kind", filePath);
372
431
  const pricingModel = expectString(frontmatter, "pricing_model", filePath);
373
432
  requireEnum(pricingModel, "pricing_model", PRICING_MODEL_VALUES, filePath);
374
- validateCapabilities(expectList(frontmatter, "required_capabilities", filePath), "required_capabilities", filePath);
375
- validatePortableRefs(optionalList(frontmatter, "skill_refs", filePath), "skill_refs", filePath);
376
- validatePortableRefs(optionalList(frontmatter, "tool_refs", filePath), "tool_refs", filePath);
377
- validatePortableRefs(optionalList(frontmatter, "model_refs", filePath), "model_refs", filePath);
378
- validatePortableRefs(optionalList(frontmatter, "wasm_component_refs", filePath), "wasm_component_refs", filePath);
379
- validatePortableRefs(optionalList(frontmatter, "runtime_image_refs", filePath), "runtime_image_refs", filePath);
380
- validatePortableRefs(optionalList(frontmatter, "subagent_refs", filePath), "subagent_refs", filePath);
433
+ const requiredCapabilities = expectList(frontmatter, "required_capabilities", filePath);
434
+ validateCapabilities(requiredCapabilities, "required_capabilities", filePath);
435
+ const skillRefs = optionalList(frontmatter, "skill_refs", filePath);
436
+ validatePortableRefs(skillRefs, "skill_refs", filePath);
437
+ const toolRefs = optionalList(frontmatter, "tool_refs", filePath);
438
+ validatePortableRefs(toolRefs, "tool_refs", filePath);
439
+ const modelRefs = optionalList(frontmatter, "model_refs", filePath);
440
+ validatePortableRefs(modelRefs, "model_refs", filePath);
441
+ const wasmComponentRefs = optionalList(frontmatter, "wasm_component_refs", filePath);
442
+ validatePortableRefs(wasmComponentRefs, "wasm_component_refs", filePath);
443
+ const runtimeImageRefs = optionalList(frontmatter, "runtime_image_refs", filePath);
444
+ validatePortableRefs(runtimeImageRefs, "runtime_image_refs", filePath);
445
+ const subagentRefs = optionalList(frontmatter, "subagent_refs", filePath);
446
+ validatePortableRefs(subagentRefs, "subagent_refs", filePath);
447
+ validateWorkInvocationAnchor(requiredCapabilities, {
448
+ skill_refs: skillRefs,
449
+ tool_refs: toolRefs,
450
+ model_refs: modelRefs,
451
+ wasm_component_refs: wasmComponentRefs,
452
+ runtime_image_refs: runtimeImageRefs,
453
+ subagent_refs: subagentRefs,
454
+ }, filePath);
381
455
  validateFieldDescriptors(expectList(frontmatter, "inputs", filePath), "inputs", filePath);
382
456
  validateFieldDescriptors(expectList(frontmatter, "outputs", filePath), "outputs", filePath);
383
457
  expectBoolean(frontmatter, "receipt_required", filePath);
@@ -396,7 +470,16 @@ function validateAgentFrontmatter(type, frontmatter, filePath) {
396
470
  if (requestRef) {
397
471
  validatePortableOrUriScalar(requestRef, "request_ref", filePath);
398
472
  }
473
+ const triggerRef = optionalRefString(frontmatter, "trigger_ref", filePath);
474
+ if (triggerRef) {
475
+ validatePortableOrUriScalar(triggerRef, "trigger_ref", filePath);
476
+ }
477
+ const payloadHash = optionalString(frontmatter, "payload_hash", filePath);
478
+ if (payloadHash) {
479
+ validateHashRef(payloadHash, "payload_hash", filePath);
480
+ }
399
481
  validatePortableOrUriRefs(optionalList(frontmatter, "input_refs", filePath), "input_refs", filePath);
482
+ validatePortableOrUriRefs(optionalList(frontmatter, "queue_refs", filePath), "queue_refs", filePath);
400
483
  validateOptionalFieldDescriptors(optionalList(frontmatter, "requested_outputs", filePath), "requested_outputs", filePath);
401
484
  validatePortableOrUriRefs(optionalList(frontmatter, "constraint_refs", filePath), "constraint_refs", filePath);
402
485
  const artifactPolicy = optionalString(frontmatter, "artifact_policy", filePath);
@@ -416,8 +499,13 @@ function validateAgentFrontmatter(type, frontmatter, filePath) {
416
499
  if (costRef) {
417
500
  validatePortableOrUriScalar(costRef, "cost_ref", filePath);
418
501
  }
502
+ const redactionPolicy = optionalString(frontmatter, "redaction_policy", filePath);
503
+ if (redactionPolicy) {
504
+ requireEnum(redactionPolicy, "redaction_policy", REDACTION_POLICY_VALUES, filePath);
505
+ }
419
506
  validatePortableOrUriRefs(optionalList(frontmatter, "proof_refs", filePath), "proof_refs", filePath);
420
507
  validatePortableOrUriRefs(optionalList(frontmatter, "attestation_refs", filePath), "attestation_refs", filePath);
508
+ validateHashRefs(optionalList(frontmatter, "evidence_hashes", filePath), "evidence_hashes", filePath);
421
509
  validateHashRefs(optionalList(frontmatter, "input_hashes", filePath), "input_hashes", filePath);
422
510
  validateHashRefs(optionalList(frontmatter, "output_hashes", filePath), "output_hashes", filePath);
423
511
  break;
@@ -74,7 +74,92 @@ function pickAttributes(attributes, keys) {
74
74
  }
75
75
  return picked;
76
76
  }
77
- function nodeCapabilityRecord(root, config, node, kind, indexedAt) {
77
+ function toStringList(value) {
78
+ if (!Array.isArray(value)) {
79
+ return [];
80
+ }
81
+ return value.filter((item) => typeof item === "string");
82
+ }
83
+ function nodeRefSet(node) {
84
+ return new Set([node.id, node.qid, `${node.ws}:${node.id}`]);
85
+ }
86
+ function sortedNodes(nodes) {
87
+ return [...nodes].sort((a, b) => a.qid.localeCompare(b.qid));
88
+ }
89
+ function resolveSpecWorkContracts(index, specNode) {
90
+ const candidates = new Map();
91
+ const specDir = path_1.default.posix.dirname(specNode.path);
92
+ for (const contractPath of toStringList(specNode.attributes.work_contracts)) {
93
+ const normalizedPath = path_1.default.posix.normalize(path_1.default.posix.join(specDir, contractPath));
94
+ for (const node of Object.values(index.nodes)) {
95
+ if (node.type === "work" && node.ws === specNode.ws && node.path === normalizedPath) {
96
+ candidates.set(node.qid, node);
97
+ }
98
+ }
99
+ }
100
+ for (const qid of specNode.edges.relates) {
101
+ const node = index.nodes[qid];
102
+ if (node?.type === "work") {
103
+ candidates.set(node.qid, node);
104
+ }
105
+ }
106
+ for (const qid of index.reverse_edges.relates?.[specNode.qid] ?? []) {
107
+ const node = index.nodes[qid];
108
+ if (node?.type === "work") {
109
+ candidates.set(node.qid, node);
110
+ }
111
+ }
112
+ return sortedNodes(candidates.values());
113
+ }
114
+ function resolveWorkSpecs(index, workNode) {
115
+ const candidates = new Map();
116
+ const workRefs = nodeRefSet(workNode);
117
+ for (const node of Object.values(index.nodes)) {
118
+ if (node.type !== "spec" || node.ws !== workNode.ws) {
119
+ continue;
120
+ }
121
+ const agentId = typeof workNode.attributes.agent_id === "string" ? workNode.attributes.agent_id : undefined;
122
+ if (agentId && nodeRefSet(node).has(agentId)) {
123
+ candidates.set(node.qid, node);
124
+ }
125
+ if (resolveSpecWorkContracts(index, node).some((contract) => contract.qid === workNode.qid)) {
126
+ candidates.set(node.qid, node);
127
+ }
128
+ if (node.edges.relates.some((qid) => workRefs.has(qid))) {
129
+ candidates.set(node.qid, node);
130
+ }
131
+ }
132
+ return sortedNodes(candidates.values());
133
+ }
134
+ function resolveWorkOrders(index, workNode) {
135
+ const workRefs = nodeRefSet(workNode);
136
+ return sortedNodes(Object.values(index.nodes).filter((node) => node.type === "work_order" && workRefs.has(String(node.attributes.work_id ?? ""))));
137
+ }
138
+ function resolveReceiptsForOrders(index, orderNodes) {
139
+ const orderRefs = new Set();
140
+ for (const order of orderNodes) {
141
+ for (const ref of nodeRefSet(order)) {
142
+ orderRefs.add(ref);
143
+ }
144
+ }
145
+ return sortedNodes(Object.values(index.nodes).filter((node) => node.type === "receipt" && orderRefs.has(String(node.attributes.work_order_id ?? ""))));
146
+ }
147
+ function buildCapabilityLinkage(index, node, kind) {
148
+ if (kind !== "spec" && kind !== "work") {
149
+ return undefined;
150
+ }
151
+ const workContracts = kind === "spec" ? resolveSpecWorkContracts(index, node) : [node];
152
+ const specNodes = kind === "work" ? resolveWorkSpecs(index, node) : [];
153
+ const workOrders = workContracts.flatMap((workNode) => resolveWorkOrders(index, workNode));
154
+ const receipts = resolveReceiptsForOrders(index, workOrders);
155
+ return {
156
+ spec_qids: specNodes.map((specNode) => specNode.qid),
157
+ work_contract_qids: workContracts.map((workNode) => workNode.qid),
158
+ work_order_qids: workOrders.map((orderNode) => orderNode.qid),
159
+ receipt_qids: receipts.map((receiptNode) => receiptNode.qid),
160
+ };
161
+ }
162
+ function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
78
163
  const absolutePath = path_1.default.resolve(root, node.path);
79
164
  const content = fs_1.default.readFileSync(absolutePath, "utf8");
80
165
  const record = {
@@ -99,6 +184,7 @@ function nodeCapabilityRecord(root, config, node, kind, indexedAt) {
99
184
  if (kind === "spec") {
100
185
  record.spec = pickAttributes(node.attributes, [
101
186
  "version",
187
+ "spec_kind",
102
188
  "role",
103
189
  "runtime_mode",
104
190
  "work_contracts",
@@ -131,6 +217,7 @@ function nodeCapabilityRecord(root, config, node, kind, indexedAt) {
131
217
  "receipt_required",
132
218
  ]);
133
219
  }
220
+ record.linkage = buildCapabilityLinkage(index, node, kind);
134
221
  return record;
135
222
  }
136
223
  function skillCapabilityRecord(root, config, skill, indexedAt) {
@@ -210,7 +297,7 @@ function buildCapabilitiesIndex(root, config, nodeIndex) {
210
297
  if (!kind) {
211
298
  continue;
212
299
  }
213
- records.push(nodeCapabilityRecord(root, config, node, kind, generatedAt));
300
+ records.push(nodeCapabilityRecord(root, config, index, node, kind, generatedAt));
214
301
  }
215
302
  records.push(...buildWorkspaceSkillCapabilities(root, config, generatedAt));
216
303
  const sortedRecords = sortRecords(records);
@@ -24,6 +24,7 @@ exports.DEFAULT_FRONTMATTER_KEY_ORDER = [
24
24
  "next",
25
25
  "supersedes",
26
26
  "version",
27
+ "spec_kind",
27
28
  "role",
28
29
  "runtime_mode",
29
30
  "work_contracts",
@@ -42,10 +43,14 @@ exports.DEFAULT_FRONTMATTER_KEY_ORDER = [
42
43
  "requester",
43
44
  "order_status",
44
45
  "request_ref",
46
+ "trigger_ref",
47
+ "payload_hash",
48
+ "queue_refs",
45
49
  "work_order_id",
46
50
  "receipt_status",
47
51
  "outcome",
48
52
  "cost_ref",
53
+ "redaction_policy",
49
54
  "target_id",
50
55
  "sentiment",
51
56
  "feedback_status",
@@ -73,6 +78,7 @@ exports.DEFAULT_FRONTMATTER_KEY_ORDER = [
73
78
  "artifact_policy",
74
79
  "proof_refs",
75
80
  "attestation_refs",
81
+ "evidence_hashes",
76
82
  "input_hashes",
77
83
  "output_hashes",
78
84
  "tags",
@@ -226,14 +226,20 @@ function requireTemplateSchema(type, templateSchemas, filePath) {
226
226
  }
227
227
  return schema;
228
228
  }
229
+ const OPTIONAL_COMPAT_TEMPLATE_KEYS = {
230
+ spec: {
231
+ spec_kind: "scalar",
232
+ },
233
+ };
229
234
  function validateTemplateKeys(frontmatter, schema, filePath) {
230
235
  for (const key of Object.keys(frontmatter)) {
231
- if (!schema.allowedKeys.has(key)) {
236
+ if (!schema.allowedKeys.has(key) &&
237
+ OPTIONAL_COMPAT_TEMPLATE_KEYS[schema.type]?.[key] === undefined) {
232
238
  throw formatError(filePath, `unknown key: ${key}`);
233
239
  }
234
240
  }
235
241
  for (const [key, value] of Object.entries(frontmatter)) {
236
- const expected = schema.keyKinds[key];
242
+ const expected = schema.keyKinds[key] ?? OPTIONAL_COMPAT_TEMPLATE_KEYS[schema.type]?.[key];
237
243
  if (!expected) {
238
244
  continue;
239
245
  }
@@ -30,6 +30,7 @@ Agent operating prompt:
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
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
34
  - Use `mdkg index` to refresh JSON compatibility caches and `.mdkg/index/mdkg.sqlite` when SQLite mode is enabled.
34
35
  - Treat `.mdkg/db` as project application state; use `mdkg db init` to create
35
36
  the generic scaffold and enable `db.enabled` without creating an active
@@ -50,7 +51,7 @@ Agent operating prompt:
50
51
  `.mdkg/db/runtime/` and WAL/SHM/journal/lock/temp files ignored unless a
51
52
  sealed artifact policy explicitly says otherwise.
52
53
  - Use `mdkg archive add/list/show/verify/compress` for committed source and artifact sidecars under `.mdkg/archive`.
53
- - Use `mdkg work ...` helpers for semantic mirror contracts, work orders, receipts, and artifact registration.
54
+ - Use `mdkg work ...` helpers for semantic mirror contracts, deterministic triggers, work order status, receipt verification, and artifact registration.
54
55
  - Treat work contracts, orders, and receipts as committed semantic mirrors only; never store raw secrets, credentials, live payment state, ledger mutations, or canonical marketplace state in mdkg.
55
56
  - Use `artifact://...` for external/runtime-managed artifacts and `archive://...` for committed mdkg archive sidecars.
56
57
  - Use `mdkg bundle create/list/show/verify` for explicit full `.mdkg` graph snapshot bundles.
@@ -107,6 +108,9 @@ Capability discovery:
107
108
  - `mdkg capability list --kind skill --json`
108
109
  - `mdkg capability search "<query>" --kind spec --json`
109
110
  - `mdkg capability search "<query>" --kind work --json`
111
+ - `mdkg spec list --json`
112
+ - `mdkg spec show <id-or-qid-or-alias> --json`
113
+ - `mdkg spec validate <id-or-qid-or-alias> --json`
110
114
 
111
115
  Conventions:
112
116
  - `AGENTS.md` is the Codex/OpenAI-oriented wrapper doc.
@@ -6,6 +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.
11
+
9
12
  Primary commands:
10
13
  - `mdkg init`
11
14
  - `mdkg upgrade [--dry-run] [--apply] [--json]`
@@ -16,6 +19,7 @@ Primary commands:
16
19
  - `mdkg pack`
17
20
  - `mdkg skill`
18
21
  - `mdkg capability`
22
+ - `mdkg spec`
19
23
  - `mdkg archive`
20
24
  - `mdkg bundle`
21
25
  - `mdkg work`
@@ -143,8 +147,19 @@ Capability discovery:
143
147
  - `mdkg capability resolve [query] [--requires <capability>] [--fresh-only] [--json]`
144
148
  - capability records are deterministic cache projections from Markdown
145
149
  - records include source hash, headings, refs, and `indexed_at`
150
+ - SPEC and WORK capability records include read-only `linkage` arrays for related SPECs, work contracts, work orders, and receipts when those graph mirrors exist
146
151
  - normal task, epic, feat, bug, test, and checkpoint nodes are intentionally excluded
147
152
 
153
+ Spec capability records:
154
+ - `mdkg spec list [--json]`
155
+ - `mdkg spec show <id-or-qid-or-alias> [--json]`
156
+ - `mdkg spec validate [<id-or-qid-or-alias>] [--json]`
157
+ - `SPEC.md` is optional; repos with no SPEC files still validate
158
+ - SPEC records describe reusable capability surfaces, not general planning notes
159
+ - `mdkg spec validate` with no ref validates the graph and all optional SPEC records
160
+ - `mdkg spec validate <ref>` also checks that the target SPEC reference exists
161
+ - `mdkg spec ...` is the focused SPEC command family; `mdkg capability ...` remains broader skill/spec/work/core/design discovery
162
+
148
163
  Archive sidecars:
149
164
  - `mdkg archive add <file> [--id <archive.id>] [--kind source|artifact] [--visibility private|internal|public] [--title <title>] [--refs <...>] [--relates <...>] [--json]`
150
165
  - `mdkg archive list [--kind source|artifact] [--visibility private|internal|public] [--ws <alias>] [--json]`
@@ -188,11 +203,19 @@ Subgraph orchestration:
188
203
 
189
204
  Work semantic mirrors:
190
205
  - `mdkg work contract new "<title>" --id <work.id> --agent-id <agent.id> --kind <kind> --inputs <...> --outputs <...> [--required-capabilities <...>] [--pricing-model <...>] [--json]`
206
+ - `mdkg work trigger <work-or-capability-ref> [--id <order.id>] [--title "<title>"] [--requester <ref>] [--enqueue <queue>] [--json]`
191
207
  - `mdkg work order new "<title>" --id <order.id> --work-id <work.id> --requester <ref> [--request-ref <ref>] [--input-refs <...>] [--requested-outputs <...>] [--json]`
208
+ - `mdkg work order status <id-or-qid> [--json]`
192
209
  - `mdkg work order update <id-or-qid> [--status <status>] [--add-input-refs <...>] [--add-artifacts <...>] [--json]`
193
210
  - `mdkg work receipt new "<title>" --id <receipt.id> --work-order-id <order.id> --outcome success|partial|failure [--receipt-status recorded|verified|rejected|superseded] [--json]`
211
+ - `mdkg work receipt verify <id-or-qid> [--json]`
194
212
  - `mdkg work receipt update <id-or-qid> [--receipt-status <status>] [--add-artifacts <...>] [--add-proof-refs <...>] [--add-attestation-refs <...>] [--json]`
195
213
  - `mdkg work artifact add <order-or-receipt-id-or-qid> <file> [--id <archive.id>] [--kind source|artifact] [--json]`
214
+ - `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
215
+ - example: `mdkg work trigger work.example --id order.example-1 --requester user://example --json`
216
+ - `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
217
+ - `work order status` is read-only and reports deterministic order state plus linked receipts
218
+ - `work receipt verify` is read-only and reports linkage, evidence, archive ref, hash, outcome, and redaction-policy checks
196
219
  - work commands mutate mdkg semantic mirror files only; production order, receipt, feedback, dispute, payment, ledger, marketplace inventory, fulfillment, and execution state remains canonical outside mdkg
197
220
  - do not store raw secrets, credentials, live payment state, ledger mutations, or canonical marketplace state in work mirrors
198
221
  - `artifact://...` refs identify external/runtime-managed artifacts; `archive://...` refs identify committed mdkg archive sidecars
@@ -25,13 +25,14 @@ mdkg search "..."
25
25
  mdkg show <id>
26
26
  mdkg pack <id>
27
27
  mdkg capability search "..."
28
+ mdkg spec list --json
28
29
  mdkg archive list
29
30
  mdkg bundle create --profile private
30
31
  mdkg subgraph list --json
31
32
  mdkg validate
32
33
  ```
33
34
 
34
- This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg new` to create work, `mdkg new goal "..."` plus `mdkg goal select/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 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, `mdkg bundle ...` to create full graph snapshot bundles, `mdkg subgraph ...` to register read-only child graph planning views, `mdkg pack <id>` to build deterministic context, and `mdkg validate` before closeout.
35
+ This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg new` to create work, `mdkg new goal "..."` plus `mdkg goal select/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 subgraph ...` to register read-only child graph planning views, `mdkg pack <id>` to build deterministic context, and `mdkg validate` before closeout.
35
36
 
36
37
  Agent workflow docs can use semantic ids:
37
38
 
@@ -40,6 +41,12 @@ mdkg new spec "image worker" --id agent.image-worker
40
41
  mdkg new work "generate image" --id work.generate-image
41
42
  ```
42
43
 
44
+ `SPEC.md` is optional. Repos without SPEC files still validate. When present,
45
+ SPEC records describe reusable capability surfaces rather than general planning
46
+ notes. `mdkg spec list/show/validate` is the focused SPEC command family, while
47
+ `mdkg capability ...` remains the broader read-only discovery surface for
48
+ skills, SPECs, WORK contracts, core docs, and design docs.
49
+
43
50
  Read `AGENT_START.md` first when this repo includes it.
44
51
 
45
52
  ## Pack Profiles
@@ -146,13 +153,29 @@ Use work lifecycle helpers for semantic mirrors only:
146
153
 
147
154
  ```bash
148
155
  mdkg work contract new "example capability" --id work.example --agent-id agent.example --kind example --inputs prompt:text:required --outputs result:text:required
149
- mdkg work order new "example request" --id order.example-1 --work-id work.example --requester user://example
156
+ mdkg work trigger work.example --id order.example-1 --requester user://example
157
+ mdkg work order status order.example-1 --json
150
158
  mdkg work receipt new "example receipt" --id receipt.example-1 --work-order-id order.example-1 --outcome success
159
+ mdkg work receipt verify receipt.example-1 --json
160
+ ```
161
+
162
+ Create a manual order instead of a trigger-created order when you need to supply
163
+ input refs at order creation time:
164
+
165
+ ```bash
166
+ mdkg work order new "example request" --id order.example-manual --work-id work.example --requester user://example --input-refs archive://archive.example
151
167
  ```
152
168
 
153
169
  Receipt statuses are `recorded`, `verified`, `rejected`, and `superseded`.
154
170
  Update and artifact commands accept local ids or local qids; subgraph qids are read-only and must be changed in their source workspace.
155
171
 
172
+ `mdkg work trigger` creates a deterministic submitted `WORK_ORDER.md` from a
173
+ WORK contract or a SPEC with exactly one resolvable work contract. `mdkg work
174
+ order status` and `mdkg work receipt verify` are read-only review helpers.
175
+ `mdkg work trigger --enqueue <queue>` optionally writes a local project DB queue
176
+ delivery message after the queue has been explicitly created and is active; it
177
+ still does not execute work.
178
+
156
179
  Production orders, receipts, feedback, disputes, payments, ledgers, marketplace inventory, fulfillment records, and execution state remain canonical outside mdkg. mdkg stores committed semantic mirrors and reviewable evidence. Do not store raw secrets, credentials, live payment state, ledger mutations, canonical marketplace state, or bulky raw payloads in these mirrors.
157
180
 
158
181
  Use `artifact://...` for external or runtime-managed artifact identities. Use `archive://...` only for committed mdkg archive sidecars.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "tool": "mdkg",
4
- "mdkg_version": "0.2.0",
4
+ "mdkg_version": "0.3.0",
5
5
  "files": [
6
6
  {
7
7
  "path": ".mdkg/config.json",
@@ -61,7 +61,7 @@
61
61
  {
62
62
  "path": ".mdkg/README.md",
63
63
  "category": "mdkg_doc",
64
- "sha256": "14ba3fa0657a43345ae81631024519955868fa34081b7517cb253b0be96cf163"
64
+ "sha256": "353aa7318974d4b3dbdf772ae5a3deb2d41b5d71ea5308d260aab8081121548b"
65
65
  },
66
66
  {
67
67
  "path": ".mdkg/skills/build-pack-and-execute-task/SKILL.md",
@@ -151,7 +151,7 @@
151
151
  {
152
152
  "path": ".mdkg/templates/default/receipt.md",
153
153
  "category": "template",
154
- "sha256": "f08753cc38e02d73a5df92df58c2d34b0d33749b298eeb31d81aa019c38d43dd"
154
+ "sha256": "516faf98abe421f154d162b18006c7875f1a0025ac4d35cc16df744c13548d9d"
155
155
  },
156
156
  {
157
157
  "path": ".mdkg/templates/default/rule.md",
@@ -161,7 +161,7 @@
161
161
  {
162
162
  "path": ".mdkg/templates/default/spec.md",
163
163
  "category": "template",
164
- "sha256": "e3e05d8d627c478d2757451f61b5a8fda8a75da9885a9261b2f8f5cb8a3a36dc"
164
+ "sha256": "8c96e0b6dafa65acb83a2d84519e05a7354896aec8991c148650e9ec58196c77"
165
165
  },
166
166
  {
167
167
  "path": ".mdkg/templates/default/task.md",
@@ -176,12 +176,12 @@
176
176
  {
177
177
  "path": ".mdkg/templates/default/work_order.md",
178
178
  "category": "template",
179
- "sha256": "6ee6007674f30f88153ce79ed67d8c736b4f0998ceb0c8314a3f2cf9c48ac88c"
179
+ "sha256": "5fe376413035f2afe406d13491a597f103a2fce29d137951fe55ae042a1082f5"
180
180
  },
181
181
  {
182
182
  "path": ".mdkg/templates/default/work.md",
183
183
  "category": "template",
184
- "sha256": "9d8b971ded7a587105fb8b14bb79f68b612fa6e1962cf06859bab82e2aee57c7"
184
+ "sha256": "cfc53d3be1d2c31576448d071a579bc3d5d2f6851755e29c20825f6b6764c0aa"
185
185
  },
186
186
  {
187
187
  "path": ".mdkg/templates/skills/base.SKILL.md",
@@ -191,57 +191,57 @@
191
191
  {
192
192
  "path": ".mdkg/templates/specs/agent.SPEC.md",
193
193
  "category": "template",
194
- "sha256": "6facd5a424fa91d23f7df3e357c98ca4d31691410fad024d5bc8ff3781b0f571"
194
+ "sha256": "dab10c0ed12aa10a752ee3bd61f263065644826eb950c71a9e3458673edb0ca5"
195
195
  },
196
196
  {
197
197
  "path": ".mdkg/templates/specs/api.SPEC.md",
198
198
  "category": "template",
199
- "sha256": "42f6119478241a3c7dd12a2a25bd03b30d9c2bc60528287136ea044f20b215c4"
199
+ "sha256": "aee86cadcca31a5a015d7e15ad7503c4aa30f2af0079ec03f857b82b3ecbae59"
200
200
  },
201
201
  {
202
202
  "path": ".mdkg/templates/specs/base.SPEC.md",
203
203
  "category": "template",
204
- "sha256": "cff1ee53e9369184e2d92194f165f131254d4439bc79bcbbaaae4a13d616c97b"
204
+ "sha256": "6d4171fac00c2f3d8f2a2ac746b8a47c59aaecebe224c3a0046dd6e6974a1d08"
205
205
  },
206
206
  {
207
207
  "path": ".mdkg/templates/specs/capability.SPEC.md",
208
208
  "category": "template",
209
- "sha256": "755c24dea04f687da4714d0a12489e1ae36c5f17b838c2e24bb993378a7d9510"
209
+ "sha256": "68a91e8bbd80d1ff1972e4c31e29f26451d5a1be1d25d414170fdd670010066f"
210
210
  },
211
211
  {
212
212
  "path": ".mdkg/templates/specs/integration.SPEC.md",
213
213
  "category": "template",
214
- "sha256": "990005a805bc6e6397f03e0de1ca69d536ae9d55719782a3075781289b44b941"
214
+ "sha256": "e907ce6ebc1fa5a455e31e39036e3f8699dccb3d9e45288c8ea025eaec4ca4a2"
215
215
  },
216
216
  {
217
217
  "path": ".mdkg/templates/specs/model.SPEC.md",
218
218
  "category": "template",
219
- "sha256": "eb73ed195139cf5655ba70c948aaaa28fc2c85d2db1b6258d703f10e73bf3713"
219
+ "sha256": "56061a241819dfda4d3022c075f744cf6650f5f52c58cd15b0af9d1f613af4f2"
220
220
  },
221
221
  {
222
- "path": ".mdkg/templates/specs/omniruntime-agent.SPEC.md",
222
+ "path": ".mdkg/templates/specs/project.SPEC.md",
223
223
  "category": "template",
224
- "sha256": "343c7c148faae0c2b24364c276ce345757b5725a750cfebeee4cdeb3dde55009"
224
+ "sha256": "386c41852cbb46e7a6ba583a7b0c4126262a56618d8e214aaa601b68d55818b9"
225
225
  },
226
226
  {
227
- "path": ".mdkg/templates/specs/project.SPEC.md",
227
+ "path": ".mdkg/templates/specs/runtime-agent.SPEC.md",
228
228
  "category": "template",
229
- "sha256": "5ade0aa05907b9ec418c41ee051493d8ecc8ad3d45608ab74fc3cbe2974e79a4"
229
+ "sha256": "53af7c3e172f5ed1297f340aca0be5e53302613d2e6bb9145915067d7b0004c8"
230
230
  },
231
231
  {
232
232
  "path": ".mdkg/templates/specs/runtime-image.SPEC.md",
233
233
  "category": "template",
234
- "sha256": "24c1b2fb0bd0d63bbce41ee36b43f9edf531b26438bca2706ad1ab556eaabbf0"
234
+ "sha256": "37416b045cd7733d1f5e1cc629ac9b6616024d5fa52f2bdcd90110267151e593"
235
235
  },
236
236
  {
237
237
  "path": ".mdkg/templates/specs/tool.SPEC.md",
238
238
  "category": "template",
239
- "sha256": "18340481891bba180dd077d82b86248ede885131fb75675b775ea0c3749ee5c0"
239
+ "sha256": "05b827bbce4f721ea25beda62850688aff3db644aec65e71b9cf76cad8e5f46f"
240
240
  },
241
241
  {
242
242
  "path": "AGENT_START.md",
243
243
  "category": "startup_doc",
244
- "sha256": "5948ed5222b2cbce0468191d00287ce5dbc1aaa434640f4daa676afb92d48d4b"
244
+ "sha256": "cf58e37c72be2593f1d920520dbdc6e316182bfda5c49837443a8b18024504c7"
245
245
  },
246
246
  {
247
247
  "path": "AGENTS.md",
@@ -256,7 +256,7 @@
256
256
  {
257
257
  "path": "CLI_COMMAND_MATRIX.md",
258
258
  "category": "startup_doc",
259
- "sha256": "baf9792f0bd50ce44de2dc16babc73f631a1191acff853fdc4caa7d452f50561"
259
+ "sha256": "48c1b7fbef3a01faf5ddf8bb232b19362b49ef2a371a7c38ae11302c8b3bccac"
260
260
  },
261
261
  {
262
262
  "path": "llms.txt",