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.
- package/CHANGELOG.md +44 -1
- package/README.md +26 -4
- package/dist/cli.js +146 -7
- package/dist/commands/capability.js +13 -8
- package/dist/commands/format.js +1 -1
- package/dist/commands/spec.js +101 -0
- package/dist/commands/work.js +569 -20
- package/dist/graph/agent_file_types.js +95 -7
- package/dist/graph/capabilities_indexer.js +89 -2
- package/dist/graph/frontmatter.js +6 -0
- package/dist/graph/node.js +8 -2
- package/dist/init/AGENT_START.md +5 -1
- package/dist/init/CLI_COMMAND_MATRIX.md +23 -0
- package/dist/init/README.md +25 -2
- package/dist/init/init-manifest.json +20 -20
- package/dist/init/templates/default/receipt.md +12 -1
- package/dist/init/templates/default/spec.md +8 -6
- package/dist/init/templates/default/work.md +5 -1
- package/dist/init/templates/default/work_order.md +11 -0
- package/dist/init/templates/specs/agent.SPEC.md +45 -4
- package/dist/init/templates/specs/api.SPEC.md +1 -0
- package/dist/init/templates/specs/base.SPEC.md +45 -12
- package/dist/init/templates/specs/capability.SPEC.md +16 -3
- package/dist/init/templates/specs/integration.SPEC.md +1 -0
- package/dist/init/templates/specs/model.SPEC.md +1 -0
- package/dist/init/templates/specs/project.SPEC.md +14 -1
- package/dist/init/templates/specs/{omniruntime-agent.SPEC.md → runtime-agent.SPEC.md} +13 -3
- package/dist/init/templates/specs/runtime-image.SPEC.md +1 -0
- package/dist/init/templates/specs/tool.SPEC.md +1 -0
- package/dist/util/argparse.js +8 -0
- package/package.json +4 -2
|
@@ -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
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
validatePortableRefs(
|
|
378
|
-
|
|
379
|
-
validatePortableRefs(
|
|
380
|
-
|
|
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
|
|
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",
|
package/dist/graph/node.js
CHANGED
|
@@ -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
|
}
|
package/dist/init/AGENT_START.md
CHANGED
|
@@ -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
|
|
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
|
package/dist/init/README.md
CHANGED
|
@@ -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
|
|
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.
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
179
|
+
"sha256": "5fe376413035f2afe406d13491a597f103a2fce29d137951fe55ae042a1082f5"
|
|
180
180
|
},
|
|
181
181
|
{
|
|
182
182
|
"path": ".mdkg/templates/default/work.md",
|
|
183
183
|
"category": "template",
|
|
184
|
-
"sha256": "
|
|
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": "
|
|
194
|
+
"sha256": "dab10c0ed12aa10a752ee3bd61f263065644826eb950c71a9e3458673edb0ca5"
|
|
195
195
|
},
|
|
196
196
|
{
|
|
197
197
|
"path": ".mdkg/templates/specs/api.SPEC.md",
|
|
198
198
|
"category": "template",
|
|
199
|
-
"sha256": "
|
|
199
|
+
"sha256": "aee86cadcca31a5a015d7e15ad7503c4aa30f2af0079ec03f857b82b3ecbae59"
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
202
|
"path": ".mdkg/templates/specs/base.SPEC.md",
|
|
203
203
|
"category": "template",
|
|
204
|
-
"sha256": "
|
|
204
|
+
"sha256": "6d4171fac00c2f3d8f2a2ac746b8a47c59aaecebe224c3a0046dd6e6974a1d08"
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
"path": ".mdkg/templates/specs/capability.SPEC.md",
|
|
208
208
|
"category": "template",
|
|
209
|
-
"sha256": "
|
|
209
|
+
"sha256": "68a91e8bbd80d1ff1972e4c31e29f26451d5a1be1d25d414170fdd670010066f"
|
|
210
210
|
},
|
|
211
211
|
{
|
|
212
212
|
"path": ".mdkg/templates/specs/integration.SPEC.md",
|
|
213
213
|
"category": "template",
|
|
214
|
-
"sha256": "
|
|
214
|
+
"sha256": "e907ce6ebc1fa5a455e31e39036e3f8699dccb3d9e45288c8ea025eaec4ca4a2"
|
|
215
215
|
},
|
|
216
216
|
{
|
|
217
217
|
"path": ".mdkg/templates/specs/model.SPEC.md",
|
|
218
218
|
"category": "template",
|
|
219
|
-
"sha256": "
|
|
219
|
+
"sha256": "56061a241819dfda4d3022c075f744cf6650f5f52c58cd15b0af9d1f613af4f2"
|
|
220
220
|
},
|
|
221
221
|
{
|
|
222
|
-
"path": ".mdkg/templates/specs/
|
|
222
|
+
"path": ".mdkg/templates/specs/project.SPEC.md",
|
|
223
223
|
"category": "template",
|
|
224
|
-
"sha256": "
|
|
224
|
+
"sha256": "386c41852cbb46e7a6ba583a7b0c4126262a56618d8e214aaa601b68d55818b9"
|
|
225
225
|
},
|
|
226
226
|
{
|
|
227
|
-
"path": ".mdkg/templates/specs/
|
|
227
|
+
"path": ".mdkg/templates/specs/runtime-agent.SPEC.md",
|
|
228
228
|
"category": "template",
|
|
229
|
-
"sha256": "
|
|
229
|
+
"sha256": "53af7c3e172f5ed1297f340aca0be5e53302613d2e6bb9145915067d7b0004c8"
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
232
|
"path": ".mdkg/templates/specs/runtime-image.SPEC.md",
|
|
233
233
|
"category": "template",
|
|
234
|
-
"sha256": "
|
|
234
|
+
"sha256": "37416b045cd7733d1f5e1cc629ac9b6616024d5fa52f2bdcd90110267151e593"
|
|
235
235
|
},
|
|
236
236
|
{
|
|
237
237
|
"path": ".mdkg/templates/specs/tool.SPEC.md",
|
|
238
238
|
"category": "template",
|
|
239
|
-
"sha256": "
|
|
239
|
+
"sha256": "05b827bbce4f721ea25beda62850688aff3db644aec65e71b9cf76cad8e5f46f"
|
|
240
240
|
},
|
|
241
241
|
{
|
|
242
242
|
"path": "AGENT_START.md",
|
|
243
243
|
"category": "startup_doc",
|
|
244
|
-
"sha256": "
|
|
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": "
|
|
259
|
+
"sha256": "48c1b7fbef3a01faf5ddf8bb232b19362b49ef2a371a7c38ae11302c8b3bccac"
|
|
260
260
|
},
|
|
261
261
|
{
|
|
262
262
|
"path": "llms.txt",
|