mdkg 0.1.0 → 0.1.2

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 (68) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +108 -15
  3. package/dist/cli.js +566 -15
  4. package/dist/commands/archive.js +474 -0
  5. package/dist/commands/bundle.js +743 -0
  6. package/dist/commands/bundle_import.js +243 -0
  7. package/dist/commands/capability.js +162 -0
  8. package/dist/commands/doctor.js +233 -2
  9. package/dist/commands/format.js +38 -9
  10. package/dist/commands/index.js +11 -0
  11. package/dist/commands/init.js +188 -63
  12. package/dist/commands/init_manifest.js +19 -6
  13. package/dist/commands/list.js +5 -2
  14. package/dist/commands/new.js +6 -0
  15. package/dist/commands/next.js +7 -0
  16. package/dist/commands/node_card.js +4 -1
  17. package/dist/commands/pack.js +62 -2
  18. package/dist/commands/query_output.js +1 -0
  19. package/dist/commands/search.js +5 -2
  20. package/dist/commands/show.js +7 -14
  21. package/dist/commands/skill_mirror.js +22 -0
  22. package/dist/commands/task.js +3 -0
  23. package/dist/commands/upgrade.js +151 -13
  24. package/dist/commands/validate.js +19 -2
  25. package/dist/commands/work.js +365 -0
  26. package/dist/commands/workspace.js +12 -2
  27. package/dist/core/config.js +100 -1
  28. package/dist/graph/agent_file_types.js +78 -5
  29. package/dist/graph/archive_file.js +125 -0
  30. package/dist/graph/archive_integrity.js +66 -0
  31. package/dist/graph/bundle_imports.js +418 -0
  32. package/dist/graph/capabilities_index_cache.js +103 -0
  33. package/dist/graph/capabilities_indexer.js +231 -0
  34. package/dist/graph/frontmatter.js +19 -0
  35. package/dist/graph/index_cache.js +21 -4
  36. package/dist/graph/indexer.js +4 -1
  37. package/dist/graph/node.js +23 -4
  38. package/dist/graph/node_body.js +37 -0
  39. package/dist/graph/skills_indexer.js +8 -3
  40. package/dist/graph/template_schema.js +33 -5
  41. package/dist/graph/validate_graph.js +83 -7
  42. package/dist/graph/visibility.js +214 -0
  43. package/dist/graph/workspace_files.js +22 -0
  44. package/dist/init/AGENT_START.md +21 -0
  45. package/dist/init/CLI_COMMAND_MATRIX.md +58 -3
  46. package/dist/init/README.md +60 -3
  47. package/dist/init/config.json +13 -1
  48. package/dist/init/core/guide.md +6 -2
  49. package/dist/init/core/rule-3-cli-contract.md +71 -4
  50. package/dist/init/core/rule-4-repo-safety-and-ignores.md +20 -0
  51. package/dist/init/core/rule-6-templates-and-schemas.md +10 -1
  52. package/dist/init/init-manifest.json +19 -14
  53. package/dist/init/skills/default/build-pack-and-execute-task/SKILL.md +2 -1
  54. package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +26 -0
  55. package/dist/init/templates/default/archive.md +33 -0
  56. package/dist/init/templates/default/receipt.md +15 -1
  57. package/dist/init/templates/default/work.md +6 -1
  58. package/dist/init/templates/default/work_order.md +15 -1
  59. package/dist/pack/export_md.js +3 -0
  60. package/dist/pack/export_xml.js +3 -0
  61. package/dist/pack/order.js +1 -0
  62. package/dist/pack/pack.js +3 -13
  63. package/dist/templates/builtin.js +38 -0
  64. package/dist/templates/loader.js +9 -16
  65. package/dist/util/argparse.js +30 -0
  66. package/dist/util/refs.js +40 -0
  67. package/dist/util/zip.js +153 -0
  68. package/package.json +8 -2
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.collectGraphErrors = collectGraphErrors;
4
4
  exports.validateGraph = validateGraph;
