mdkg 0.3.1 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -12,6 +12,52 @@ mdkg is pre-v1 public alpha software. Command, graph, cache, bundle, and DAL con
12
12
 
13
13
  - No changes yet.
14
14
 
15
+ ## 0.3.2 - 2026-06-16
16
+
17
+ ### Added
18
+
19
+ - Added first-class research spike work-node support with `mdkg new spike`,
20
+ `spike-#` ids, `.mdkg/work/` storage, and compatibility with existing
21
+ `mdkg task start/update/done` lifecycle commands.
22
+ - Added spike participation in `mdkg next`, `mdkg goal next`, `mdkg goal claim`,
23
+ list/search/show structured exports, deterministic packs, goal-root pack
24
+ closure, and generated command contract metadata.
25
+ - Added a default spike template for research question, context, search plan,
26
+ findings, options/tradeoffs, recommendation, follow-up nodes, skill
27
+ candidates, domain notes, mdkg.dev launch implications, and evidence/sources.
28
+ - Added packed `smoke:spike` coverage that installs mdkg from a tarball in a
29
+ temp prefix, creates a fresh repo, exercises spike lifecycle and goal routing,
30
+ verifies structured exports and pack formats, creates follow-up task/test
31
+ nodes, and confirms no automatic skill generation occurs.
32
+ - Added mdkg.dev dogfood research spike nodes and follow-up roadmap nodes so
33
+ launch planning can proceed from evidence-backed spikes after this release.
34
+
35
+ ### Changed
36
+
37
+ - Updated README, `CLI_COMMAND_MATRIX.md`, init assets, help text, command docs,
38
+ and publish-readiness assertions to describe spikes as actionable research
39
+ work nodes, not autonomous web-search or file-generation agents.
40
+ - Hardened init and upgrade compatibility so fresh and upgraded repos receive
41
+ the bundled spike template while customized spike templates are preserved.
42
+ - Hardened spike pack/export behavior across JSON, Markdown, XML, and toon
43
+ pack formats plus public visibility filtering for spike archive references.
44
+ - Hardened validation and fix-plan UX for malformed spikes: invalid ids,
45
+ statuses, priorities, missing refs, duplicate spike ids, and missing spike
46
+ body sections now have explicit test coverage and read-only repair guidance
47
+ where existing fix-plan families apply.
48
+ - Extended `mdkg fix plan refs` to inspect indexed `links`, `artifacts`, and
49
+ `refs` fields in addition to custom attributes, so missing archive refs in
50
+ normal node metadata appear in repair plans.
51
+
52
+ ### Security
53
+
54
+ - Kept spikes as human/agent-authored Markdown work nodes only. This release
55
+ does not add a `mdkg spike ...` namespace, automatic web search, automatic
56
+ follow-up node creation, automatic `SKILL.md` generation, or repair apply
57
+ behavior.
58
+ - Preserved dry-run-only repair planning: spike-related fix guidance remains
59
+ receipt-shaped, non-mutating, and `apply_supported: false`.
60
+
15
61
  ## 0.3.1 - 2026-06-11
16
62
 
17
63
  ### Added
@@ -1,7 +1,7 @@
1
1
  # CLI Command Matrix
2
2
 
3
3
  as_of: 2026-06-06
4
- package_version_in_source: 0.2.0
4
+ package_version_in_source: 0.3.1
5
5
  source: live help from `src/cli.ts`, runtime command handlers, and `dec-15`..`dec-18`
6
6
  status: canonical single-source command and flag reference for mdkg
7
7
 
@@ -101,6 +101,7 @@ Notes:
101
101
  - removed flags `--llm`, `--agents`, `--claude`, and `--omni` fail before mutation with guidance to use `mdkg init --agent`
102
102
  - published bootstrap config is root-only by default
103
103
  - `--agent` creates `AGENT_START.md`, `AGENTS.md`, `CLAUDE.md`, `llms.txt`, `CLI_COMMAND_MATRIX.md`, strict-node core docs, default mdkg usage skills, `events.jsonl`, registry, and skill mirrors
104
+ - run `mdkg index` after fresh init before treating `mdkg doctor --strict --json` as a clean health gate; init writes source scaffold files and index writes generated caches
104
105
 
105
106
  ### `mdkg upgrade`
106
107
 
@@ -145,6 +146,7 @@ Types:
145
146
  - `feat`
146
147
  - `task`
147
148
  - `bug`
149
+ - `spike`
148
150
  - `checkpoint`
149
151
  - `test`
150
152
 
@@ -169,6 +171,16 @@ Agent workflow file type creation:
169
171
  Goal node creation:
170
172
  - `mdkg new goal "<title>" [options] [--json]`
171
173
 
174
+ Spike node creation:
175
+ - `mdkg new spike "<research question>" [options] [--json]`
176
+ - spikes are actionable research/planning work nodes under `.mdkg/work/`
177
+ - use `mdkg task start|update|done <spike-id>` for lifecycle state
178
+ - spikes record research, sources, recommendations, follow-up node ideas, and
179
+ skill candidates in Markdown body sections
180
+ - spikes do not perform web search, execute research, create follow-up nodes,
181
+ or generate `SKILL.md` files automatically
182
+ - no `mdkg spike ...` namespace is exposed in this release
183
+
172
184
  Primary flags:
173
185
  - `--id <portable-id>` agent workflow file types only
174
186
  - `--ws <alias>`
@@ -500,7 +512,7 @@ Notes:
500
512
  - records include deterministic source metadata such as workspace, visibility, kind, id/qid/slug, path, headings, refs, source hash, and `indexed_at`
501
513
  - SPEC and WORK capability records include read-only `linkage` arrays for related SPECs, work contracts, work orders, and receipts when those graph mirrors exist
