mdkg 0.0.1 → 0.0.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 (67) hide show
  1. package/README.md +20 -6
  2. package/dist/cli.js +667 -11
  3. package/dist/commands/checkpoint.js +133 -0
  4. package/dist/commands/format.js +297 -0
  5. package/dist/commands/guide.js +22 -0
  6. package/dist/commands/index.js +17 -0
  7. package/dist/commands/init.js +111 -0
  8. package/dist/commands/list.js +52 -0
  9. package/dist/commands/new.js +279 -0
  10. package/dist/commands/next.js +75 -0
  11. package/dist/commands/node_card.js +17 -0
  12. package/dist/commands/pack.js +105 -0
  13. package/dist/commands/search.js +70 -0
  14. package/dist/commands/show.js +95 -0
  15. package/dist/commands/validate.js +229 -0
  16. package/dist/commands/workspace.js +101 -0
  17. package/dist/core/config.js +162 -0
  18. package/dist/core/migrate.js +30 -0
  19. package/dist/core/paths.js +14 -0
  20. package/dist/graph/edges.js +64 -0
  21. package/dist/graph/frontmatter.js +132 -0
  22. package/dist/graph/index_cache.js +50 -0
  23. package/dist/graph/indexer.js +144 -0
  24. package/dist/graph/node.js +225 -0
  25. package/dist/graph/staleness.js +31 -0
  26. package/dist/graph/template_schema.js +86 -0
  27. package/dist/graph/validate_graph.js +115 -0
  28. package/dist/graph/workspace_files.js +64 -0
  29. package/dist/init/AGENTS.md +43 -0
  30. package/dist/init/CLAUDE.md +37 -0
  31. package/dist/init/config.json +67 -0
  32. package/dist/init/core/core.md +12 -0
  33. package/dist/init/core/guide.md +99 -0
  34. package/dist/init/core/rule-1-mdkg-conventions.md +232 -0
  35. package/dist/init/core/rule-2-context-pack-rules.md +186 -0
  36. package/dist/init/core/rule-3-cli-contract.md +177 -0
  37. package/dist/init/core/rule-4-repo-safety-and-ignores.md +97 -0
  38. package/dist/init/core/rule-5-release-and-versioning.md +82 -0
  39. package/dist/init/core/rule-6-templates-and-schemas.md +186 -0
  40. package/dist/init/templates/default/bug.md +54 -0
  41. package/dist/init/templates/default/chk.md +55 -0
  42. package/dist/init/templates/default/dec.md +38 -0
  43. package/dist/init/templates/default/edd.md +50 -0
  44. package/dist/init/templates/default/epic.md +46 -0
  45. package/dist/init/templates/default/feat.md +35 -0
  46. package/dist/init/templates/default/prd.md +59 -0
  47. package/dist/init/templates/default/prop.md +45 -0
  48. package/dist/init/templates/default/rule.md +33 -0
  49. package/dist/init/templates/default/task.md +53 -0
  50. package/dist/init/templates/default/test.md +49 -0
  51. package/dist/pack/export_json.js +38 -0
  52. package/dist/pack/export_md.js +93 -0
  53. package/dist/pack/export_toon.js +7 -0
  54. package/dist/pack/export_xml.js +73 -0
  55. package/dist/pack/order.js +162 -0
  56. package/dist/pack/pack.js +181 -0
  57. package/dist/pack/types.js +2 -0
  58. package/dist/pack/verbose_core.js +23 -0
  59. package/dist/templates/loader.js +82 -0
  60. package/dist/util/argparse.js +154 -0
  61. package/dist/util/date.js +9 -0
  62. package/dist/util/errors.js +12 -0
  63. package/dist/util/filter.js +26 -0
  64. package/dist/util/output.js +50 -0
  65. package/dist/util/qid.js +54 -0
  66. package/dist/util/sort.js +40 -0
  67. package/package.json +18 -2
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectGraphErrors = collectGraphErrors;
4
+ exports.validateGraph = validateGraph;
5
+ function pushError(errors, message) {
6
+ if (errors) {
7
+ errors.push(message);
8
+ return;
9
+ }
10
+ throw new Error(message);
11
+ }
12
+ function validateEdgeTargets(index, allowMissing, errors) {
13
+ const nodes = index.nodes;
14
+ for (const [qid, node] of Object.entries(nodes)) {
15
+ const edges = node.edges;
16
+ const edgeLists = [
17
+ ["relates", edges.relates],
18
+ ["blocked_by", edges.blocked_by],
19
+ ["blocks", edges.blocks],
20
+ ];
21
+ if (edges.epic) {
22
+ edgeLists.push(["epic", [edges.epic]]);
23
+ }
24
+ if (edges.parent) {
25
+ edgeLists.push(["parent", [edges.parent]]);
26
+ }
27
+ if (edges.prev) {
28
+ edgeLists.push(["prev", [edges.prev]]);
29
+ }
30
+ if (edges.next) {
31
+ edgeLists.push(["next", [edges.next]]);
32
+ }
33
+ for (const [edgeKey, values] of edgeLists) {
34
+ for (const value of values) {
35
+ if (!nodes[value]) {
36
+ if (allowMissing) {
37
+ continue;
38
+ }
39
+ pushError(errors, `${qid}: ${edgeKey} references missing node ${value}`);
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ function validatePrevNextSymmetry(index, _allowMissing, errors) {
46
+ const nodes = index.nodes;
47
+ for (const [qid, node] of Object.entries(nodes)) {
48
+ const edges = node.edges;
49
+ if (edges.next) {
50
+ const target = nodes[edges.next];
51
+ if (!target) {
52
+ continue;
53
+ }
54
+ if (target.edges.prev !== qid) {
55
+ pushError(errors, `${qid}: next ${edges.next} missing matching prev`);
56
+ }
57
+ }
58
+ if (edges.prev) {
59
+ const target = nodes[edges.prev];
60
+ if (!target) {
61
+ continue;
62
+ }
63
+ if (target.edges.next !== qid) {
64
+ pushError(errors, `${qid}: prev ${edges.prev} missing matching next`);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ function detectPrevNextCycles(index, errors) {
70
+ const nodes = index.nodes;
71
+ const seen = new Set();
72
+ for (const start of Object.keys(nodes)) {
73
+ if (seen.has(start)) {
74
+ continue;
75
+ }
76
+ const path = new Map();
77
+ let current = start;
78
+ while (current) {
79
+ if (seen.has(current)) {
80
+ break;
81
+ }
82
+ if (path.has(current)) {
83
+ const entries = Array.from(path.keys());
84
+ const cycleStart = path.get(current) ?? 0;
85
+ const cycle = entries.slice(cycleStart);
86
+ cycle.push(current);
87
+ pushError(errors, `cycle detected in prev/next chain: ${cycle.join(" -> ")}`);
88
+ break;
89
+ }
90
+ path.set(current, path.size);
91
+ const nextQid = nodes[current]?.edges.next;
92
+ if (!nextQid || !nodes[nextQid]) {
93
+ break;
94
+ }
95
+ current = nextQid;
96
+ }
97
+ for (const visited of path.keys()) {
98
+ seen.add(visited);
99
+ }
100
+ }
101
+ }
102
+ function collectGraphErrors(index, options = {}) {
103
+ const errors = [];
104
+ const allowMissing = options.allowMissing ?? false;
105
+ validateEdgeTargets(index, allowMissing, errors);
106
+ validatePrevNextSymmetry(index, allowMissing, errors);
107
+ detectPrevNextCycles(index, errors);
108
+ return errors;
109
+ }
110
+ function validateGraph(index, options = {}) {
111
+ const errors = collectGraphErrors(index, options);
112
+ if (errors.length > 0) {
113
+ throw new Error(errors[0]);
114
+ }
115
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getWorkspaceDocRoots = getWorkspaceDocRoots;
7
+ exports.listWorkspaceDocFiles = listWorkspaceDocFiles;
8
+ exports.listWorkspaceDocFilesByAlias = listWorkspaceDocFilesByAlias;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const DOC_FOLDERS = ["core", "design", "work"];
12
+ function listMarkdownFiles(dir) {
13
+ if (!fs_1.default.existsSync(dir)) {
14
+ return [];
15
+ }
16
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
17
+ const files = [];
18
+ for (const entry of entries) {
19
+ const fullPath = path_1.default.join(dir, entry.name);
20
+ if (entry.isDirectory()) {
21
+ files.push(...listMarkdownFiles(fullPath));
22
+ }
23
+ else if (entry.isFile() && entry.name.endsWith(".md")) {
24
+ files.push(fullPath);
25
+ }
26
+ }
27
+ return files;
28
+ }
29
+ function getWorkspaceDocRoots(root, config) {
30
+ const roots = [];
31
+ const aliases = Object.keys(config.workspaces).sort();
32
+ for (const alias of aliases) {
33
+ const entry = config.workspaces[alias];
34
+ if (!entry.enabled) {
35
+ continue;
36
+ }
37
+ const wsRoot = path_1.default.resolve(root, entry.path, entry.mdkg_dir);
38
+ roots.push({ alias, root: wsRoot });
39
+ }
40
+ return roots;
41
+ }
42
+ function listWorkspaceDocFiles(root, config) {
43
+ const files = [];
44
+ for (const { root: wsRoot } of getWorkspaceDocRoots(root, config)) {
45
+ for (const folder of DOC_FOLDERS) {
46
+ const folderPath = path_1.default.join(wsRoot, folder);
47
+ files.push(...listMarkdownFiles(folderPath));
48
+ }
49
+ }
50
+ return files;
51
+ }
52
+ function listWorkspaceDocFilesByAlias(root, config) {
53
+ const result = {};
54
+ for (const { alias, root: wsRoot } of getWorkspaceDocRoots(root, config)) {
55
+ const files = [];
56
+ for (const folder of DOC_FOLDERS) {
57
+ const folderPath = path_1.default.join(wsRoot, folder);
58
+ files.push(...listMarkdownFiles(folderPath));
59
+ }
60
+ files.sort();
61
+ result[alias] = files;
62
+ }
63
+ return result;
64
+ }
@@ -0,0 +1,43 @@
1
+ # Agent Guidelines
2
+
3
+ This repo uses mdkg for tasks, decisions, and context packs.
4
+
5
+ ## Quickstart
6
+
7
+ - `mdkg init --llm`
8
+ - `mdkg index`
9
+ - `mdkg new task "..." --status todo --priority 1`
10
+ - `mdkg list --status todo`
11
+ - `mdkg pack <id> --verbose`
12
+ - `mdkg validate`
13
+
14
+ ## Core commands
15
+
16
+ - `mdkg init` (scaffold .mdkg and optional agent docs)
17
+ - `mdkg guide` (print the repo guide)
18
+ - `mdkg new <type> "<title>"` (create nodes)
19
+ - `mdkg list` / `mdkg show` / `mdkg search`
20
+ - `mdkg pack` (context bundles)
21
+ - `mdkg next` (priority/chain)
22
+ - `mdkg validate` / `mdkg format`
23
+
24
+ ## Getting context
25
+
26
+ - Run `mdkg list --status todo` to find work items.
27
+ - Before coding, run `mdkg pack <task-id> --verbose`.
28
+ - Read linked rules and decisions in the pack.
29
+
30
+ ## Editing rules
31
+
32
+ - Keep frontmatter valid and lowercase.
33
+ - Update `updated: YYYY-MM-DD` when you make changes.
34
+ - Use `links:` and `artifacts:` for anything you want searchable.
35
+
36
+ ## Validation
37
+
38
+ - Run `mdkg validate` after edits.
39
+ - Run `mdkg format` if frontmatter drifts.
40
+
41
+ ## Project-specific notes
42
+
43
+ Add repo-specific build/test commands and conventions here.
@@ -0,0 +1,37 @@
1
+ # Claude Instructions
2
+
3
+ This project uses mdkg to manage tasks and context.
4
+
5
+ ## Quickstart
6
+
7
+ - `mdkg init --llm`
8
+ - `mdkg index`
9
+ - `mdkg new task "..." --status todo --priority 1`
10
+ - `mdkg list --status todo`
11
+ - `mdkg pack <id> --verbose`
12
+ - `mdkg validate`
13
+
14
+ ## Core commands
15
+
16
+ - `mdkg init` (scaffold .mdkg and optional agent docs)
17
+ - `mdkg guide` (print the repo guide)
18
+ - `mdkg new <type> "<title>"` (create nodes)
19
+ - `mdkg list` / `mdkg show` / `mdkg search`
20
+ - `mdkg pack` (context bundles)
21
+ - `mdkg next` (priority/chain)
22
+ - `mdkg validate` / `mdkg format`
23
+
24
+ ## Before making changes
25
+
26
+ - Run `mdkg pack <task-id> --verbose`.
27
+ - Follow linked rules and decisions.
28
+
29
+ ## After making changes
30
+
31
+ - Update frontmatter fields and `updated: YYYY-MM-DD`.
32
+ - Run `mdkg validate` and fix any errors.
33
+ - If frontmatter is inconsistent, run `mdkg format`.
34
+
35
+ ## Repo-specific notes
36
+
37
+ Add build, test, and release instructions here.
@@ -0,0 +1,67 @@
1
+ {
2
+ "schema_version": 1,
3
+ "tool": "mdkg",
4
+ "root_required": true,
5
+ "index": {
6
+ "auto_reindex": true,
7
+ "tolerant": false,
8
+ "global_index_path": ".mdkg/index/global.json"
9
+ },
10
+ "pack": {
11
+ "default_depth": 2,
12
+ "default_edges": [
13
+ "parent",
14
+ "epic",
15
+ "relates"
16
+ ],
17
+ "verbose_core_list_path": ".mdkg/core/core.md",
18
+ "limits": {
19
+ "max_nodes": 25,
20
+ "max_bytes": 2000000
21
+ }
22
+ },
23
+ "templates": {
24
+ "root_path": ".mdkg/templates",
25
+ "default_set": "default",
26
+ "workspace_overrides_enabled": false
27
+ },
28
+ "work": {
29
+ "status_enum": [
30
+ "backlog",
31
+ "blocked",
32
+ "todo",
33
+ "progress",
34
+ "review",
35
+ "done"
36
+ ],
37
+ "priority_min": 0,
38
+ "priority_max": 9,
39
+ "next": {
40
+ "strategy": "chain_then_priority",
41
+ "status_preference": [
42
+ "progress",
43
+ "todo",
44
+ "review",
45
+ "blocked",
46
+ "backlog"
47
+ ]
48
+ }
49
+ },
50
+ "workspaces": {
51
+ "root": {
52
+ "path": ".",
53
+ "enabled": true,
54
+ "mdkg_dir": ".mdkg"
55
+ },
56
+ "polish": {
57
+ "path": "polish",
58
+ "enabled": true,
59
+ "mdkg_dir": ".mdkg"
60
+ },
61
+ "smoke": {
62
+ "path": "smoke",
63
+ "enabled": true,
64
+ "mdkg_dir": ".mdkg"
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,12 @@
1
+ # mdkg verbose core list
2
+
3
+ # One node ID per line. Lines starting with # are comments.
4
+ # This list is included by `mdkg pack --verbose`.
5
+
6
+ rule-1
7
+ rule-2
8
+ rule-3
9
+ rule-4
10
+ rule-5
11
+ rule-6
12
+ rule-guide
@@ -0,0 +1,99 @@
1
+ ---
2
+ id: rule-guide
3
+ type: rule
4
+ title: agent guide (how to work in this repo using mdkg)
5
+ tags: [agents, mdkg, workflow]
6
+ owners: []
7
+ links: []
8
+ artifacts: []
9
+ relates: []
10
+ refs: []
11
+ aliases: []
12
+ created: 2026-01-06
13
+ updated: 2026-01-22
14
+ ---
15
+
16
+ # Agent guide
17
+
18
+ This repo uses **mdkg** to manage documentation, decisions, and work tracking.
19
+
20
+ ## Quickstart
21
+
22
+ - `mdkg init --llm`
23
+ - `mdkg index`
24
+ - `mdkg new task "..." --status todo --priority 1`
25
+ - `mdkg list --status todo`
26
+ - `mdkg pack <id> --verbose`
27
+ - `mdkg validate`
28
+
29
+ ## Core commands
30
+
31
+ - `mdkg init` (scaffold .mdkg and optional agent docs)
32
+ - `mdkg guide` (print this guide)
33
+ - `mdkg new <type> "<title>"`
34
+ - `mdkg list` / `mdkg show` / `mdkg search`
35
+ - `mdkg pack`
36
+ - `mdkg next`
37
+ - `mdkg validate` / `mdkg format`
38
+
39
+ ## Always start with a pack
40
+
41
+ Before coding, generate a context pack for the task you’re working on:
42
+
43
+ - `mdkg pack <task-id> --verbose`
44
+
45
+ Read:
46
+ - the task
47
+ - linked design docs (edd/prd)
48
+ - decision records (dec)
49
+ - rules (rule)
50
+
51
+ Do not begin implementation without understanding constraints in rules and decisions.
52
+
53
+ ## Keep frontmatter valid and searchable
54
+
55
+ Frontmatter must remain strictly valid or indexing/search breaks.
56
+
57
+ - do not introduce multiline values
58
+ - do not introduce nested objects
59
+ - keep keys lowercase
60
+ - keep IDs lowercase
61
+ - keep `links: [...]` and `artifacts: [...]` in frontmatter for anything you want searchable
62
+ - keep graph fields (`epic`, `parent`, `relates`, `blocked_by`, `blocks`, `prev`, `next`) accurate
63
+
64
+ ## Update the right fields
65
+
66
+ When you make a meaningful edit:
67
+ - update the node’s `updated: YYYY-MM-DD`
68
+ - update status and priority as needed
69
+
70
+ ## Work item discipline
71
+
72
+ - Use `prev/next` to define an explicit “immediate next” chain when the workflow is linear.
73
+ - Use `priority: 0..9` for triage and non-linear backlogs.
74
+ - Keep `status` accurate.
75
+
76
+ ## Use checkpoints to compress phases
77
+
78
+ After completing a meaningful phase:
79
+ - create a `chk-*` node summarizing work, verification, and links.
80
+ - link it to the epic or relevant tasks.
81
+ - optionally include a `scope` list of the nodes covered.
82
+
83
+ Checkpoints reduce context sprawl and improve future packs.
84
+
85
+ ## Validate frequently
86
+
87
+ After making changes:
88
+ - run `mdkg validate`
89
+
90
+ If formatting drift is common (especially with agent edits):
91
+ - run `mdkg format` before committing.
92
+
93
+ ## Indexing behavior
94
+
95
+ Index is cached by default and auto-reindexed when stale.
96
+
97
+ If debugging index issues:
98
+ - run `mdkg index`
99
+ - inspect errors from strict frontmatter enforcement
@@ -0,0 +1,232 @@
1
+ ---
2
+ id: rule-1
3
+ type: rule
4
+ title: mdkg conventions (naming, ids, frontmatter, status, priority, templates)
5
+ tags: [conventions, mdkg, spec]
6
+ owners: []
7
+ links: []
8
+ artifacts: []
9
+ relates: []
10
+ refs: []
11
+ aliases: []
12
+ created: 2026-01-06
13
+ updated: 2026-01-22
14
+ ---
15
+
16
+ # mdkg conventions
17
+
18
+ This rule defines the file-first conventions for a local Markdown knowledge graph managed by **mdkg**.
19
+
20
+ ## Principles
21
+
22
+ - Markdown files are the source of truth.
23
+ - Identity is the `id` in frontmatter, not the path or filename.
24
+ - Graph edges are explicit in frontmatter and reference IDs.
25
+ - Anything that must be searchable (external URLs, refs, artifacts) should be stored in frontmatter.
26
+ - Document bodies are for narrative detail; frontmatter is for indexing and graph structure.
27
+ - Everything is lowercase on disk (IDs, types, filenames, enums).
28
+ - The CLI may accept any case but MUST normalize to lowercase before processing.
29
+ - Frontmatter must be strict and valid (or the graph breaks).
30
+ - Body structure is template-guided and flexible (warnings, not hard failures).
31
+ - Templates are global (root-only) in v1.
32
+
33
+ ## Root-only operation
34
+
35
+ mdkg commands are intended to run at the repo root.
36
+
37
+ - Root is defined by `./.mdkg/config.json`.
38
+ - No directory-walking “workspace discovery” at runtime.
39
+ - Workspaces are explicitly registered in `.mdkg/config.json`.
40
+
41
+ ## Workspaces
42
+
43
+ A workspace is a registered project area (usually a subdirectory). Workspace docs live near code:
44
+
45
+ - `<workspace>/.mdkg/`
46
+
47
+ Workspaces are indexed by the root indexer according to `.mdkg/config.json`.
48
+
49
+ Qualified IDs exist for global uniqueness in the index:
50
+
51
+ - `qid = <workspace_alias>:<id>`
52
+ - example: `root:task-1`, `e2e:bug-3`
53
+
54
+ Local IDs remain unqualified in files.
55
+
56
+ ## File naming
57
+
58
+ Canonical filename format:
59
+
60
+ `<prefix>-<number>-<slug>.md`
61
+
62
+ Rules:
63
+ - `<prefix>` MUST be lowercase.
64
+ - `<number>` MUST be an integer with no zero padding.
65
+ - `<slug>` SHOULD be lowercase kebab-case.
66
+ - Renames are allowed; identity remains stable via frontmatter `id`.
67
+
68
+ ## Node types and prefixes
69
+
70
+ Design + core:
71
+ - `rule-*` — rules and conventions
72
+ - `prd-*` — product requirements document
73
+ - `edd-*` — engineering design document
74
+ - `dec-*` — decision record (generic, not only architecture)
75
+ - `prop-*` — proposal (early-stage)
76
+
77
+ Work:
78
+ - `epic-*`
79
+ - `feat-*` (optional)
80
+ - `task-*`
81
+ - `bug-*`
82
+ - `chk-*` — checkpoint (phase summary / compression node)
83
+
84
+ ## IDs
85
+
86
+ Canonical ID format:
87
+
88
+ `<prefix>-<number>`
89
+
90
+ Examples:
91
+ - `task-183`
92
+ - `edd-14`
93
+ - `dec-3`
94
+ - `chk-1`
95
+
96
+ IDs MUST be lowercase and unique within a workspace. Global uniqueness is achieved via qualified IDs in the global index.
97
+
98
+ ## Status
99
+
100
+ Work items store status in frontmatter only (no status directories).
101
+
102
+ Work status enum:
103
+ - `backlog`
104
+ - `blocked`
105
+ - `todo`
106
+ - `progress`
107
+ - `review`
108
+ - `done`
109
+
110
+ ## Priority
111
+
112
+ Work items MAY include:
113
+
114
+ - `priority: 0..9`
115
+
116
+ Meaning:
117
+ - `0` = breaking / urgent (must be addressed immediately)
118
+ - `9` = later / lowest urgency
119
+
120
+ Priority is used as a default ranking when no explicit `prev/next` chain is present.
121
+
122
+ ## Frontmatter (restricted subset)
123
+
124
+ Frontmatter MUST be the first lines of the file:
125
+
126
+ - begins with `---`
127
+ - ends with the next `---`
128
+
129
+ Allowed forms per line:
130
+
131
+ `key: value`
132
+
133
+ Keys:
134
+ - lowercase snake_case: `[a-z][a-z0-9_]*`
135
+
136
+ Values:
137
+ - string (rest of line)
138
+ - boolean: `true` / `false`
139
+ - list: `[a, b, c]` (comma-separated; items trimmed)
140
+ - empty lists SHOULD be written as `[]` for list fields
141
+
142
+ Disallowed:
143
+ - nested maps
144
+ - multiline values
145
+ - duplicate keys
146
+
147
+ ## Required fields
148
+
149
+ All nodes MUST include:
150
+ - `id`
151
+ - `type`
152
+ - `title`
153
+ - `created` (YYYY-MM-DD)
154
+ - `updated` (YYYY-MM-DD)
155
+
156
+ Work items (`epic/feat/task/bug/chk/test`) MUST include:
157
+ - `status`
158
+
159
+ Work items MAY include:
160
+ - `priority`
161
+
162
+ Optional searchable metadata
163
+
164
+ All nodes MAY include:
165
+ - `tags: [a, b, c]`
166
+ - `owners: [a, b, c]`
167
+ - `links: [ref, ref]` (any searchable reference string; may include URLs)
168
+ - `artifacts: [ref, ref]` (build outputs, releases, commits, PRs, tarballs, etc.)
169
+ - `refs: [id, id]` (non-edge references to other nodes)
170
+ - `aliases: [text, text]` (extra searchable terms)
171
+
172
+ `dec-*` MUST include:
173
+ - `status: proposed|accepted|rejected|superseded`
174
+
175
+ ## Graph edges
176
+
177
+ Edges reference IDs (or qualified IDs when cross-workspace).
178
+
179
+ Supported edge keys:
180
+ - `epic: epic-#`
181
+ - `parent: feat-#`
182
+ - `relates: [id, id]`
183
+ - `refs: [id, id]` (non-edge references; searchable but not traversed by default)
184
+ - `blocked_by: [id, id]`
185
+ - `blocks: [id, id]`
186
+ - `prev: id`
187
+ - `next: id`
188
+
189
+ Notes:
190
+ - Reverse relationships (e.g., “children of epic”) are derived by indexing.
191
+ - `prev/next` SHOULD be used for explicit “immediate next” flows.
192
+ - Priority SHOULD be used for triage when chain is absent or incomplete.
193
+
194
+ ## Templates
195
+
196
+ Templates are global in v1 and live at:
197
+
198
+ - `.mdkg/templates/<set>/<type>.md`
199
+
200
+ Template sets (recommended):
201
+ - `default`
202
+ - `minimal`
203
+ - `verbose`
204
+
205
+ Templates are filled by token substitution (no template engine dependency). Optional scalar fields (like `epic`, `parent`, `prev`, `next`) should be omitted when empty; list fields should default to `[]`.
206
+
207
+ Body headings are guidance only. Frontmatter is strictly validated.
208
+
209
+ ## Checkpoints
210
+
211
+ Checkpoints (`chk-*`) are first-class nodes used to summarize completed phases and compress context.
212
+
213
+ They SHOULD include:
214
+ - a summary of outcomes
215
+ - verification/testing notes
216
+ - key decisions referenced
217
+ - searchable links and artifacts in frontmatter (see `links` and `artifacts`)
218
+ - a `scope` list in frontmatter when possible (IDs covered)
219
+
220
+ ## Index and cache
221
+
222
+ The cache is enabled by default.
223
+
224
+ - Root global index lives at `.mdkg/index/global.json`
225
+ - Index is rebuilt automatically when stale unless disabled by flag/config.
226
+ - `.mdkg/index/` is generated and MUST be gitignored.
227
+
228
+ ## Safety guidance (high level)
229
+
230
+ mdkg content may include sensitive notes. Ensure production artifacts don’t include `.mdkg/`:
231
+ - prefer publishing only `dist/` via package.json `files`
232
+ - consider `.npmignore` / `.dockerignore` excludes