mdkg 0.1.4 → 0.1.6
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 +25 -1
- package/README.md +24 -1
- package/dist/cli.js +175 -2
- package/dist/commands/goal.js +548 -0
- package/dist/commands/init.js +1 -0
- package/dist/commands/new.js +7 -1
- package/dist/commands/task.js +2 -2
- package/dist/commands/upgrade.js +3 -3
- package/dist/commands/validate.js +33 -1
- package/dist/graph/frontmatter.js +8 -0
- package/dist/graph/goal_scope.js +127 -0
- package/dist/graph/node.js +80 -1
- package/dist/graph/validate_graph.js +41 -0
- package/dist/init/AGENT_START.md +16 -1
- package/dist/init/CLI_COMMAND_MATRIX.md +27 -0
- package/dist/init/README.md +1 -1
- package/dist/init/core/rule-3-cli-contract.md +26 -0
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +6 -1
- package/dist/init/core/rule-6-templates-and-schemas.md +10 -1
- package/dist/init/init-manifest.json +19 -9
- package/dist/init/skills/default/pursue-mdkg-goal/SKILL.md +68 -0
- package/dist/init/skills/default/select-work-and-ground-context/SKILL.md +9 -7
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +10 -9
- package/dist/init/templates/default/goal.md +91 -0
- package/dist/pack/order.js +2 -1
- package/dist/pack/pack.js +17 -0
- package/package.json +3 -2
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GOAL_SCOPE_ALLOWED_TYPES = exports.GOAL_SCOPE_ACTIONABLE_TYPES = exports.GOAL_SCOPE_CONTAINER_TYPES = void 0;
|
|
4
|
+
exports.goalScopeRefs = goalScopeRefs;
|
|
5
|
+
exports.collectGoalScope = collectGoalScope;
|
|
6
|
+
const qid_1 = require("../util/qid");
|
|
7
|
+
exports.GOAL_SCOPE_CONTAINER_TYPES = new Set(["epic", "feat"]);
|
|
8
|
+
exports.GOAL_SCOPE_ACTIONABLE_TYPES = new Set(["feat", "task", "bug", "test"]);
|
|
9
|
+
exports.GOAL_SCOPE_ALLOWED_TYPES = new Set([
|
|
10
|
+
...exports.GOAL_SCOPE_CONTAINER_TYPES,
|
|
11
|
+
...exports.GOAL_SCOPE_ACTIONABLE_TYPES,
|
|
12
|
+
]);
|
|
13
|
+
function toStringList(value) {
|
|
14
|
+
if (!Array.isArray(value)) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
return value.filter((item) => typeof item === "string");
|
|
18
|
+
}
|
|
19
|
+
function goalScopeRefs(goal) {
|
|
20
|
+
return toStringList(goal.attributes.scope_refs);
|
|
21
|
+
}
|
|
22
|
+
function resolveGoalScopeRef(index, value, ws) {
|
|
23
|
+
const resolved = (0, qid_1.resolveQid)(index, value, ws);
|
|
24
|
+
return resolved.status === "ok" ? resolved.qid : undefined;
|
|
25
|
+
}
|
|
26
|
+
function addIfPresent(values, value) {
|
|
27
|
+
if (value) {
|
|
28
|
+
values.add(value);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function collectDirectCompatibilityRefs(index, goal) {
|
|
32
|
+
const qids = new Set();
|
|
33
|
+
const edges = goal.edges;
|
|
34
|
+
addIfPresent(qids, edges.next);
|
|
35
|
+
addIfPresent(qids, edges.prev);
|
|
36
|
+
addIfPresent(qids, edges.parent);
|
|
37
|
+
addIfPresent(qids, edges.epic);
|
|
38
|
+
for (const value of edges.relates) {
|
|
39
|
+
qids.add(value);
|
|
40
|
+
}
|
|
41
|
+
for (const value of edges.blocks) {
|
|
42
|
+
qids.add(value);
|
|
43
|
+
}
|
|
44
|
+
for (const value of edges.blocked_by) {
|
|
45
|
+
qids.add(value);
|
|
46
|
+
}
|
|
47
|
+
for (const node of Object.values(index.nodes)) {
|
|
48
|
+
if (node.edges.parent === goal.qid ||
|
|
49
|
+
node.edges.epic === goal.qid ||
|
|
50
|
+
node.edges.prev === goal.qid ||
|
|
51
|
+
node.edges.next === goal.qid ||
|
|
52
|
+
node.edges.relates.includes(goal.qid) ||
|
|
53
|
+
node.edges.blocked_by.includes(goal.qid) ||
|
|
54
|
+
node.edges.blocks.includes(goal.qid)) {
|
|
55
|
+
qids.add(node.qid);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return qids;
|
|
59
|
+
}
|
|
60
|
+
function descendantQids(index, qid) {
|
|
61
|
+
const byEpic = index.reverse_edges.epic?.[qid] ?? [];
|
|
62
|
+
const byParent = index.reverse_edges.parent?.[qid] ?? [];
|
|
63
|
+
return [...new Set([...byEpic, ...byParent])].sort();
|
|
64
|
+
}
|
|
65
|
+
function collectGoalScope(index, goal, options = {}) {
|
|
66
|
+
const includeCompatibilityRefs = options.includeCompatibilityRefs ?? true;
|
|
67
|
+
const rootQids = [];
|
|
68
|
+
const qids = new Set();
|
|
69
|
+
const actionableQids = new Set();
|
|
70
|
+
const missingRefs = [];
|
|
71
|
+
const invalidRefs = [];
|
|
72
|
+
const queued = new Set();
|
|
73
|
+
const queue = [];
|
|
74
|
+
function enqueue(qid) {
|
|
75
|
+
if (queued.has(qid)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
queued.add(qid);
|
|
79
|
+
queue.push(qid);
|
|
80
|
+
}
|
|
81
|
+
for (const ref of goalScopeRefs(goal)) {
|
|
82
|
+
const resolved = resolveGoalScopeRef(index, ref, goal.ws);
|
|
83
|
+
if (!resolved) {
|
|
84
|
+
missingRefs.push(ref);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
rootQids.push(resolved);
|
|
88
|
+
enqueue(resolved);
|
|
89
|
+
}
|
|
90
|
+
if (includeCompatibilityRefs) {
|
|
91
|
+
for (const qid of collectDirectCompatibilityRefs(index, goal)) {
|
|
92
|
+
rootQids.push(qid);
|
|
93
|
+
enqueue(qid);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
while (queue.length > 0) {
|
|
97
|
+
const qid = queue.shift();
|
|
98
|
+
if (!qid) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
const node = index.nodes[qid];
|
|
102
|
+
if (!node) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (!exports.GOAL_SCOPE_ALLOWED_TYPES.has(node.type)) {
|
|
106
|
+
invalidRefs.push(qid);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
qids.add(qid);
|
|
110
|
+
if (exports.GOAL_SCOPE_ACTIONABLE_TYPES.has(node.type)) {
|
|
111
|
+
actionableQids.add(qid);
|
|
112
|
+
}
|
|
113
|
+
if (exports.GOAL_SCOPE_CONTAINER_TYPES.has(node.type)) {
|
|
114
|
+
for (const childQid of descendantQids(index, qid)) {
|
|
115
|
+
enqueue(childQid);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
rootQids.sort();
|
|
120
|
+
return {
|
|
121
|
+
rootQids: [...new Set(rootQids)],
|
|
122
|
+
qids,
|
|
123
|
+
actionableQids,
|
|
124
|
+
missingRefs,
|
|
125
|
+
invalidRefs: [...new Set(invalidRefs)].sort(),
|
|
126
|
+
};
|
|
127
|
+
}
|
package/dist/graph/node.js
CHANGED
|
@@ -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(["epic", "feat", "task", "bug", "checkpoint", "test"]);
|
|
13
|
+
exports.WORK_TYPES = new Set(["goal", "epic", "feat", "task", "bug", "checkpoint", "test"]);
|
|
14
14
|
exports.DEC_TYPES = new Set(["dec"]);
|
|
15
15
|
exports.ALLOWED_TYPES = new Set([
|
|
16
16
|
"rule",
|
|
@@ -18,6 +18,7 @@ exports.ALLOWED_TYPES = new Set([
|
|
|
18
18
|
"edd",
|
|
19
19
|
"dec",
|
|
20
20
|
"prop",
|
|
21
|
+
"goal",
|
|
21
22
|
"epic",
|
|
22
23
|
"feat",
|
|
23
24
|
"task",
|
|
@@ -28,7 +29,18 @@ exports.ALLOWED_TYPES = new Set([
|
|
|
28
29
|
...agent_file_types_1.AGENT_FILE_TYPES,
|
|
29
30
|
]);
|
|
30
31
|
const DEC_STATUS = new Set(["proposed", "accepted", "rejected", "superseded"]);
|
|
32
|
+
const GOAL_STATE = new Set(["active", "paused", "achieved", "blocked", "budget_limited"]);
|
|
31
33
|
const SKILL_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
34
|
+
const GOAL_ATTRIBUTE_KEYS = [
|
|
35
|
+
"goal_state",
|
|
36
|
+
"goal_condition",
|
|
37
|
+
"scope_refs",
|
|
38
|
+
"active_node",
|
|
39
|
+
"required_skills",
|
|
40
|
+
"required_checks",
|
|
41
|
+
"max_iterations",
|
|
42
|
+
"blocked_after_attempts",
|
|
43
|
+
];
|
|
32
44
|
function formatError(filePath, message) {
|
|
33
45
|
return new Error(`${filePath}: ${message}`);
|
|
34
46
|
}
|
|
@@ -142,6 +154,71 @@ function normalizeSkillList(values, filePath) {
|
|
|
142
154
|
return normalized;
|
|
143
155
|
});
|
|
144
156
|
}
|
|
157
|
+
function parsePositiveIntegerString(value, key, filePath) {
|
|
158
|
+
if (!/^[1-9][0-9]*$/.test(value)) {
|
|
159
|
+
throw formatError(filePath, `${key} must be a positive integer`);
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
function validateGoalFrontmatter(type, frontmatter, filePath) {
|
|
164
|
+
if (type !== "goal") {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const goalState = requireLowercase(expectString(frontmatter, "goal_state", filePath), "goal_state", filePath);
|
|
168
|
+
if (!GOAL_STATE.has(goalState)) {
|
|
169
|
+
throw formatError(filePath, `goal_state must be one of ${Array.from(GOAL_STATE).join(", ")}`);
|
|
170
|
+
}
|
|
171
|
+
const goalCondition = expectString(frontmatter, "goal_condition", filePath);
|
|
172
|
+
if (goalCondition.length > 4000) {
|
|
173
|
+
throw formatError(filePath, "goal_condition must be 4000 characters or fewer");
|
|
174
|
+
}
|
|
175
|
+
const activeNode = optionalString(frontmatter, "active_node", filePath);
|
|
176
|
+
if (activeNode !== undefined) {
|
|
177
|
+
const normalized = requireLowercase(activeNode, "active_node", filePath);
|
|
178
|
+
if (!(0, id_1.isPortableIdRef)(normalized)) {
|
|
179
|
+
throw formatError(filePath, "active_node must be a local id or qid");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const scopeRefs = optionalList(frontmatter, "scope_refs", filePath);
|
|
183
|
+
for (const [index, value] of scopeRefs.entries()) {
|
|
184
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
185
|
+
throw formatError(filePath, `scope_refs[${index}] must not be empty`);
|
|
186
|
+
}
|
|
187
|
+
const normalized = requireLowercase(value, `scope_refs[${index}]`, filePath);
|
|
188
|
+
if (!(0, id_1.isPortableIdRef)(normalized)) {
|
|
189
|
+
throw formatError(filePath, `scope_refs[${index}] must be a local id or qid`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const requiredSkills = optionalList(frontmatter, "required_skills", filePath);
|
|
193
|
+
normalizeSkillList(requiredSkills, filePath);
|
|
194
|
+
const requiredChecks = optionalList(frontmatter, "required_checks", filePath);
|
|
195
|
+
for (const [index, value] of requiredChecks.entries()) {
|
|
196
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
197
|
+
throw formatError(filePath, `required_checks[${index}] must not be empty`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const maxIterations = optionalString(frontmatter, "max_iterations", filePath);
|
|
201
|
+
if (maxIterations !== undefined) {
|
|
202
|
+
parsePositiveIntegerString(maxIterations, "max_iterations", filePath);
|
|
203
|
+
}
|
|
204
|
+
const blockedAfterAttempts = optionalString(frontmatter, "blocked_after_attempts", filePath);
|
|
205
|
+
if (blockedAfterAttempts !== undefined) {
|
|
206
|
+
parsePositiveIntegerString(blockedAfterAttempts, "blocked_after_attempts", filePath);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function extractGoalAttributes(type, frontmatter) {
|
|
210
|
+
if (type !== "goal") {
|
|
211
|
+
return {};
|
|
212
|
+
}
|
|
213
|
+
const attributes = {};
|
|
214
|
+
for (const key of GOAL_ATTRIBUTE_KEYS) {
|
|
215
|
+
const value = frontmatter[key];
|
|
216
|
+
if (value !== undefined) {
|
|
217
|
+
attributes[key] = value;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return attributes;
|
|
221
|
+
}
|
|
145
222
|
function requireTemplateSchema(type, templateSchemas, filePath) {
|
|
146
223
|
const schema = templateSchemas[type];
|
|
147
224
|
if (!schema) {
|
|
@@ -185,6 +262,7 @@ function parseNode(content, filePath, options) {
|
|
|
185
262
|
validateTemplateKeys(frontmatter, schema, filePath);
|
|
186
263
|
(0, agent_file_types_1.validateAgentFrontmatter)(type, frontmatter, filePath);
|
|
187
264
|
(0, archive_file_1.validateArchiveFrontmatter)(type, frontmatter, filePath);
|
|
265
|
+
validateGoalFrontmatter(type, frontmatter, filePath);
|
|
188
266
|
const idValue = requireLowercase(expectString(frontmatter, "id", filePath), "id", filePath);
|
|
189
267
|
const id = isPortableType
|
|
190
268
|
? requirePortableIdFormat(idValue, "id", filePath)
|
|
@@ -250,6 +328,7 @@ function parseNode(content, filePath, options) {
|
|
|
250
328
|
}
|
|
251
329
|
const edges = (0, edges_1.extractEdges)(frontmatter, filePath, { allowPortableRefs: isPortableType });
|
|
252
330
|
const attributes = {
|
|
331
|
+
...extractGoalAttributes(type, frontmatter),
|
|
253
332
|
...(0, agent_file_types_1.extractAgentAttributes)(type, frontmatter),
|
|
254
333
|
...(0, archive_file_1.extractArchiveAttributes)(type, frontmatter),
|
|
255
334
|
};
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.collectGraphErrors = collectGraphErrors;
|
|
4
4
|
exports.validateGraph = validateGraph;
|
|
5
5
|
const refs_1 = require("../util/refs");
|
|
6
|
+
const goal_scope_1 = require("./goal_scope");
|
|
6
7
|
function pushError(errors, message) {
|
|
7
8
|
if (errors) {
|
|
8
9
|
errors.push(message);
|
|
@@ -433,6 +434,45 @@ function validateArchiveUriRefs(index, allowMissing, errors) {
|
|
|
433
434
|
}
|
|
434
435
|
}
|
|
435
436
|
}
|
|
437
|
+
function validateGoalRefs(index, allowMissing, errors) {
|
|
438
|
+
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
439
|
+
if (node.type !== "goal") {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
const scope = (0, goal_scope_1.collectGoalScope)(index, node, { includeCompatibilityRefs: false });
|
|
443
|
+
for (const ref of scope.missingRefs) {
|
|
444
|
+
if (allowMissing) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
pushError(errors, `${qid}: scope_refs references missing node ${ref}`);
|
|
448
|
+
}
|
|
449
|
+
for (const ref of scope.invalidRefs) {
|
|
450
|
+
const target = index.nodes[ref];
|
|
451
|
+
const typeLabel = target ? target.type : "missing";
|
|
452
|
+
pushError(errors, `${qid}: scope_refs references ${ref} with type ${typeLabel}, expected ${Array.from(goal_scope_1.GOAL_SCOPE_ALLOWED_TYPES).join(", ")}`);
|
|
453
|
+
}
|
|
454
|
+
const activeNode = node.attributes.active_node;
|
|
455
|
+
if (typeof activeNode !== "string") {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
const activeQid = activeNode.includes(":") ? activeNode : `${node.ws}:${activeNode}`;
|
|
459
|
+
const target = index.nodes[activeQid];
|
|
460
|
+
if (!target) {
|
|
461
|
+
if (allowMissing) {
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
pushError(errors, `${qid}: active_node references missing node ${activeNode}`);
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
if (!goal_scope_1.GOAL_SCOPE_ACTIONABLE_TYPES.has(target.type)) {
|
|
468
|
+
pushError(errors, `${qid}: active_node references ${activeQid} with type ${target.type}, expected ${Array.from(goal_scope_1.GOAL_SCOPE_ACTIONABLE_TYPES).join(", ")}`);
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
if (scope.qids.size > 0 && !scope.actionableQids.has(activeQid)) {
|
|
472
|
+
pushError(errors, `${qid}: active_node ${activeQid} is not inside goal scope_refs`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
436
476
|
function detectPrevNextCycles(index, errors) {
|
|
437
477
|
const nodes = index.nodes;
|
|
438
478
|
const seen = new Set();
|
|
@@ -480,6 +520,7 @@ function collectGraphErrors(index, options = {}) {
|
|
|
480
520
|
validateAgentWorkflowDisputeRefs(index, allowMissing, errors);
|
|
481
521
|
validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors);
|
|
482
522
|
validateArchiveUriRefs(index, allowMissing, errors);
|
|
523
|
+
validateGoalRefs(index, allowMissing, errors);
|
|
483
524
|
detectPrevNextCycles(index, errors);
|
|
484
525
|
return errors;
|
|
485
526
|
}
|
package/dist/init/AGENT_START.md
CHANGED
|
@@ -23,6 +23,11 @@ Agent operating prompt:
|
|
|
23
23
|
- Treat mdkg rules, EDDs, DECs, PRDs, and work nodes as more authoritative than chat memory.
|
|
24
24
|
- Use `mdkg show <id>` for direct inspection and `mdkg show <id> --meta` for card-only inspection.
|
|
25
25
|
- Use `mdkg search "..."` and `mdkg next` to discover current work.
|
|
26
|
+
- Use `mdkg new goal "..."` for long-running recursive objectives that need an explicit end condition, active node, required skills, required checks, and completion evidence.
|
|
27
|
+
- Use `mdkg goal select <goal-id>` when a goal is active, then `mdkg goal next` to surface one scoped feature, task, bug, or test at a time; normal `mdkg next` remains for non-goal concrete work.
|
|
28
|
+
- Use `mdkg goal claim [goal-id] <work-id>` only after accepting the surfaced work item; `mdkg goal next` is read-only.
|
|
29
|
+
- Treat goal `required_checks` as report-only guidance from mdkg. Run commands yourself, then record evidence in the goal or active work item.
|
|
30
|
+
- Record skill improvement candidates during normal goal execution; edit `SKILL.md` only when the active node is explicit skill-maintenance work.
|
|
26
31
|
- Use `mdkg skill list`, `mdkg skill search`, and `mdkg skill show <slug>` for skill discovery.
|
|
27
32
|
- Use `mdkg capability list/search/show` for deterministic skills, `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
|
|
28
33
|
- Use `mdkg index` to refresh JSON compatibility caches and `.mdkg/index/mdkg.sqlite` when SQLite mode is enabled.
|
|
@@ -37,7 +42,7 @@ Agent operating prompt:
|
|
|
37
42
|
- Mark archive sidecars public only with explicit `mdkg archive add --visibility public` intent.
|
|
38
43
|
- Treat sidecar `.md` plus deterministic `.zip` caches as the commit-eligible archive record; validation and `mdkg archive verify` both check ZIP payload integrity.
|
|
39
44
|
- 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`.
|
|
40
|
-
- Use `mdkg task start/update/done` for structured task, bug, and test lifecycle fields.
|
|
45
|
+
- Use `mdkg task start/update/done` for structured feature, task, bug, and test lifecycle fields.
|
|
41
46
|
- Use `mdkg upgrade` to preview scaffold updates; only run `mdkg upgrade --apply` after reviewing the receipt.
|
|
42
47
|
- Keep nuanced summaries, body text, and manual parent closeout edits in markdown.
|
|
43
48
|
- Use `mdkg event enable` only if `events.jsonl` is missing and provenance should be restored.
|
|
@@ -51,6 +56,16 @@ If the active task is known:
|
|
|
51
56
|
- `mdkg task done <id>` when work is complete
|
|
52
57
|
- `mdkg validate`
|
|
53
58
|
|
|
59
|
+
If an active goal is known:
|
|
60
|
+
- `mdkg goal select <goal-id>`
|
|
61
|
+
- `mdkg goal current`
|
|
62
|
+
- `mdkg goal next`
|
|
63
|
+
- `mdkg goal claim <work-id>`
|
|
64
|
+
- work the selected concrete node to completion
|
|
65
|
+
- run required checks and record evidence
|
|
66
|
+
- `mdkg goal evaluate <goal-id>`
|
|
67
|
+
- repeat until the goal condition is achieved, blocked, paused, or budget-limited
|
|
68
|
+
|
|
54
69
|
If no task is known:
|
|
55
70
|
- `mdkg search "..."`
|
|
56
71
|
- `mdkg show <id>`
|
|
@@ -19,6 +19,7 @@ Primary commands:
|
|
|
19
19
|
- `mdkg archive`
|
|
20
20
|
- `mdkg bundle`
|
|
21
21
|
- `mdkg work`
|
|
22
|
+
- `mdkg goal`
|
|
22
23
|
- `mdkg task`
|
|
23
24
|
- `mdkg validate`
|
|
24
25
|
|
|
@@ -32,6 +33,7 @@ Validation commands:
|
|
|
32
33
|
|
|
33
34
|
Node creation commands:
|
|
34
35
|
- `mdkg new <type> "<title>" [options] [--json]`
|
|
36
|
+
- `mdkg new goal "<title>" [options] [--json]`
|
|
35
37
|
|
|
36
38
|
Agent workflow file type creation:
|
|
37
39
|
- `mdkg new spec "<title>" [options] [--json]`
|
|
@@ -48,6 +50,7 @@ Agent workflow notes:
|
|
|
48
50
|
- `--id <portable-id>` is only for agent workflow file types.
|
|
49
51
|
- `spec` and `work` scaffold as validation-clean standalone docs.
|
|
50
52
|
- `work_order`, `receipt`, `feedback`, `dispute`, and `proposal` need real refs before strict `mdkg validate` passes.
|
|
53
|
+
- `goal` nodes capture recursive objective state and required checks, but normal `mdkg next` does not select them.
|
|
51
54
|
|
|
52
55
|
Workspace registry commands:
|
|
53
56
|
- `mdkg workspace ls [--json]`
|
|
@@ -146,6 +149,30 @@ Work semantic mirrors:
|
|
|
146
149
|
- `artifact://...` refs identify external/runtime-managed artifacts; `archive://...` refs identify committed mdkg archive sidecars
|
|
147
150
|
- work update and artifact commands accept local ids or local qids; subgraph qids are read-only and must be changed in their source workspace
|
|
148
151
|
|
|
152
|
+
Goal nodes:
|
|
153
|
+
- `mdkg goal show <goal-id-or-qid> [--json]`
|
|
154
|
+
- `mdkg goal select <goal-id-or-qid> [--json]`
|
|
155
|
+
- `mdkg goal current [--json]`
|
|
156
|
+
- `mdkg goal clear [--json]`
|
|
157
|
+
- `mdkg goal next [goal-id-or-qid] [--json]`
|
|
158
|
+
- `mdkg goal claim [goal-id-or-qid] <work-id-or-qid> [--json]`
|
|
159
|
+
- `mdkg goal evaluate <goal-id-or-qid> [--json]`
|
|
160
|
+
- `mdkg goal pause|resume|done <goal-id-or-qid> [--json]`
|
|
161
|
+
- `mdkg goal show <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
162
|
+
- `mdkg goal select <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
163
|
+
- `mdkg goal current [--ws <alias>] [--json]`
|
|
164
|
+
- `mdkg goal next [goal-id-or-qid] [--ws <alias>] [--json]`
|
|
165
|
+
- `mdkg goal claim <work-id-or-qid> [--ws <alias>] [--json]`
|
|
166
|
+
- `mdkg goal claim <goal-id-or-qid> <work-id-or-qid> [--ws <alias>] [--json]`
|
|
167
|
+
- `mdkg goal evaluate <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
168
|
+
- `mdkg goal pause <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
169
|
+
- `mdkg goal resume <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
170
|
+
- `mdkg goal done <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
171
|
+
- goals orchestrate recursive progress through explicit `scope_refs`; tasks, bugs, tests, and features remain concrete executable units
|
|
172
|
+
- `goal next` is read-only; use `goal claim` to set `active_node`
|
|
173
|
+
- `mdkg goal evaluate` is report-only and never runs commands from `required_checks`
|
|
174
|
+
- skill improvements discovered during normal goal execution should be recorded as candidates or proposals unless the active node is skill-maintenance
|
|
175
|
+
|
|
149
176
|
Discovery/show export flags:
|
|
150
177
|
- `--json`
|
|
151
178
|
- `--xml`
|
package/dist/init/README.md
CHANGED
|
@@ -30,7 +30,7 @@ mdkg subgraph list --json
|
|
|
30
30
|
mdkg validate
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
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 capability resolve ...` to rank local and subgraph capabilities, `mdkg archive ...` to register source/artifact sidecars, `mdkg work ...` to create work contract/order/receipt semantic mirrors, `mdkg bundle ...` to create full graph snapshot bundles, `mdkg subgraph ...` to register read-only child graph planning views, `mdkg pack <id>` to build deterministic context, and `mdkg validate` before closeout.
|
|
33
|
+
This repo is already initialized. Use `mdkg upgrade` to preview safe scaffold updates, `mdkg new` to create work, `mdkg new goal "..."` plus `mdkg goal select/current/next/claim/evaluate` for recursive long-running objectives, `mdkg search`/`mdkg show` to inspect graph state, `mdkg capability ...` to inspect cached skill/spec/work/core/design capabilities, `mdkg capability resolve ...` to rank local and subgraph capabilities, `mdkg archive ...` to register source/artifact sidecars, `mdkg work ...` to create work contract/order/receipt semantic mirrors, `mdkg bundle ...` to create full graph snapshot bundles, `mdkg subgraph ...` to register read-only child graph planning views, `mdkg pack <id>` to build deterministic context, and `mdkg validate` before closeout.
|
|
34
34
|
|
|
35
35
|
Agent workflow docs can use semantic ids:
|
|
36
36
|
|
|
@@ -157,6 +157,7 @@ If a user provides an unqualified ID and it is ambiguous globally:
|
|
|
157
157
|
- uses global templates (root-only) via token substitution
|
|
158
158
|
- writes into the appropriate workspace-local `.mdkg/<area>/` folder
|
|
159
159
|
- updates index if necessary
|
|
160
|
+
- supports `goal` nodes for recursive objective contracts
|
|
160
161
|
|
|
161
162
|
Common flags:
|
|
162
163
|
- `--ws <alias>` (default `root`)
|
|
@@ -176,6 +177,27 @@ Common flags:
|
|
|
176
177
|
- `--skills <slug,slug,...>` (work items)
|
|
177
178
|
- `--template <set>` (default from config)
|
|
178
179
|
|
|
180
|
+
### Goal commands
|
|
181
|
+
- `mdkg goal show <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
182
|
+
- reports condition, goal state, scope refs, active node, required skills, required checks, and source path
|
|
183
|
+
- `mdkg goal select <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
184
|
+
- stores local ignored selected-goal state at `.mdkg/state/selected-goal.json`
|
|
185
|
+
- `mdkg goal current [--ws <alias>] [--json]`
|
|
186
|
+
- reports selected goal or a unique active goal fallback without requiring committed state
|
|
187
|
+
- `mdkg goal clear [--json]`
|
|
188
|
+
- clears local selected-goal state
|
|
189
|
+
- `mdkg goal next [goal-id-or-qid] [--ws <alias>] [--json]`
|
|
190
|
+
- read-only; resolves explicit id, then selected goal, then one unique active goal
|
|
191
|
+
- recursively expands `scope_refs` through `epic` and `parent` edges
|
|
192
|
+
- selects local `feat`, `task`, `bug`, or `test` work and never returns the goal or container-only epic itself
|
|
193
|
+
- `mdkg goal claim [goal-id-or-qid] <work-id-or-qid> [--ws <alias>] [--json]`
|
|
194
|
+
- explicit mutating path that writes goal `active_node` after the work is confirmed inside scope
|
|
195
|
+
- `mdkg goal evaluate <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
196
|
+
- report-only; lists required checks and completion evidence state without executing scripts
|
|
197
|
+
- `mdkg goal pause|resume|done <goal-id-or-qid> [--ws <alias>] [--json]`
|
|
198
|
+
- updates `goal_state`, compatible work status, and `updated`
|
|
199
|
+
- subgraph goal qids are read-only and must be changed in their source workspace
|
|
200
|
+
|
|
179
201
|
### Read/search
|
|
180
202
|
- `mdkg show <id-or-qid> [--meta] [--json|--xml|--toon|--md]`
|
|
181
203
|
- default behavior shows the full node body
|
|
@@ -290,6 +312,7 @@ Common flags:
|
|
|
290
312
|
- `mdkg next [<id-or-qid>] [--ws <alias>]`
|
|
291
313
|
- If `<id>` provided: follow `next` if present; otherwise fall back to priority-based selection.
|
|
292
314
|
- If no `<id>` provided: use priority-based selection (and optionally an epic filter in future).
|
|
315
|
+
- Does not select `goal` nodes; use `mdkg goal select <goal-id>` plus `mdkg goal next`, or explicit `mdkg goal next <goal-id>`, for goal-scoped selection.
|
|
293
316
|
|
|
294
317
|
### Checkpoints
|
|
295
318
|
- `mdkg checkpoint new "<title>" [--ws <alias>] [--relates <id,...>] [--scope <id,...>]`
|
|
@@ -310,6 +333,9 @@ Common flags:
|
|
|
310
333
|
- `TASK_STARTED`
|
|
311
334
|
- `TASK_UPDATED`
|
|
312
335
|
- `TASK_DONE`
|
|
336
|
+
- `GOAL_PAUSE`
|
|
337
|
+
- `GOAL_RESUME`
|
|
338
|
+
- `GOAL_DONE`
|
|
313
339
|
|
|
314
340
|
### Validation and formatting
|
|
315
341
|
- `mdkg validate`
|
|
@@ -23,6 +23,7 @@ mdkg content may contain sensitive notes and internal project planning. This rul
|
|
|
23
23
|
- `.mdkg/` must not be published to npm.
|
|
24
24
|
- Generated JSON index, temp, lock, WAL, SHM, and journal files under `.mdkg/index/` must not be committed.
|
|
25
25
|
- `.mdkg/index/mdkg.sqlite` is a rebuildable access cache and may be committed when the repo intentionally tracks it and it stays reasonably small.
|
|
26
|
+
- `.mdkg/state/` stores local workflow convenience state and must not be committed.
|
|
26
27
|
- `.mdkg/bundles/` may be committed only when the repo intentionally tracks private or public snapshot bundles.
|
|
27
28
|
|
|
28
29
|
## Git ignore requirements
|
|
@@ -37,6 +38,7 @@ The repo MUST ignore at minimum:
|
|
|
37
38
|
- `.mdkg/index/*.sqlite-wal`
|
|
38
39
|
- `.mdkg/index/*.sqlite-shm`
|
|
39
40
|
- `.mdkg/index/*.sqlite-journal`
|
|
41
|
+
- `.mdkg/state/`
|
|
40
42
|
- `.mdkg/pack/`
|
|
41
43
|
- `.mdkg/archive/**/source/`
|
|
42
44
|
|
|
@@ -47,6 +49,7 @@ Recommended `.gitignore` entries:
|
|
|
47
49
|
- `.mdkg/index/*.sqlite-wal`
|
|
48
50
|
- `.mdkg/index/*.sqlite-shm`
|
|
49
51
|
- `.mdkg/index/*.sqlite-journal`
|
|
52
|
+
- `.mdkg/state/`
|
|
50
53
|
- `.mdkg/pack/`
|
|
51
54
|
- `.mdkg/archive/**/source/`
|
|
52
55
|
|
|
@@ -87,7 +90,7 @@ For application builds:
|
|
|
87
90
|
|
|
88
91
|
`mdkg init` updates ignore files by default for safety:
|
|
89
92
|
|
|
90
|
-
- `.gitignore` appends generated index cache/temp/lock patterns, `.mdkg/pack/`, and raw archive source ignores.
|
|
93
|
+
- `.gitignore` appends generated index cache/temp/lock patterns, `.mdkg/state/`, `.mdkg/pack/`, and raw archive source ignores.
|
|
91
94
|
- `.npmignore` appends `.mdkg/`, generated index cache/temp/lock patterns, and `.mdkg/pack/`.
|
|
92
95
|
- `--no-update-ignores` disables these default writes
|
|
93
96
|
|
|
@@ -102,6 +105,7 @@ Explicit flags remain available and take precedence:
|
|
|
102
105
|
- `.mdkg/index/` contains generated caches.
|
|
103
106
|
- JSON index files may contain extracted metadata and could expose sensitive strings; they MUST be ignored from git.
|
|
104
107
|
- `.mdkg/index/mdkg.sqlite` contains the same rebuildable access data and may be committed only by explicit repo policy; `mdkg doctor` warns when it exceeds `index.sqlite_commit_warning_bytes`.
|
|
108
|
+
- `.mdkg/state/` contains local workflow convenience state such as selected goals and MUST stay ignored.
|
|
105
109
|
- Index rebuild should be deterministic and safe to regenerate at any time.
|
|
106
110
|
|
|
107
111
|
## Bundle safety
|
|
@@ -131,6 +135,7 @@ Workspace-local `.mdkg/` directories (near code) should follow the same rules:
|
|
|
131
135
|
## Summary checklist
|
|
132
136
|
|
|
133
137
|
- ✅ generated JSON index/temp/lock files ignored
|
|
138
|
+
- ✅ local `.mdkg/state/` ignored
|
|
134
139
|
- ✅ `.mdkg/index/mdkg.sqlite` committed only by explicit repo policy
|
|
135
140
|
- ✅ event logs are committed by default unless a repo chooses to ignore them manually
|
|
136
141
|
- ✅ npm publishes only `dist/`, `README.md`, `LICENSE`
|
|
@@ -91,12 +91,21 @@ All nodes MAY include the following searchable frontmatter lists:
|
|
|
91
91
|
List fields SHOULD be written as `[]` when empty.
|
|
92
92
|
Optional scalar graph fields (like `epic`, `parent`, `prev`, `next`) should be omitted when empty.
|
|
93
93
|
|
|
94
|
-
Work items (`epic/feat/task/bug/checkpoint/test`):
|
|
94
|
+
Work items (`goal/epic/feat/task/bug/checkpoint/test`):
|
|
95
95
|
- `status` (enum)
|
|
96
96
|
- optional `priority` (0..9)
|
|
97
97
|
- optional `skills: [slug, ...]` (kebab-case skill slugs)
|
|
98
98
|
- optional graph edges: `epic`, `parent`, `relates`, `blocked_by`, `blocks`, `prev`, `next`
|
|
99
99
|
|
|
100
|
+
Goal nodes (`goal-*`):
|
|
101
|
+
- required `goal_state`: `active`, `paused`, `achieved`, `blocked`, or `budget_limited`
|
|
102
|
+
- required `goal_condition` up to 4000 characters for external slash-command compatibility
|
|
103
|
+
- optional `scope_refs: [id-or-qid, ...]` naming explicit goal ownership roots; allowed targets are `epic`, `feat`, `task`, `bug`, and `test`
|
|
104
|
+
- optional `active_node`
|
|
105
|
+
- optional `required_skills: [slug, ...]`
|
|
106
|
+
- optional `required_checks: [command, ...]` as report-only guidance; mdkg does not execute these scripts
|
|
107
|
+
- optional positive integer strings `max_iterations` and `blocked_after_attempts`
|
|
108
|
+
|
|
100
109
|
Decision records (`dec-*`):
|
|
101
110
|
- `status` (enum: `proposed`, `accepted`, `rejected`, `superseded`)
|
|
102
111
|
- optional `supersedes: dec-#`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"tool": "mdkg",
|
|
4
|
-
"mdkg_version": "0.1.
|
|
4
|
+
"mdkg_version": "0.1.6",
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
7
7
|
"path": ".mdkg/config.json",
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
{
|
|
37
37
|
"path": ".mdkg/core/rule-3-cli-contract.md",
|
|
38
38
|
"category": "core",
|
|
39
|
-
"sha256": "
|
|
39
|
+
"sha256": "0b72a2448cc91779278fed6e011c3936c31c5b11a7365a4145941dcc90f805a3"
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"path": ".mdkg/core/rule-4-repo-safety-and-ignores.md",
|
|
43
43
|
"category": "core",
|
|
44
|
-
"sha256": "
|
|
44
|
+
"sha256": "d8aff39af7a00e63db51831d4324856bbf49d3e3434141416903bad42c7d5380"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"path": ".mdkg/core/rule-5-release-and-versioning.md",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
{
|
|
52
52
|
"path": ".mdkg/core/rule-6-templates-and-schemas.md",
|
|
53
53
|
"category": "core",
|
|
54
|
-
"sha256": "
|
|
54
|
+
"sha256": "3ae20e1a925154ddc69bfc79495b169500aa5158db2134336890b00e64750c2f"
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"path": ".mdkg/core/SOUL.md",
|
|
@@ -61,22 +61,27 @@
|
|
|
61
61
|
{
|
|
62
62
|
"path": ".mdkg/README.md",
|
|
63
63
|
"category": "mdkg_doc",
|
|
64
|
-
"sha256": "
|
|
64
|
+
"sha256": "f733792daa2b0f3318fd7b39fa2f812c61b8a3f5f630dba2f271cdcb10af9927"
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"path": ".mdkg/skills/build-pack-and-execute-task/SKILL.md",
|
|
68
68
|
"category": "default_skill",
|
|
69
69
|
"sha256": "3e240cb844b22e5e4c0046a4f839ac3c0d771a62d00a72719fc449477564b1ae"
|
|
70
70
|
},
|
|
71
|
+
{
|
|
72
|
+
"path": ".mdkg/skills/pursue-mdkg-goal/SKILL.md",
|
|
73
|
+
"category": "default_skill",
|
|
74
|
+
"sha256": "fd64f666fb1329c392ff0979ed9999b71ad948cbca6a191502eb2cdfd76ec825"
|
|
75
|
+
},
|
|
71
76
|
{
|
|
72
77
|
"path": ".mdkg/skills/select-work-and-ground-context/SKILL.md",
|
|
73
78
|
"category": "default_skill",
|
|
74
|
-
"sha256": "
|
|
79
|
+
"sha256": "e50fc3b1a2c79a9a3544ca9df1bf4ca9c312e7c3a51d5e4c6f3314341eca268b"
|
|
75
80
|
},
|
|
76
81
|
{
|
|
77
82
|
"path": ".mdkg/skills/verify-close-and-checkpoint/SKILL.md",
|
|
78
83
|
"category": "default_skill",
|
|
79
|
-
"sha256": "
|
|
84
|
+
"sha256": "f85ffa4a139db10c3bc3203cde0e4f41603fbc7f3925e6fdaba821346ffa28b8"
|
|
80
85
|
},
|
|
81
86
|
{
|
|
82
87
|
"path": ".mdkg/templates/default/archive.md",
|
|
@@ -123,6 +128,11 @@
|
|
|
123
128
|
"category": "template",
|
|
124
129
|
"sha256": "61ad7b8b717d17736ba505f814fa6e4f9ec61f7fe4ae6622359304620a99d649"
|
|
125
130
|
},
|
|
131
|
+
{
|
|
132
|
+
"path": ".mdkg/templates/default/goal.md",
|
|
133
|
+
"category": "template",
|
|
134
|
+
"sha256": "710252d8a2dc35be71661d6988007af127052fa8ad24b1fb00374c975ae117a2"
|
|
135
|
+
},
|
|
126
136
|
{
|
|
127
137
|
"path": ".mdkg/templates/default/prd.md",
|
|
128
138
|
"category": "template",
|
|
@@ -176,7 +186,7 @@
|
|
|
176
186
|
{
|
|
177
187
|
"path": "AGENT_START.md",
|
|
178
188
|
"category": "startup_doc",
|
|
179
|
-
"sha256": "
|
|
189
|
+
"sha256": "7676e534b2f161a19764de666d9362b9ee1c6cdec6ec9fdfacab2eb52ce0e80d"
|
|
180
190
|
},
|
|
181
191
|
{
|
|
182
192
|
"path": "AGENTS.md",
|
|
@@ -191,7 +201,7 @@
|
|
|
191
201
|
{
|
|
192
202
|
"path": "CLI_COMMAND_MATRIX.md",
|
|
193
203
|
"category": "startup_doc",
|
|
194
|
-
"sha256": "
|
|
204
|
+
"sha256": "a2f59afae403fff7335b0cf0109ee550c7a864b9ef6744b39a645096432e5206"
|
|
195
205
|
},
|
|
196
206
|
{
|
|
197
207
|
"path": "llms.txt",
|