502
514
  - `.mdkg/index/capabilities.json` is rebuilt by `mdkg index` and by capability commands when stale
503
- - normal task, epic, feat, bug, test, and checkpoint nodes are intentionally excluded
515
+ - normal task, epic, feat, bug, test, spike, and checkpoint nodes are intentionally excluded
504
516
  - visibility is mdkg export metadata used by capability filters, `pack --visibility`, public bundle checks, validation, and doctor diagnostics; it is not secret scanning or body redaction
505
517
 
506
518
  ### `mdkg spec`
@@ -745,7 +757,7 @@ Behavior:
745
757
  - `goal select` writes local ignored selected-goal state so `goal next` can omit the goal id.
746
758
  - `goal current` shows the selected goal or unique active goal fallback.
747
759
  - `goal clear` removes local selected-goal state.
748
- - `goal next` is read-only and selects feature, task, bug, or test work inside explicit `scope_refs`; epics are recursive containers, not executable returns.
760
+ - `goal next` is read-only and selects feature, task, bug, test, or spike work inside explicit `scope_refs`; epics are recursive containers, not executable returns.
749
761
  - `goal claim` mutates only `active_node` after the work item is confirmed inside the goal scope.
750
762
  - `goal evaluate` is report-only and never runs commands from `required_checks`.
751
763
  - `goal pause`, `goal resume`, and `goal done` update `goal_state`, compatible work status, and `updated`.
@@ -779,7 +791,7 @@ Usage:
779
791
  - `mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"] [--json]`
780
792
 
781
793
  Behavior:
782
- - supports `task`, `bug`, and `test` only
794
+ - supports task-like `feat`, `task`, `bug`, `test`, and `spike` nodes
783
795
  - sets `status: progress`
784
796
  - if `events.jsonl` is missing for the workspace, prints a short `stderr` reminder about `mdkg event enable`
785
797
 
@@ -795,7 +807,7 @@ Usage:
795
807
  - ` [--clear-blocked-by] [--run-id <id>] [--note "<text>"] [--json]`
796
808
 
797
809
  Behavior:
798
- - supports `task`, `bug`, and `test` only
810
+ - supports task-like `feat`, `task`, `bug`, `test`, and `spike` nodes
799
811
  - list mutations are additive and unique
800
812
  - scalar fields replace existing values
801
813
  - `--clear-blocked-by` clears blockers before optional re-add
@@ -810,7 +822,7 @@ Usage:
810
822
  - ` [--add-refs <id,...>] [--checkpoint "<title>"] [--run-id <id>] [--note "<text>"] [--json]`
811
823
 
812
824
  Behavior:
813
- - supports `task`, `bug`, and `test` only
825
+ - supports task-like `feat`, `task`, `bug`, `test`, and `spike` nodes
814
826
  - sets `status: done`
815
827
  - `--checkpoint` creates a related checkpoint
816
828
  - if `events.jsonl` is missing for the workspace, prints a short `stderr` reminder about `mdkg event enable`
package/README.md CHANGED
@@ -14,7 +14,7 @@ mdkg stays deliberately boring:
14
14
  - first-class rebuildable SQLite cache through built-in `node:sqlite`
15
15
  - no daemon, hosted index, or vector DB
16
16
 
17
- Current package version in source: `0.2.0`
17
+ Current package version in source: `0.3.1`
18
18
 
19
19
  mdkg is still pre-v1 public alpha software. The public package is usable, but graph, cache, bundle, and DAL contracts may continue to change quickly while the project converges on a stable v1 surface.
20
20
 
@@ -48,10 +48,16 @@ Initialize mdkg in a repo:
48
48
 
49
49
  ```bash
50
50
  mdkg init --agent
51
+ mdkg index
51
52
  ```
52
53
 
53
54
  This is the canonical AI-agent bootstrap path. It creates `.mdkg/`, `AGENT_START.md`, `AGENTS.md`, `CLAUDE.md`, `llms.txt`, `CLI_COMMAND_MATRIX.md`, strict-node `SOUL.md` / `HUMAN.md`, the three default mdkg usage skills, `events.jsonl`, the skill registry, core pin updates, and mirrored skill folders under `.agents/skills/` and `.claude/skills/`. It also updates `.gitignore` / `.npmignore` by default. Use `--no-update-ignores` to opt out of those ignore-file updates.
54
55
 
56
+ Run `mdkg index` after a fresh init before using `mdkg status --json` or
57
+ `mdkg doctor --strict --json` as health gates. Init writes source scaffold
58
+ files; indexing creates the generated graph, skill, capability, subgraph, and
59
+ SQLite caches that strict doctor expects.
60
+
55
61
  For a non-agent markdown graph only, run `mdkg init`.
56
62
 
57
63
  Preview safe scaffold upgrades in an existing mdkg workspace:
@@ -86,7 +92,28 @@ mdkg goal next goal-1
86
92
  mdkg goal evaluate goal-1 --json