5
+ const refs_1 = require("../util/refs");
5
6
  function pushError(errors, message) {
6
7
  if (errors) {
7
8
  errors.push(message);
@@ -9,7 +10,7 @@ function pushError(errors, message) {
9
10
  }
10
11
  throw new Error(message);
11
12
  }
12
- function validateEdgeTargets(index, allowMissing, knownSkillSlugs, errors) {
13
+ function validateEdgeTargets(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors) {
13
14
  const nodes = index.nodes;
14
15
  for (const [qid, node] of Object.entries(nodes)) {
15
16
  const edges = node.edges;
@@ -33,6 +34,10 @@ function validateEdgeTargets(index, allowMissing, knownSkillSlugs, errors) {
33
34
  for (const [edgeKey, values] of edgeLists) {
34
35
  for (const value of values) {
35
36
  if (!nodes[value]) {
37
+ const [workspace] = value.split(":");
38
+ if (workspace && externalWorkspaces?.has(workspace)) {
39
+ continue;
40
+ }
36
41
  if (edgeKey === "relates" &&
37
42
  node.type === "proposal" &&
38
43
  node.attributes.proposal_kind === "skill_update" &&
@@ -320,7 +325,11 @@ function buildNodeIdsByWorkspace(index) {
320
325
  }
321
326
  return nodeIdsByWorkspace;
322
327
  }
323
- function validateAgentWorkflowNodeIdRef(qid, ws, field, value, nodeIdsByWorkspace, allowSkillRef, knownSkillSlugs, allowMissing, errors) {
328
+ function validateAgentWorkflowNodeIdRef(qid, ws, field, value, nodeIdsByWorkspace, allowSkillRef, knownSkillSlugs, externalWorkspaces, allowMissing, errors) {
329
+ const [workspace] = value.split(":");
330
+ if (workspace && value.includes(":") && externalWorkspaces?.has(workspace)) {
331
+ return;
332
+ }
324
333
  if (nodeIdsByWorkspace[ws]?.has(value)) {
325
334
  return;
326
335
  }
@@ -333,7 +342,7 @@ function validateAgentWorkflowNodeIdRef(qid, ws, field, value, nodeIdsByWorkspac
333
342
  }
334
343
  pushError(errors, `${qid}: ${field} references missing node ${value}`);
335
344
  }
336
- function validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSkillSlugs, errors) {
345
+ function validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors) {
337
346
  const nodeIdsByWorkspace = buildNodeIdsByWorkspace(index);
338
347
  for (const [qid, node] of Object.entries(index.nodes)) {
339
348
  if (node.type !== "feedback" && node.type !== "proposal") {
@@ -342,7 +351,7 @@ function validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSki
342
351
  const targetId = node.attributes.target_id;
343
352
  if (typeof targetId === "string") {
344
353
  const allowSkillTarget = node.type === "proposal" && node.attributes.proposal_kind === "skill_update";
345
- validateAgentWorkflowNodeIdRef(qid, node.ws, "target_id", targetId, nodeIdsByWorkspace, allowSkillTarget, knownSkillSlugs, allowMissing, errors);
354
+ validateAgentWorkflowNodeIdRef(qid, node.ws, "target_id", targetId, nodeIdsByWorkspace, allowSkillTarget, knownSkillSlugs, externalWorkspaces, allowMissing, errors);
346
355
  }
347
356
  if (node.type !== "proposal") {
348
357
  continue;
@@ -355,7 +364,72 @@ function validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSki
355
364
  if (typeof value !== "string") {
356
365
  continue;
357
366
  }
358
- validateAgentWorkflowNodeIdRef(qid, node.ws, `evidence_refs[${indexValue}]`, value, nodeIdsByWorkspace, true, knownSkillSlugs, allowMissing, errors);
367
+ validateAgentWorkflowNodeIdRef(qid, node.ws, `evidence_refs[${indexValue}]`, value, nodeIdsByWorkspace, true, knownSkillSlugs, externalWorkspaces, allowMissing, errors);
368
+ }
369
+ }
370
+ }
371
+ function buildArchiveIdsByWorkspace(index) {
372
+ const archiveIdsByWorkspace = {};
373
+ for (const node of Object.values(index.nodes)) {
374
+ if (node.type !== "archive") {
375
+ continue;
376
+ }
377
+ if (!archiveIdsByWorkspace[node.ws]) {
378
+ archiveIdsByWorkspace[node.ws] = new Set();
379
+ }
380
+ archiveIdsByWorkspace[node.ws].add(node.id);
381
+ }
382
+ return archiveIdsByWorkspace;
383
+ }
384
+ function validateArchiveUriValue(qid, ws, field, value, archiveIdsByWorkspace, allowMissing, errors) {
385
+ if (!value.startsWith("archive://")) {
386
+ return;
387
+ }
388
+ const archiveId = (0, refs_1.archiveIdFromUri)(value);
389
+ if (!archiveId) {
390
+ pushError(errors, `${qid}: ${field} has malformed archive ref ${value}`);
391
+ return;
392
+ }
393
+ if (archiveIdsByWorkspace[ws]?.has(archiveId)) {
394
+ return;
395
+ }
396
+ if (allowMissing) {
397
+ return;
398
+ }
399
+ pushError(errors, `${qid}: ${field} references missing archive ${value}`);
400
+ }
401
+ function validateArchiveUriRefs(index, allowMissing, errors) {
402
+ const archiveIdsByWorkspace = buildArchiveIdsByWorkspace(index);
403
+ const attributeListFields = [
404
+ "input_refs",
405
+ "constraint_refs",
406
+ "proof_refs",
407
+ "attestation_refs",
408
+ ];
409
+ const attributeScalarFields = ["request_ref", "cost_ref"];
410
+ for (const [qid, node] of Object.entries(index.nodes)) {
411
+ for (const [indexValue, value] of node.artifacts.entries()) {
412
+ validateArchiveUriValue(qid, node.ws, `artifacts[${indexValue}]`, value, archiveIdsByWorkspace, allowMissing, errors);
413
+ }
414
+ const attributes = node.attributes ?? {};
415
+ for (const field of attributeListFields) {
416
+ const values = attributes[field];
417
+ if (!Array.isArray(values)) {
418
+ continue;
419
+ }
420
+ for (const [indexValue, value] of values.entries()) {
421
+ if (typeof value !== "string") {
422
+ continue;
423
+ }
424
+ validateArchiveUriValue(qid, node.ws, `${field}[${indexValue}]`, value, archiveIdsByWorkspace, allowMissing, errors);
425
+ }
426
+ }
427
+ for (const field of attributeScalarFields) {
428
+ const value = attributes[field];
429
+ if (typeof value !== "string") {
430
+ continue;
431
+ }
432
+ validateArchiveUriValue(qid, node.ws, field, value, archiveIdsByWorkspace, allowMissing, errors);
359
433
  }
360
434
  }
361
435
  }
@@ -396,14 +470,16 @@ function collectGraphErrors(index, options = {}) {
396
470
  const errors = [];
397
471
  const allowMissing = options.allowMissing ?? false;
398
472
  const knownSkillSlugs = options.knownSkillSlugs;
399
- validateEdgeTargets(index, allowMissing, knownSkillSlugs, errors);
473
+ const externalWorkspaces = options.externalWorkspaces;
474
+ validateEdgeTargets(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors);
400
475
  validatePrevNextSymmetry(index, allowMissing, errors);
401
476
  validateAgentWorkflowSpecWorkContracts(index, allowMissing, errors);
402
477
  validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, errors);
403
478
  validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, errors);
404
479
  validateAgentWorkflowSubagentRefs(index, allowMissing, errors);
405
480
  validateAgentWorkflowDisputeRefs(index, allowMissing, errors);
406
- validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSkillSlugs, errors);
481
+ validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors);
482
+ validateArchiveUriRefs(index, allowMissing, errors);
407
483
  detectPrevNextCycles(index, errors);
408
484
  return errors;
409
485
  }
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VISIBILITY_VALUES = void 0;
4
+ exports.isVisibility = isVisibility;
5
+ exports.normalizeVisibility = normalizeVisibility;
6
+ exports.isVisibleAt = isVisibleAt;
7
+ exports.isLessVisibleThan = isLessVisibleThan;
8
+ exports.effectiveNodeVisibility = effectiveNodeVisibility;
9
+ exports.collectNodeVisibilityReferences = collectNodeVisibilityReferences;
10
+ exports.collectVisibilityViolations = collectVisibilityViolations;
11
+ exports.visibilityViolationMessages = visibilityViolationMessages;
12
+ const errors_1 = require("../util/errors");
13
+ const refs_1 = require("../util/refs");
14
+ exports.VISIBILITY_VALUES = ["public", "internal", "private"];
15
+ const VISIBILITY_RANK = {
16
+ public: 0,
17
+ internal: 1,
18
+ private: 2,
19
+ };
20
+ function isVisibility(value) {
21
+ return typeof value === "string" && exports.VISIBILITY_VALUES.includes(value);
22
+ }
23
+ function normalizeVisibility(value, label = "--visibility", fallback = "private") {
24
+ const normalized = (value ?? fallback).toLowerCase();
25
+ if (isVisibility(normalized)) {
26
+ return normalized;
27
+ }
28
+ throw new errors_1.UsageError(`${label} must be public, internal, or private`);
29
+ }
30
+ function isVisibleAt(recordVisibility, scope) {
31
+ return VISIBILITY_RANK[recordVisibility] <= VISIBILITY_RANK[scope];
32
+ }
33
+ function isLessVisibleThan(targetVisibility, sourceVisibility) {
34
+ return VISIBILITY_RANK[targetVisibility] > VISIBILITY_RANK[sourceVisibility];
35
+ }
36
+ function effectiveNodeVisibility(node, config) {
37
+ if (node.source?.imported && isVisibility(node.source.visibility)) {
38
+ return node.source.visibility;
39
+ }
40
+ const archiveVisibility = node.attributes.visibility;
41
+ if (node.type === "archive" && isVisibility(archiveVisibility)) {
42
+ return archiveVisibility;
43
+ }
44
+ const workspaceVisibility = config.workspaces[node.ws]?.visibility;
45
+ if (isVisibility(workspaceVisibility)) {
46
+ return workspaceVisibility;
47
+ }
48
+ const importVisibility = config.bundle_imports[node.ws]?.visibility;
49
+ if (isVisibility(importVisibility)) {
50
+ return importVisibility;
51
+ }
52
+ return "private";
53
+ }
54
+ function collectStringValues(value, prefix, out) {
55
+ if (typeof value === "string") {
56
+ out.push({ field: prefix, value });
57
+ return;
58
+ }
59
+ if (Array.isArray(value)) {
60
+ value.forEach((item, index) => collectStringValues(item, `${prefix}[${index}]`, out));
61
+ return;
62
+ }
63
+ if (typeof value === "object" && value !== null) {
64
+ for (const [key, child] of Object.entries(value)) {
65
+ collectStringValues(child, prefix ? `${prefix}.${key}` : key, out);
66
+ }
67
+ }
68
+ }
69
+ function collectNodeStringReferences(node) {
70
+ const values = [];
71
+ const edgeFields = [
72
+ ["epic", node.edges.epic],
73
+ ["parent", node.edges.parent],
74
+ ["prev", node.edges.prev],
75
+ ["next", node.edges.next],
76
+ ];
77
+ for (const [field, value] of edgeFields) {
78
+ if (value) {
79
+ values.push({ field, value });
80
+ }
81
+ }
82
+ for (const [index, value] of node.edges.relates.entries()) {
83
+ values.push({ field: `relates[${index}]`, value });
84
+ }
85
+ for (const [index, value] of node.edges.blocked_by.entries()) {
86
+ values.push({ field: `blocked_by[${index}]`, value });
87
+ }
88
+ for (const [index, value] of node.edges.blocks.entries()) {
89
+ values.push({ field: `blocks[${index}]`, value });
90
+ }
91
+ for (const [index, value] of node.links.entries()) {
92
+ values.push({ field: `links[${index}]`, value });
93
+ }
94
+ for (const [index, value] of node.artifacts.entries()) {
95
+ values.push({ field: `artifacts[${index}]`, value });
96
+ }
97
+ for (const [index, value] of node.refs.entries()) {
98
+ values.push({ field: `refs[${index}]`, value });
99
+ }
100
+ collectStringValues(node.attributes, "attributes", values);
101
+ return values;
102
+ }
103
+ function archiveNodeById(index, workspace, archiveId) {
104
+ const sameWorkspace = index.nodes[`${workspace}:${archiveId}`];
105
+ if (sameWorkspace?.type === "archive") {
106
+ return sameWorkspace;
107
+ }
108
+ const matches = Object.values(index.nodes).filter((candidate) => candidate.type === "archive" && candidate.id === archiveId);
109
+ return matches.length === 1 ? matches[0] : undefined;
110
+ }
111
+ function resolveReferenceTarget(index, source, value) {
112
+ const archiveId = (0, refs_1.archiveIdFromUri)(value);
113
+ if (archiveId) {
114
+ return archiveNodeById(index, source.ws, archiveId);
115
+ }
116
+ if ((0, refs_1.isUriRef)(value)) {
117
+ return undefined;
118
+ }
119
+ const exact = index.nodes[value];
120
+ if (exact) {
121
+ return exact;
122
+ }
123
+ if (!value.includes(":")) {
124
+ return index.nodes[`${source.ws}:${value}`];
125
+ }
126
+ return undefined;
127
+ }
128
+ function collectNodeVisibilityReferences(index, config, node) {
129
+ const references = [];
130
+ const seen = new Set();
131
+ for (const ref of collectNodeStringReferences(node)) {
132
+ const target = resolveReferenceTarget(index, node, ref.value);
133
+ if (!target || target.qid === node.qid) {
134
+ continue;
135
+ }
136
+ const key = `${ref.field}\0${ref.value}\0${target.qid}`;
137
+ if (seen.has(key)) {
138
+ continue;
139
+ }
140
+ seen.add(key);
141
+ references.push({
142
+ field: ref.field,
143
+ value: ref.value,
144
+ targetQid: target.qid,
145
+ targetVisibility: effectiveNodeVisibility(target, config),
146
+ });
147
+ }
148
+ return references;
149
+ }
150
+ function collectVisibilityViolations(index, config, options = {}) {
151
+ const violations = [];
152
+ const qids = options.includedQids
153
+ ? Object.keys(index.nodes).filter((qid) => options.includedQids?.has(qid))
154
+ : Object.keys(index.nodes);
155
+ for (const qid of qids.sort()) {
156
+ const node = index.nodes[qid];
157
+ if (!node) {
158
+ continue;
159
+ }
160
+ const sourceVisibility = effectiveNodeVisibility(node, config);
161
+ if (options.scope && !isVisibleAt(sourceVisibility, options.scope)) {
162
+ continue;
163
+ }
164
+ for (const ref of collectNodeVisibilityReferences(index, config, node)) {
165
+ if (options.includedQids && !options.includedQids.has(ref.targetQid)) {
166
+ const target = index.nodes[ref.targetQid];
167
+ if (!target) {
168
+ continue;
169
+ }
170
+ const targetVisibility = effectiveNodeVisibility(target, config);
171
+ if (options.scope && isVisibleAt(targetVisibility, options.scope)) {
172
+ continue;
173
+ }
174
+ violations.push({
175
+ qid: node.qid,
176
+ visibility: sourceVisibility,
177
+ field: ref.field,
178
+ value: ref.value,
179
+ target_qid: ref.targetQid,
180
+ target_visibility: targetVisibility,
181
+ message: `${node.qid} references ${targetVisibility} ${ref.targetQid} through ${ref.field}`,
182
+ });
183
+ continue;
184
+ }
185
+ if (isLessVisibleThan(ref.targetVisibility, sourceVisibility)) {
186
+ violations.push({
187
+ qid: node.qid,
188
+ visibility: sourceVisibility,
189
+ field: ref.field,
190
+ value: ref.value,
191
+ target_qid: ref.targetQid,
192
+ target_visibility: ref.targetVisibility,
193
+ message: `${node.qid} (${sourceVisibility}) references ${ref.targetVisibility} ${ref.targetQid} through ${ref.field}`,
194
+ });
195
+ continue;
196
+ }
197
+ if (options.scope && !isVisibleAt(ref.targetVisibility, options.scope)) {
198
+ violations.push({
199
+ qid: node.qid,
200
+ visibility: sourceVisibility,
201
+ field: ref.field,
202
+ value: ref.value,
203
+ target_qid: ref.targetQid,
204
+ target_visibility: ref.targetVisibility,
205
+ message: `${node.qid} references ${ref.targetVisibility} ${ref.targetQid} through ${ref.field}, which is excluded by ${options.scope} visibility`,
206
+ });
207
+ }
208
+ }
209
+ }
210
+ return violations;
211
+ }
212
+ function visibilityViolationMessages(violations) {
213
+ return Array.from(new Set(violations.map((violation) => violation.message))).sort();
214
+ }
@@ -26,6 +26,26 @@ function listMarkdownFiles(dir) {
26
26
  }
27
27
  return files;
28
28
  }
29
+ function listArchiveSidecarFiles(dir) {
30
+ if (!fs_1.default.existsSync(dir)) {
31
+ return [];
32
+ }
33
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
34
+ const files = [];
35
+ for (const entry of entries) {
36
+ if (entry.name === "source") {
37
+ continue;
38
+ }
39
+ const fullPath = path_1.default.join(dir, entry.name);
40
+ if (entry.isDirectory()) {
41
+ files.push(...listArchiveSidecarFiles(fullPath));
42
+ }
43
+ else if (entry.isFile() && entry.name.endsWith(".md")) {
44
+ files.push(fullPath);
45
+ }
46
+ }
47
+ return files;
48
+ }
29
49
  function getWorkspaceDocRoots(root, config) {
30
50
  const roots = [];
31
51
  const aliases = Object.keys(config.workspaces).sort();
@@ -46,6 +66,7 @@ function listWorkspaceDocFiles(root, config) {
46
66
  const folderPath = path_1.default.join(wsRoot, folder);
47
67
  files.push(...listMarkdownFiles(folderPath));
48
68
  }
69
+ files.push(...listArchiveSidecarFiles(path_1.default.join(wsRoot, "archive")));
49
70
  }
50
71
  return files;
51
72
  }
@@ -57,6 +78,7 @@ function listWorkspaceDocFilesByAlias(root, config) {
57
78
  const folderPath = path_1.default.join(wsRoot, folder);
58
79
  files.push(...listMarkdownFiles(folderPath));
59
80
  }
81
+ files.push(...listArchiveSidecarFiles(path_1.default.join(wsRoot, "archive")));
60
82
  files.sort();
61
83
  result[alias] = files;
62
84
  }
@@ -22,6 +22,17 @@ Agent operating prompt:
22
22
  - Use `mdkg show <id>` for direct inspection and `mdkg show <id> --meta` for card-only inspection.
23
23
  - Use `mdkg search "..."` and `mdkg next` to discover current work.
24
24
  - Use `mdkg skill list`, `mdkg skill search`, and `mdkg skill show <slug>` for skill discovery.
25
+ - Use `mdkg capability list/search/show` for deterministic skills, `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
26
+ - Use `mdkg archive add/list/show/verify/compress` for committed source and artifact sidecars under `.mdkg/archive`.
27
+ - Use `mdkg work ...` helpers for semantic mirror contracts, work orders, receipts, and artifact registration.
28
+ - 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.
29
+ - Use `artifact://...` for external/runtime-managed artifacts and `archive://...` for committed mdkg archive sidecars.
30
+ - Use `mdkg bundle create/list/show/verify` for explicit full `.mdkg` graph snapshot bundles.
31
+ - Use `mdkg bundle import add/list/verify` to register child bundle snapshots as read-only planning context.
32
+ - Use `mdkg pack <id> --visibility public|internal` only when you need a public-safe or internal-safe pack; no flag remains private-capable local behavior.
33
+ - Mark archive sidecars public only with explicit `mdkg archive add --visibility public` intent.
34
+ - Treat sidecar `.md` plus deterministic `.zip` caches as the commit-eligible archive record; validation and `mdkg archive verify` both check ZIP payload integrity.
35
+ - Before committing repos that track archive caches or `.mdkg/bundles/`, run `mdkg archive compress --all`, `mdkg archive verify --json`, `mdkg bundle create --profile private`, and `mdkg bundle verify .mdkg/bundles/private/all.mdkg.zip`.
25
36
  - Use `mdkg task start/update/done` for structured task, bug, and test lifecycle fields.
26
37
  - Use `mdkg upgrade` to preview scaffold updates; only run `mdkg upgrade --apply` after reviewing the receipt.
27
38
  - Keep nuanced summaries, body text, and manual parent closeout edits in markdown.
@@ -42,12 +53,22 @@ If no task is known:
42
53
  - `mdkg next`
43
54
  - then use `mdkg pack <id>`
44
55
 
56
+ If this is a fresh import or external docs bundle:
57
+ - create a root epic, PRD, or EDD that captures the imported context and source locations
58
+ - create follow-on tasks and tests from that root context instead of scattering untracked notes
59
+ - run `mdkg validate` after the first ingestion pass
60
+
45
61
  Skill discovery:
46
62
  - `mdkg skill list --tags stage:plan --json`
47
63
  - `mdkg skill list --tags stage:execute --json`
48
64
  - `mdkg skill list --tags stage:review --json`
49
65
  - `mdkg skill show select-work-and-ground-context`
50
66
 
67
+ Capability discovery:
68
+ - `mdkg capability list --kind skill --json`
69
+ - `mdkg capability search "<query>" --kind spec --json`
70
+ - `mdkg capability search "<query>" --kind work --json`
71
+
51
72
  Conventions:
52
73
  - `AGENTS.md` is the Codex/OpenAI-oriented wrapper doc.
53
74
  - `CLAUDE.md` is the Claude-oriented wrapper doc.
@@ -15,6 +15,10 @@ Primary commands:
15
15
  - `mdkg search`
16
16
  - `mdkg pack`
17
17
  - `mdkg skill`
18
+ - `mdkg capability`
19
+ - `mdkg archive`
20
+ - `mdkg bundle`
21
+ - `mdkg work`
18
22
  - `mdkg task`
19
23
  - `mdkg validate`
20
24
 
@@ -42,7 +46,7 @@ Agent workflow notes:
42
46
 
43
47
  Workspace registry commands:
44
48
  - `mdkg workspace ls [--json]`
45
- - `mdkg workspace add <alias> <path> [--mdkg-dir <dir>] [--json]`
49
+ - `mdkg workspace add <alias> <path> [--mdkg-dir <dir>] [--visibility <level>] [--json]`
46
50
  - `mdkg workspace rm <alias> [--json]`
47
51
  - `mdkg workspace enable <alias> [--json]`
48
52
  - `mdkg workspace disable <alias> [--json]`
@@ -60,15 +64,17 @@ Checkpoint commands:
60
64
  - `mdkg checkpoint new <title> [--ws <alias>] [--json]`
61
65
 
62
66
  Agent bootstrap:
63
- - `mdkg init --llm`
64
67
  - `mdkg init --agent`
65
- - `mdkg init --llm --agent`
66
68
  - published bootstrap config is root-only by default
69
+ - `mdkg init --agent` creates the complete startup docs, wrapper docs, default mdkg skills, event log, registry, and skill mirrors
70
+ - removed flags `--llm`, `--agents`, `--claude`, and `--omni` fail before mutation with guidance to use `mdkg init --agent`
67
71
 
68
72
  Upgrade:
69
73
  - `mdkg upgrade` previews safe scaffold updates and writes nothing by default
70
74
  - `mdkg upgrade --apply` updates only managed or unchanged init assets
75
+ - JSON receipts include `safe_to_apply`, `will_write_paths`, `preserved_customizations`, `blocking_conflicts`, and `apply_side_effects`
71
76
  - customized docs, templates, skills, and core files are preserved and reported
77
+ - ignored event logs are skipped with guidance to run `mdkg event enable`
72
78
 
73
79
  Skill discovery:
74
80
  - `mdkg skill list --tags stage:plan --json`
@@ -77,6 +83,55 @@ Skill discovery:
77
83
  - `mdkg skill validate [<slug>] [--json]`
78
84
  - `mdkg skill sync [--force] [--json]`
79
85
 
86
+ Capability discovery:
87
+ - `mdkg capability list [--kind <skill|spec|work|core|design>] [--visibility <private|internal|public>] [--json]`
88
+ - `mdkg capability search "<query>" [--kind <kind>] [--visibility <level>] [--json]`
89
+ - `mdkg capability show <id-or-qid-or-slug> [--json]`
90
+ - capability records are deterministic cache projections from Markdown
91
+ - records include source hash, headings, refs, and `indexed_at`
92
+ - normal task, epic, feat, bug, test, and checkpoint nodes are intentionally excluded
93
+
94
+ Archive sidecars:
95
+ - `mdkg archive add <file> [--id <archive.id>] [--kind source|artifact] [--visibility private|internal|public] [--title <title>] [--refs <...>] [--relates <...>] [--json]`
96
+ - `mdkg archive list [--kind source|artifact] [--visibility private|internal|public] [--ws <alias>] [--json]`
97
+ - `mdkg archive show <id-or-archive-uri> [--ws <alias>] [--json]`
98
+ - `mdkg archive verify [id-or-archive-uri] [--ws <alias>] [--json]`
99
+ - `mdkg archive compress <id-or-archive-uri|--all> [--json]`
100
+ - archive sidecars are `type: archive` nodes under `.mdkg/archive`
101
+ - archive visibility defaults to `private`
102
+ - `mdkg validate` and `mdkg archive verify` both check ZIP hash, ZIP readability, payload SHA-256, and payload byte size
103
+ - outside-repo archive sources are recorded as `external:<basename>` instead of absolute local paths
104
+ - `mdkg doctor` warns about ZIP caches larger than `archive.large_cache_warning_bytes`; `0` disables the warning
105
+ - committed sidecar `.md` files and ZIP caches are source-of-truth evidence; raw source copies under `.mdkg/archive/**/source/` are ignored by default
106
+
107
+ Graph snapshot bundles:
108
+ - `mdkg bundle create [--profile private|public] [--ws <alias|all>] [--output <path>] [--json]`
109
+ - `mdkg bundle verify [bundle-path] [--json]`
110
+ - `mdkg bundle show <bundle-path> [--json]`
111
+ - `mdkg bundle list [--json]`
112
+ - `mdkg bundle import add/list/rm/enable/disable/verify ...`
113
+ - `mdkg bundle import add <alias> <bundle-path> [--visibility private|internal|public] [--profile private|public] [--source-path <path>] [--json]`
114
+ - `mdkg bundle import verify [alias|--all] [--json]`
115
+ - default output is `.mdkg/bundles/<profile>/<workspace-or-all>.mdkg.zip`
116
+ - private bundles are explicit local graph transport artifacts
117
+ - bundle imports are read-only planning views and use import-alias qids such as `child_repo:task-1`
118
+ - repos that track archive caches or bundles should run `mdkg archive compress --all`, `mdkg archive verify --json`, `mdkg bundle create --profile private`, and `mdkg bundle verify .mdkg/bundles/private/all.mdkg.zip` before commit
119
+ - public bundles include only public workspace content and public archive sidecars
120
+ - public bundle creation fails when public records reference private graph, archive, or imported records
121
+ - public/internal imports require public bundle profiles
122
+
123
+ Work semantic mirrors:
124
+ - `mdkg work contract new "<title>" --id <work.id> --agent-id <agent.id> --kind <kind> --inputs <...> --outputs <...> [--required-capabilities <...>] [--pricing-model <...>] [--json]`
125
+ - `mdkg work order new "<title>" --id <order.id> --work-id <work.id> --requester <ref> [--request-ref <ref>] [--input-refs <...>] [--requested-outputs <...>] [--json]`
126
+ - `mdkg work order update <id-or-qid> [--status <status>] [--add-input-refs <...>] [--add-artifacts <...>] [--json]`
127
+ - `mdkg work receipt new "<title>" --id <receipt.id> --work-order-id <order.id> --outcome success|partial|failure [--receipt-status recorded|verified|rejected|superseded] [--json]`
128
+ - `mdkg work receipt update <id-or-qid> [--receipt-status <status>] [--add-artifacts <...>] [--add-proof-refs <...>] [--add-attestation-refs <...>] [--json]`
129
+ - `mdkg work artifact add <order-or-receipt-id-or-qid> <file> [--id <archive.id>] [--kind source|artifact] [--json]`
130
+ - 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
131
+ - do not store raw secrets, credentials, live payment state, ledger mutations, or canonical marketplace state in work mirrors
132
+ - `artifact://...` refs identify external/runtime-managed artifacts; `archive://...` refs identify committed mdkg archive sidecars
133
+ - work update and artifact commands accept local ids or local qids; imported bundle qids are read-only and must be changed in their source workspace
134
+
80
135
  Discovery/show export flags:
81
136
  - `--json`
82
137
  - `--xml`
@@ -8,20 +8,28 @@ This repository is initialized for mdkg.
8
8
  - `design/`: product/engineering decision records
9
9
  - `work/`: epics, tasks, bugs, tests, checkpoints
10
10
  - `templates/`: default node templates
11
+ - `archive/`: sidecar metadata and deterministic compressed source/artifact caches
12
+ - `bundles/`: optional committed full graph snapshot bundles
11
13
  - `index/`: generated index cache (do not commit)
12
14
  - `pack/`: generated context packs (do not commit)
13
15
 
14
- ## First Commands
16
+ ## Next Commands
15
17
 
16
18
  ```bash
17
- mdkg init --llm --agent
18
19
  mdkg upgrade
20
+ mdkg new task "..." --status todo --priority 1
19
21
  mdkg search "..."
20
22
  mdkg show <id>
21
23
  mdkg pack <id>
24
+ mdkg capability search "..."
25
+ mdkg archive list
26
+ mdkg bundle create --profile private
27
+ mdkg bundle import list --json
22
28
  mdkg validate
23
29
  ```
24
30
 
31
+ This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg new` to create work, `mdkg search`/`mdkg show` to inspect graph state, `mdkg capability ...` to inspect cached skill/spec/work/core/design 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 and read-only child graph imports, `mdkg pack <id>` to build deterministic context, and `mdkg validate` before closeout.
32
+
25
33
  Agent workflow docs can use semantic ids:
26
34
 
27
35
  ```bash
@@ -45,6 +53,7 @@ Ensure ignore files include:
45
53
 
46
54
  - `.mdkg/index/`
47
55
  - `.mdkg/pack/`
56
+ - `.mdkg/archive/**/source/`
48
57
 
49
58
  Recommended:
50
59
 
@@ -56,4 +65,52 @@ mdkg init --update-gitignore --update-npmignore
56
65
 
57
66
  `mdkg upgrade` previews safe scaffold updates for existing workspaces and writes nothing by default.
58
67
 
59
- Use `mdkg upgrade --apply` only after reviewing the receipt. Local customizations are preserved and reported instead of overwritten.
68
+ Use `mdkg upgrade --apply` only after reviewing `safe_to_apply`, `will_write_paths`, and `apply_side_effects` in the receipt. Local customizations are preserved and reported instead of overwritten. Missing built-in templates can be loaded from the installed package as a read-only fallback until you vendor them with upgrade.
69
+
70
+ ## Snapshot Bundles
71
+
72
+ Create explicit full `.mdkg` graph snapshots with:
73
+
74
+ ```bash
75
+ mdkg archive compress --all
76
+ mdkg archive verify --json
77
+ mdkg bundle create --profile private
78
+ mdkg bundle verify .mdkg/bundles/private/all.mdkg.zip
79
+ ```
80
+
81
+ Use this as a pre-commit recommendation only when the repo tracks archive caches or `.mdkg/bundles/`. Private bundles are local graph transport artifacts and may be tracked in private repos when configured. Public bundles require selected workspaces with `visibility: public` and fail closed when public records reference private graph, archive, or imported records.
82
+
83
+ Register child bundle snapshots as read-only imports with:
84
+
85
+ ```bash
86
+ mdkg bundle import add child_repo child-repo/.mdkg/bundles/private/all.mdkg.zip --source-path child-repo
87
+ mdkg bundle import verify child_repo --json
88
+ ```
89
+
90
+ Imported nodes use the import alias as their qid prefix and can be inspected or packed, but mutations must happen in the owning child repo.
91
+
92
+ ## Archive and Work Mirrors
93
+
94
+ Archive source/artifact files with:
95
+
96
+ ```bash
97
+ mdkg archive add <file> --id archive.example --kind source --visibility private
98
+ mdkg archive verify archive://archive.example
99
+ ```
100
+
101
+ `mdkg validate` and `mdkg archive verify` both check the archive sidecar contract and deterministic ZIP payload integrity. Raw local archive source copies under `.mdkg/archive/**/source/` are ignored by default; sidecar `.md` files and ZIP caches are the commit-eligible evidence. Outside-repo sources are recorded as `external:<basename>`, and `mdkg doctor` warns about large ZIP caches using `archive.large_cache_warning_bytes` from `.mdkg/config.json`.
102
+
103
+ Use work lifecycle helpers for semantic mirrors only:
104
+
105
+ ```bash
106
+ mdkg work contract new "example capability" --id work.example --agent-id agent.example --kind example --inputs prompt:text:required --outputs result:text:required
107
+ mdkg work order new "example request" --id order.example-1 --work-id work.example --requester user://example
108
+ mdkg work receipt new "example receipt" --id receipt.example-1 --work-order-id order.example-1 --outcome success
109
+ ```
110
+
111
+ Receipt statuses are `recorded`, `verified`, `rejected`, and `superseded`.
112
+ Update and artifact commands accept local ids or local qids; imported bundle qids are read-only and must be changed in their source workspace.
113
+
114
+ 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.
115
+
116
+ Use `artifact://...` for external or runtime-managed artifact identities. Use `archive://...` only for committed mdkg archive sidecars.
@@ -2,11 +2,22 @@
2
2
  "schema_version": 1,
3
3
  "tool": "mdkg",
4
4
  "root_required": true,
5
+ "archive": {
6
+ "large_cache_warning_bytes": 26214400
7
+ },
5
8
  "index": {
6
9
  "auto_reindex": true,
7
10
  "tolerant": false,
8
11
  "global_index_path": ".mdkg/index/global.json"
9
12
  },
13
+ "capabilities": {
14
+ "cache_path": ".mdkg/index/capabilities.json"
15
+ },
16
+ "bundles": {
17
+ "output_dir": ".mdkg/bundles",
18
+ "default_profile": "private"
19
+ },
20
+ "bundle_imports": {},
10
21
  "pack": {
11
22
  "default_depth": 2,
12
23
  "default_edges": [
@@ -51,7 +62,8 @@
51
62
  "root": {
52
63
  "path": ".",
53
64
  "enabled": true,
54
- "mdkg_dir": ".mdkg"
65
+ "mdkg_dir": ".mdkg",
66
+ "visibility": "private"
55
67
  }
56
68
  }
57
69
  }