87
93
  ```
88
94
 
89
- Goal nodes capture a measurable end condition, recursive loop state, required skills, required checks, and completion evidence. They guide agent harnesses through repeated graph-backed progress, while tasks, bugs, tests, and features remain the concrete executable work units. In this release `mdkg goal evaluate` is report-only: it lists required checks and evidence state, but does not execute scripts.
95
+ Goal nodes capture a measurable end condition, recursive loop state, required skills, required checks, and completion evidence. They guide agent harnesses through repeated graph-backed progress, while tasks, bugs, tests, spikes, and features remain the concrete executable work units. In this release `mdkg goal evaluate` is report-only: it lists required checks and evidence state, but does not execute scripts.
96
+
97
+ Create a research spike when the next useful work is investigation, planning,
98
+ or grounding a future implementation:
99
+
100
+ ```bash
101
+ mdkg new spike "research mdkg.dev launch guide" --status todo --priority 1
102
+ mdkg task start spike-1
103
+ mdkg show spike-1
104
+ ```
105
+
106
+ Spikes are task-like work nodes, not autonomous research agents. mdkg does not
107
+ perform web search, execute research, create follow-up nodes, or generate
108
+ `SKILL.md` files automatically. Record sources, findings, tradeoffs,
109
+ recommendations, follow-up node ideas, and skill candidates in the spike body,
110
+ then create follow-up work intentionally:
111
+
112
+ ```bash
113
+ mdkg new task "write mdkg.dev quickstart guide" --parent spike-1 --status todo --priority 1
114
+ mdkg new test "validate mdkg.dev docs examples" --parent spike-1 --status todo --priority 1
115
+ mdkg new task "author mdkg.dev launch planning skill" --parent spike-1 --status todo --priority 2
116
+ ```
90
117
 
91
118
  Create an agent workflow document with a semantic portable id:
92
119
 
@@ -250,7 +277,7 @@ The root docs below are the canonical fast-start set for humans and agents:
250
277
  mdkg lives under a hidden root directory:
251
278
  - `.mdkg/core/` rules and pinned docs
252
279
  - `.mdkg/design/` product, design, and decision docs
253
- - `.mdkg/work/` tasks, bugs, tests, epics, checkpoints
280
+ - `.mdkg/work/` tasks, bugs, tests, spikes, epics, checkpoints
254
281
  - `.mdkg/templates/` templates used by `mdkg new`
255
282
  - `.mdkg/skills/` Agent Skills packages
256
283
  - `.mdkg/archive/` sidecar metadata plus deterministic compressed source/artifact caches
@@ -434,12 +461,35 @@ as sealed state.
434
461
 
435
462
  Goal nodes are durable recursive objective contracts. Use `mdkg new goal "<objective>"` when a human or agent needs to keep working across multiple concrete nodes until a measurable end condition is achieved.
436
463
 
437
- `goal` is work-like but distinct from `task`: it can have status, priority, graph links, skills, explicit `scope_refs`, and structured goal fields, but normal `mdkg next` does not select goals. Use `mdkg goal select <goal-id>` once, then `mdkg goal next` to choose the next local feature, task, bug, or test inside that goal. `mdkg goal next <goal-id>` remains available for explicit selection. Epics organize goal scope recursively but are not returned as executable work.
464
+ `goal` is work-like but distinct from `task`: it can have status, priority, graph links, skills, explicit `scope_refs`, and structured goal fields, but normal `mdkg next` does not select goals. Use `mdkg goal select <goal-id>` once, then `mdkg goal next` to choose the next local feature, task, bug, test, or spike inside that goal. `mdkg goal next <goal-id>` remains available for explicit selection. Epics organize goal scope recursively but are not returned as executable work.
438
465
 
439
466
  Use `mdkg goal claim [goal-id] <work-id>` to durably set `active_node` after choosing the next scoped item. `goal next` is read-only. Use `mdkg goal pause|resume|done` to update goal state after review.
440
467
 
441
468
  Required checks are stored as report-only guidance. Agents should run the checks themselves, record evidence in the goal or active work item, then use `mdkg goal evaluate` to summarize the current evidence state. During normal goal execution, skill improvements should be recorded as improvement candidates or proposal nodes; edit `SKILL.md` files only when the active node is explicit skill-maintenance work.
442
469
 
470
+ ## Research spikes
471
+
472
+ Spikes are first-class actionable work nodes for research and planning. Use
473
+ `mdkg new spike "<question>"` when the right output is a documented
474
+ recommendation, not code. They share the existing task lifecycle:
475
+
476
+ ```bash
477
+ mdkg new spike "research queue-backed materializer UX" --status todo --priority 1
478
+ mdkg task start spike-1
479
+ mdkg task update spike-1 --status review --add-refs task-250
480
+ mdkg task done spike-1
481
+ ```
482
+
483
+ The default spike template includes sections for research question, context,
484
+ search plan, findings, options and tradeoffs, recommendation, follow-up nodes,
485
+ skill candidates, data-structure and algorithm notes, UX notes, security notes,
486
+ mdkg.dev launch implications, and evidence/sources.
487
+
488
+ Spikes deliberately do not expose a `mdkg spike ...` namespace in this release,
489
+ do not run browser or web-search tools, do not create tasks/tests/goals, and do
490
+ not write `SKILL.md` files. They make the research output reviewable so humans
491
+ or agents can intentionally create the next nodes with normal mdkg commands.
492
+
443
493
  ## Agent workflow files
444
494
 
445
495
  mdkg recognizes a small set of canonical agent workflow documents:
package/dist/cli.js CHANGED
@@ -136,7 +136,7 @@ function printNewHelp(log) {
136
136
  log("Usage:");
137
137
  log(' mdkg new <type> "<title>" [options] [--json]');
138
138
  log("\nTypes:");
139
- log(" rule prd edd dec prop goal epic feat task bug checkpoint test");
139
+ log(" rule prd edd dec prop goal epic feat task bug spike checkpoint test");
140
140
  log("\nAgent workflow file types:");
141
141
  log(" spec work work_order receipt feedback dispute proposal");
142
142
  log(" Use --id <portable-id> with these types for semantic ids like agent.image-worker.");
@@ -157,6 +157,9 @@ function printNewHelp(log) {
157
157
  log(" --owners <owner,owner,...> Owners");
158
158
  log("\nNotes:");
159
159
  log(" spec/work scaffold as validation-clean docs; relational workflow docs need real refs.");
160
+ log(" spike creates actionable research/planning work; use `mdkg task ...` for lifecycle.");
161
+ log(" record spike research evidence by editing the Markdown body sections.");
162
+ log(" spikes do not run web search, create follow-up nodes, generate SKILL.md, or expose `mdkg spike ...`.");
160
163
  printGlobalOptions(log);
161
164
  }
162
165
  function printGuideHelp(log) {
@@ -690,7 +693,7 @@ function printTaskHelp(log, subcommand) {
690
693
  log("Usage:");
691
694
  log(' mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"] [--json]');
692
695
  log("\nWhen to use:");
693
- log(" Move a task, bug, or test into progress as a structured state change.");
696
+ log(" Move a task-like node (feat, task, bug, test, or spike) into progress as a structured state change.");
694
697
  log(" If `events.jsonl` is missing, mdkg prints a short reminder about `mdkg event enable`.");
695
698
  printGlobalOptions(log);
696
699
  return;
@@ -719,7 +722,8 @@ function printTaskHelp(log, subcommand) {
719
722
  log(" mdkg task update <id-or-qid> [options] [--json]");
720
723
  log(' mdkg task done <id-or-qid> [--checkpoint "<title>"] [options] [--json]');
721
724
  log("\nNotes:");
722
- log(" `mdkg task ...` only supports feat, task, bug, and test nodes.");
725
+ log(" `mdkg task ...` only supports feat, task, bug, test, and spike nodes.");
726
+ log(" Spikes use this lifecycle; there is no separate `mdkg spike ...` command family.");
723
727
  log(" Feat and epic closeout remain checkpoint-first guidance plus manual parent updates.");
724
728
  printGlobalOptions(log);
725
729
  }
@@ -737,7 +741,7 @@ function printGoalHelp(log, subcommand) {
737
741
  log("Usage:");
738
742
  log(" mdkg goal next [goal-id-or-qid] [--ws <alias>] [--json]");
739
743
  log("\nWhen to use:");
740
- log(" Select the next local feature, task, bug, or test inside a recursive goal without mutating active_node.");
744
+ log(" Select the next local feature, task, bug, test, or spike inside a recursive goal without mutating active_node.");
741
745
  log(" If no goal id is supplied, mdkg uses the selected goal or the unique active goal.");
742
746
  printGlobalOptions(log);
743
747
  return;
@@ -797,7 +801,7 @@ function printGoalHelp(log, subcommand) {
797
801
  log(" mdkg goal clear [--json]");
798
802
  log(" mdkg goal pause|resume|done <goal-id-or-qid> [--json]");
799
803
  log("\nNotes:");
800
- log(" - goals orchestrate recursive progress; features, tasks, bugs, and tests are iterable work units");
804
+ log(" - goals orchestrate recursive progress; features, tasks, bugs, tests, and spikes are iterable work units");
801
805
  log(" - `mdkg goal next` is read-only; use `mdkg goal claim` to update active_node");
802
806
  log(" - goal evaluation is report-only and never executes required_checks");
803
807
  log(" - subgraph goal qids are read-only; update the source workspace instead");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "tool": "mdkg",
4
- "package_version": "0.3.1",
4
+ "package_version": "0.3.2",
5
5
  "source": {
6
6
  "help_targets": "scripts/cli_help_targets.js",
7
7
  "command_matrix": "CLI_COMMAND_MATRIX.md"
@@ -7469,5 +7469,5 @@
7469
7469
  }
7470
7470
  }
7471
7471
  ],
7472
- "contract_hash": "5fa77fe079da6a7bd80fe4418133f204917f9157b600408c47f1e965610a5c72"
7472
+ "contract_hash": "226793aa87d0fd57e187936a5ab17a86413149cbd2d52674324921b1e5051ff7"
7473
7473
  }
@@ -288,7 +288,43 @@ function normalizeGraphRef(value, sourceWorkspace, knownWorkspaces, externalWork
288
288
  function frontmatterRefEntries(index, externalWorkspaces) {
289
289
  const knownWorkspaces = new Set(index.meta.workspaces);
290
290
  const entries = [];
291
+ const pushListEntries = (node, field, raw) => {
292
+ for (const [indexValue, value] of raw.entries()) {
293
+ const indexedField = `${field}[${indexValue}]`;
294
+ if (LOCAL_LIST_REF_FIELDS.has(field)) {
295
+ const target = normalizeGraphRef(value, node.ws, knownWorkspaces, externalWorkspaces);
296
+ if (target) {
297
+ entries.push({
298
+ qid: node.qid,
299
+ path: node.path,
300
+ field: indexedField,
301
+ value,
302
+ target,
303
+ refKind: "graph",
304
+ locationKind: "frontmatter",
305
+ });
306
+ }
307
+ }
308
+ if (value.startsWith("archive://") && ARCHIVE_REF_LIST_FIELDS.has(field)) {
309
+ entries.push({
310
+ qid: node.qid,
311
+ path: node.path,
312
+ field: indexedField,
313
+ value,
314
+ refKind: "archive",
315
+ locationKind: "frontmatter",
316
+ });
317
+ }
318
+ }
319
+ };
291
320
  for (const node of Object.values(index.nodes).sort((a, b) => a.qid.localeCompare(b.qid))) {
321
+ for (const [field, raw] of [
322
+ ["links", node.links],
323
+ ["artifacts", node.artifacts],
324
+ ["refs", node.refs],
325
+ ]) {
326
+ pushListEntries(node, field, raw);
327
+ }
292
328
  for (const [field, raw] of Object.entries(node.attributes).sort(([a], [b]) => a.localeCompare(b))) {
293
329
  if (typeof raw === "string") {
294
330
  if (LOCAL_SCALAR_REF_FIELDS.has(field)) {
@@ -320,33 +356,7 @@ function frontmatterRefEntries(index, externalWorkspaces) {
320
356
  if (!Array.isArray(raw)) {
321
357
  continue;
322
358
  }
323
- for (const [indexValue, value] of raw.entries()) {
324
- const indexedField = `${field}[${indexValue}]`;
325
- if (LOCAL_LIST_REF_FIELDS.has(field)) {
326
- const target = normalizeGraphRef(value, node.ws, knownWorkspaces, externalWorkspaces);
327
- if (target) {
328
- entries.push({
329
- qid: node.qid,
330
- path: node.path,
331
- field: indexedField,
332
- value,
333
- target,
334
- refKind: "graph",
335
- locationKind: "frontmatter",
336
- });
337
- }
338
- }
339
- if (value.startsWith("archive://") && ARCHIVE_REF_LIST_FIELDS.has(field)) {
340
- entries.push({
341
- qid: node.qid,
342
- path: node.path,
343
- field: indexedField,
344
- value,
345
- refKind: "archive",
346
- locationKind: "frontmatter",
347
- });
348
- }
349
- }
359
+ pushListEntries(node, field, raw);
350
360
  }
351
361
  }
352
362
  return entries;
@@ -29,7 +29,7 @@ const qid_1 = require("../util/qid");
29
29
  const sort_1 = require("../util/sort");
30
30
  const event_support_1 = require("./event_support");
31
31
  const node_card_1 = require("./node_card");
32
- const CONCRETE_GOAL_NEXT_TYPES = new Set(["feat", "task", "bug", "test"]);
32
+ const CONCRETE_GOAL_NEXT_TYPES = new Set(["feat", "task", "bug", "test", "spike"]);
33
33
  const SELECTED_GOAL_STATE_PATH = path_1.default.join(".mdkg", "state", "selected-goal.json");
34
34
  const GOAL_STATE_BY_ACTION = {
35
35
  pause: "paused",
@@ -7,8 +7,8 @@ const errors_1 = require("../util/errors");
7
7
  const qid_1 = require("../util/qid");
8
8
  const sort_1 = require("../util/sort");
9
9
  const node_card_1 = require("./node_card");
10
- const NEXT_TYPES = new Set(["feat", "task", "bug", "test"]);
11
- const NO_MATCH_MESSAGE = 'no matching work items found; consider `mdkg new task "..."` or `mdkg new test "..."`';
10
+ const NEXT_TYPES = new Set(["feat", "task", "bug", "test", "spike"]);
11
+ const NO_MATCH_MESSAGE = 'no matching work items found; consider `mdkg new task "..."`, `mdkg new test "..."`, or `mdkg new spike "..."`';
12
12
  function normalizeWorkspace(value) {
13
13
  if (!value || value === "all") {
14
14
  return undefined;
@@ -22,7 +22,7 @@ const atomic_1 = require("../util/atomic");
22
22
  const lock_1 = require("../util/lock");
23
23
  const event_support_1 = require("./event_support");
24
24
  const checkpoint_1 = require("./checkpoint");
25
- const MUTABLE_TASK_TYPES = new Set(["feat", "task", "bug", "test"]);
25
+ const MUTABLE_TASK_TYPES = new Set(["feat", "task", "bug", "test", "spike"]);
26
26
  const SKILL_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
27
27
  function parseCsvList(raw) {
28
28
  if (!raw) {
@@ -113,7 +113,7 @@ function loadMutableTaskNode(root, idOrQid, wsHint) {
113
113
  throw new errors_1.UsageError(`cannot mutate read-only subgraph node ${node.qid}; update the source workspace for subgraph ${node.source.subgraph_alias}`);
114
114
  }
115
115
  if (!MUTABLE_TASK_TYPES.has(node.type)) {
116
- throw new errors_1.UsageError(`mdkg task only supports feat, task, bug, and test nodes; use markdown editing for ${node.type}:${node.id}`);
116
+ throw new errors_1.UsageError(`mdkg task only supports feat, task, bug, test, and spike nodes; use markdown editing for ${node.type}:${node.id}`);
117
117
  }
118
118
  const filePath = path_1.default.resolve(root, node.path);
119
119
  const content = fs_1.default.readFileSync(filePath, "utf8");
@@ -36,6 +36,17 @@ const RECOMMENDED_HEADINGS = {
36
36
  "Links / Artifacts",
37
37
  ],
38
38
  feat: ["Overview", "Acceptance Criteria", "Notes"],
39
+ spike: [
40
+ "Research Question",
41
+ "Context And Constraints",
42
+ "Search Plan",
43
+ "Findings",
44
+ "Options And Tradeoffs",
45
+ "Recommendation",
46
+ "Follow-Up Nodes To Create",
47
+ "Skill Candidates",
48
+ "Evidence And Sources",
49
+ ],
39
50
  epic: ["Goal", "Scope", "Milestones", "Out of Scope", "Risks", "Links / Artifacts"],
40
51
  checkpoint: [
41
52
  "Summary",
@@ -5,7 +5,7 @@ exports.goalScopeRefs = goalScopeRefs;
5
5
  exports.collectGoalScope = collectGoalScope;
6
6
  const qid_1 = require("../util/qid");
7
7
  exports.GOAL_SCOPE_CONTAINER_TYPES = new Set(["epic", "feat"]);
8
- exports.GOAL_SCOPE_ACTIONABLE_TYPES = new Set(["feat", "task", "bug", "test"]);
8
+ exports.GOAL_SCOPE_ACTIONABLE_TYPES = new Set(["feat", "task", "bug", "test", "spike"]);
9
9
  exports.GOAL_SCOPE_ALLOWED_TYPES = new Set([
10
10
  ...exports.GOAL_SCOPE_CONTAINER_TYPES,
11
11
  ...exports.GOAL_SCOPE_ACTIONABLE_TYPES,
@@ -10,7 +10,7 @@ const id_1 = require("../util/id");
10
10
  const refs_1 = require("../util/refs");
11
11
  const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
12
12
  const DEC_ID_RE = /^dec-[0-9]+$/;
13
- exports.WORK_TYPES = new Set(["goal", "epic", "feat", "task", "bug", "checkpoint", "test"]);
13
+ exports.WORK_TYPES = new Set(["goal", "epic", "feat", "task", "bug", "spike", "checkpoint", "test"]);
14
14
  exports.DEC_TYPES = new Set(["dec"]);
15
15
  exports.ALLOWED_TYPES = new Set([
16
16
  "rule",
@@ -23,6 +23,7 @@ exports.ALLOWED_TYPES = new Set([
23
23
  "feat",
24
24
  "task",
25
25
  "bug",
26
+ "spike",
26
27
  "checkpoint",
27
28
  "test",
28
29
  "archive",
@@ -92,6 +92,7 @@ Validation commands:
92
92
  Node creation commands:
93
93
  - `mdkg new <type> "<title>" [options] [--json]`
94
94
  - `mdkg new goal "<title>" [options] [--json]`
95
+ - `mdkg new spike "<research question>" [options] [--json]`
95
96
 
96
97
  Agent workflow file type creation:
97
98
  - `mdkg new spec "<title>" [options] [--json]`
@@ -109,6 +110,9 @@ Agent workflow notes:
109
110
  - `spec` and `work` scaffold as validation-clean standalone docs.
110
111
  - `work_order`, `receipt`, `feedback`, `dispute`, and `proposal` need real refs before strict `mdkg validate` passes.
111
112
  - `goal` nodes capture recursive objective state and required checks, but normal `mdkg next` does not select them.
113
+ - `spike` nodes are actionable research/planning work under `.mdkg/work/`; use `mdkg task start|update|done` for lifecycle state.
114
+ - Spikes record sources, findings, recommendations, follow-up node ideas, and skill candidates in Markdown body sections; they do not perform web search, execute research, create follow-up nodes, generate `SKILL.md`, or expose a `mdkg spike ...` namespace automatically.
115
+ - after fresh init, run `mdkg index` before treating `mdkg doctor --strict --json` as a clean health gate; init writes source scaffold files and index writes generated caches.
112
116
 
113
117
  Workspace registry commands:
114
118
  - `mdkg workspace ls [--json]`
@@ -125,6 +129,7 @@ Task mutation commands:
125
129
  - `mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"] [--json]`
126
130
  - `mdkg task update <id-or-qid> [options] [--json]`
127
131
  - `mdkg task done <id-or-qid> [--checkpoint "<title>"] [options] [--json]`
132
+ - task commands support task-like `feat`, `task`, `bug`, `test`, and `spike` nodes
128
133
 
129
134
  Checkpoint commands:
130
135
  - `mdkg checkpoint new <title> [--ws <alias>] [--json]`
@@ -157,7 +162,7 @@ Capability discovery:
157
162
  - capability records are deterministic cache projections from Markdown
158
163
  - records include source hash, headings, refs, and `indexed_at`
159
164
  - SPEC and WORK capability records include read-only `linkage` arrays for related SPECs, work contracts, work orders, and receipts when those graph mirrors exist
160
- - normal task, epic, feat, bug, test, and checkpoint nodes are intentionally excluded
165
+ - normal task, epic, feat, bug, test, spike, and checkpoint nodes are intentionally excluded
161
166
 
162
167
  Spec capability records:
163
168
  - `mdkg spec list [--json]`
@@ -253,7 +258,7 @@ Goal nodes:
253
258
  - `mdkg goal pause <goal-id-or-qid> [--ws <alias>] [--json]`
254
259
  - `mdkg goal resume <goal-id-or-qid> [--ws <alias>] [--json]`
255
260
  - `mdkg goal done <goal-id-or-qid> [--ws <alias>] [--json]`
256
- - goals orchestrate recursive progress through explicit `scope_refs`; tasks, bugs, tests, and features remain concrete executable units
261
+ - goals orchestrate recursive progress through explicit `scope_refs`; tasks, bugs, tests, spikes, and features remain concrete executable units
257
262
  - `goal next` is read-only; use `goal claim` to set `active_node`
258
263
  - `mdkg goal evaluate` is report-only and never runs commands from `required_checks`
259
264
  - skill improvements discovered during normal goal execution should be recorded as candidates or proposals unless the active node is skill-maintenance
@@ -8,7 +8,7 @@ mdkg is pre-v1 public alpha software. Graph, cache, bundle, and DAL contracts ma
8
8
 
9
9
  - `core/`: rules, operating guide, and pinned docs
10
10
  - `design/`: product/engineering decision records
11
- - `work/`: epics, tasks, bugs, tests, checkpoints
11
+ - `work/`: epics, tasks, bugs, tests, spikes, checkpoints
12
12
  - `templates/`: default node templates
13
13
  - `archive/`: sidecar metadata and deterministic compressed source/artifact caches
14
14
  - `bundles/`: optional committed full graph snapshot bundles
@@ -20,6 +20,7 @@ mdkg is pre-v1 public alpha software. Graph, cache, bundle, and DAL contracts ma
20
20
 
21
21
  ```bash
22
22
  mdkg upgrade
23
+ mdkg index
23
24
  mdkg new task "..." --status todo --priority 1
24
25
  mdkg search "..."
25
26
  mdkg show <id>
@@ -34,18 +35,34 @@ mdkg fix plan --json
34
35
  mdkg validate
35
36
  ```
36
37
 
37
- 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.
38
+ This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg index` to create or refresh generated graph/skill/capability/subgraph and SQLite caches after init, `mdkg new` to create work, `mdkg new goal "..."` plus `mdkg goal 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.
38
39
 
39
40
  Use `mdkg status --json` for a read-only operator summary of Git, graph,
40
41
  selected-goal, project DB, and generated-cache health before mutating work. Use
41
42
  `mdkg doctor --strict --json` for typed diagnostic checks in CI or agent
42
- orchestration. These commands inspect state; they do not apply repairs.
43
+ orchestration. These commands inspect state; they do not apply repairs. After a
44
+ fresh init, run `mdkg index` first so strict doctor can load generated caches.
43
45
 
44
46
  Use `mdkg fix plan --json` for dry-run repair guidance. It reports generated
45
47
  index/cache repair hints, missing graph references, and duplicate local ids as
46
48
  receipt-shaped planned changes with risk levels and `apply_supported: false`.
47
49
  `fix apply` is not exposed; repair application is intentionally deferred.
48
50
 
51
+ Use research spikes for investigation and planning work that should produce a
52
+ reviewable recommendation before implementation:
53
+
54
+ ```bash
55
+ mdkg new spike "research docs launch workflow" --status todo --priority 1
56
+ mdkg task start spike-1
57
+ mdkg show spike-1
58
+ ```
59
+
60
+ Spikes use the existing task lifecycle and goal routing. They do not perform web
61
+ search, execute research, create follow-up nodes, or generate `SKILL.md` files
62
+ automatically. Record sources, findings, recommendations, follow-up node ideas,
63
+ and skill candidates in the spike body, then create follow-up tasks or tests
64
+ intentionally with `mdkg new task ...` or `mdkg new test ...`.
65
+
49
66
  Agent workflow docs can use semantic ids:
50
67
 
51
68
  ```bash
@@ -67,10 +67,19 @@ It MUST NOT include:
67
67
  - verify `package.json` `"files"` includes only expected files
68
68
  - optionally run `npm pack` and inspect tarball contents
69
69
 
70
- 7) Publish
71
- - `npm publish`
72
-
73
- 8) Tag and push
70
+ 7) Confirm npm auth
71
+ - if using an exported `NPM_TOKEN`, create a temporary npm userconfig that
72
+ references `${NPM_TOKEN}` literally:
73
+ `//registry.npmjs.org/:_authToken=${NPM_TOKEN}`
74
+ - run `npm whoami --registry=https://registry.npmjs.org/ --userconfig=/private/tmp/mdkg-npm-publish.npmrc`
75
+ - do not print the token, do not commit the temp userconfig, and do not add
76
+ unsupported `always-auth` config
77
+
78
+ 8) Publish
79
+ - `npm publish --registry=https://registry.npmjs.org/ --userconfig=/private/tmp/mdkg-npm-publish.npmrc`
80
+ - omit `--userconfig` only when an existing npm login has already been verified
81
+
82
+ 9) Tag and push
74
83
  - create git tag matching version (example `v0.1.0`)
75
84
  - push commits and tags
76
85
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "tool": "mdkg",
4
- "mdkg_version": "0.3.1",
4
+ "mdkg_version": "0.3.2",
5
5
  "files": [
6
6
  {
7
7
  "path": ".mdkg/config.json",
@@ -46,7 +46,7 @@
46
46
  {
47
47
  "path": ".mdkg/core/rule-5-release-and-versioning.md",
48
48
  "category": "core",
49
- "sha256": "e97b00aa3ade29011f1f2b482042ec292f74aad8b1d72e2f8e691cdeca5d4f70"
49
+ "sha256": "d7862806f999ae23b1d8bc3446f8c81b3a7fdd7d87920d966f59795a84978a03"
50
50
  },
51
51
  {
52
52
  "path": ".mdkg/core/rule-6-templates-and-schemas.md",
@@ -61,7 +61,7 @@
61
61
  {
62
62
  "path": ".mdkg/README.md",
63
63
  "category": "mdkg_doc",
64
- "sha256": "0661196763bf05681523a576fcd0a29138ccc36df4f48dad7ba16a1f4b7b0418"
64
+ "sha256": "c08de01602698af7eb46b70e9459df9c2fa6e6c32c06b2daab3f697baa450e0d"
65
65
  },
66
66
  {
67
67
  "path": ".mdkg/skills/build-pack-and-execute-task/SKILL.md",
@@ -163,6 +163,11 @@
163
163
  "category": "template",
164
164
  "sha256": "8c96e0b6dafa65acb83a2d84519e05a7354896aec8991c148650e9ec58196c77"
165
165
  },
166
+ {
167
+ "path": ".mdkg/templates/default/spike.md",
168
+ "category": "template",
169
+ "sha256": "ac805dca7e6edcdad35e24b615dc7399cbae3bed676b9da57e24a393eb425245"
170
+ },
166
171
  {
167
172
  "path": ".mdkg/templates/default/task.md",
168
173
  "category": "template",
@@ -256,7 +261,7 @@
256
261
  {
257
262
  "path": "CLI_COMMAND_MATRIX.md",
258
263
  "category": "startup_doc",
259
- "sha256": "a9a7133e5a7c9a07a6814c679d04637370ea144eac19a6500980a37a2c4199f5"
264
+ "sha256": "888c5ce1372c0a7ba2c24bfe0aea97e221804cab1fa8940e06dc050330830a76"
260
265
  },
261
266
  {
262
267
  "path": "llms.txt",
@@ -0,0 +1,81 @@
1
+ ---
2
+ id: {{id}}
3
+ type: spike
4
+ title: {{title}}
5
+ status: {{status}}
6
+ priority: {{priority}}
7
+ epic: {{epic}}
8
+ parent: {{parent}}
9
+ prev: {{prev}}
10
+ next: {{next}}
11
+ tags: []
12
+ owners: []
13
+ links: []
14
+ artifacts: []
15
+ relates: []
16
+ blocked_by: []
17
+ blocks: []
18
+ refs: []
19
+ aliases: []
20
+ skills: []
21
+ created: {{created}}
22
+ updated: {{updated}}
23
+ ---
24
+
25
+ # Research Question
26
+
27
+ State the question this spike must answer.
28
+
29
+ # Context And Constraints
30
+
31
+ - constraint 1
32
+ - constraint 2
33
+
34
+ # Search Plan
35
+
36
+ - source or query 1
37
+ - source or query 2
38
+
39
+ # Findings
40
+
41
+ - finding 1
42
+ - finding 2
43
+
44
+ # Options And Tradeoffs
45
+
46
+ - option 1: tradeoff
47
+ - option 2: tradeoff
48
+
49
+ # Recommendation
50
+
51
+ Summarize the recommended direction and why.
52
+
53
+ # Follow-Up Nodes To Create
54
+
55
+ - task/test/decision candidate 1
56
+ - task/test/decision candidate 2
57
+
58
+ # Skill Candidates
59
+
60
+ - skill candidate 1
61
+ - skill candidate 2
62
+
63
+ # Data Structures And Algorithms Notes
64
+
65
+ - note 1
66
+
67
+ # UX Notes
68
+
69
+ - note 1
70
+
71
+ # Security Notes
72
+
73
+ - note 1
74
+
75
+ # mdkg.dev Launch Implications
76
+
77
+ - implication 1
78
+
79
+ # Evidence And Sources
80
+
81
+ - source 1
@@ -21,9 +21,10 @@ const FALLBACK_TYPES = [
21
21
  "feat",
22
22
  "task",
23
23
  "bug",
24
+ "spike",
24
25
  "checkpoint",
25
26
  ];
26
- const WORK_TYPES = ["goal", "epic", "feat", "task", "bug", "checkpoint"];
27
+ const WORK_TYPES = ["goal", "epic", "feat", "task", "bug", "spike", "checkpoint"];
27
28
  function idNumber(id) {
28
29
  const match = id.match(/-(\d+)$/);
29
30
  if (!match) {
@@ -76,7 +77,7 @@ function buildOrderKey(index, rootQid, qid, depths) {
76
77
  const node = index.nodes[qid];
77
78
  const root = index.nodes[rootQid];
78
79
  const depth = depths.get(qid);
79
- const rootIsTask = root.type === "task" || root.type === "bug";
80
+ const rootIsTask = root.type === "task" || root.type === "bug" || root.type === "spike";
80
81
  if (qid === rootQid) {
81
82
  return {
82
83
  group: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdkg",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Markdown Knowledge Graph",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -29,6 +29,7 @@
29
29
  "smoke:fix-plan": "npm run build && node scripts/smoke-fix-plan.js",
30
30
  "smoke:branch-conflicts": "npm run build && node scripts/smoke-branch-conflicts.js",
31
31
  "smoke:command-docs": "npm run build && node scripts/smoke-command-docs.js",
32
+ "smoke:spike": "npm run build && node scripts/smoke-spike.js",
32
33
  "smoke:bundle": "npm run build && node scripts/smoke-bundle.js",
33
34
  "smoke:bundle-import": "npm run smoke:subgraph",
34
35
  "smoke:visibility": "npm run build && node scripts/smoke-visibility.js",
@@ -39,7 +40,7 @@
39
40
  "cli:check": "npm run build && node scripts/cli_help_snapshot.js --check",
40
41
  "cli:contract": "npm run build && node scripts/generate-command-contract.js --check",
41
42
  "prepack": "npm run build && node scripts/assert-publish-ready.js",
42
- "prepublishOnly": "npm run test && npm run cli:check && npm run cli:contract && node dist/cli.js validate && npm run smoke:consumer && npm run smoke:matrix && npm run smoke:upgrade && npm run smoke:init && npm run smoke:capabilities && npm run smoke:db && npm run smoke:db-queue && npm run smoke:db-queue-cli && npm run smoke:db-events && npm run smoke:db-materializer && npm run smoke:db-snapshot && npm run smoke:archive-work && npm run smoke:work-invocation && npm run smoke:cli-ux-polish && npm run smoke:operator-health && npm run smoke:fix-plan && npm run smoke:branch-conflicts && npm run smoke:command-docs && npm run smoke:bundle && npm run smoke:subgraph && npm run smoke:visibility && npm run smoke:sqlite && npm run smoke:parallel && npm run smoke:goal && node scripts/assert-publish-ready.js",
43
+ "prepublishOnly": "npm run test && npm run cli:check && npm run cli:contract && node dist/cli.js validate && npm run smoke:consumer && npm run smoke:matrix && npm run smoke:upgrade && npm run smoke:init && npm run smoke:capabilities && npm run smoke:db && npm run smoke:db-queue && npm run smoke:db-queue-cli && npm run smoke:db-events && npm run smoke:db-materializer && npm run smoke:db-snapshot && npm run smoke:archive-work && npm run smoke:work-invocation && npm run smoke:cli-ux-polish && npm run smoke:operator-health && npm run smoke:fix-plan && npm run smoke:branch-conflicts && npm run smoke:command-docs && npm run smoke:spike && npm run smoke:bundle && npm run smoke:subgraph && npm run smoke:visibility && npm run smoke:sqlite && npm run smoke:parallel && npm run smoke:goal && node scripts/assert-publish-ready.js",
43
44
  "postinstall": "node scripts/postinstall.js",
44
45
  "smoke:subgraph": "npm run build && node scripts/smoke-subgraph.js"
45
46
  },