mdkg 0.1.6 → 0.1.7
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 +30 -0
- package/README.md +54 -3
- package/dist/cli.js +208 -3
- package/dist/commands/bundle.js +6 -0
- package/dist/commands/checkpoint.js +1 -1
- package/dist/commands/db.js +560 -0
- package/dist/commands/doctor.js +18 -0
- package/dist/commands/format.js +10 -5
- package/dist/commands/index.js +16 -11
- package/dist/commands/init.js +3 -0
- package/dist/commands/new.js +17 -2
- package/dist/commands/subgraph.js +416 -0
- package/dist/commands/upgrade.js +43 -7
- package/dist/commands/work.js +21 -19
- package/dist/core/config.js +103 -0
- package/dist/core/project_db.js +108 -0
- package/dist/core/project_db_migrations.js +600 -0
- package/dist/core/project_db_snapshot.js +510 -0
- package/dist/graph/agent_file_types.js +14 -9
- package/dist/graph/node.js +2 -2
- package/dist/graph/skills_index_cache.js +1 -0
- package/dist/graph/sqlite_index.js +25 -0
- package/dist/graph/validate_graph.js +75 -63
- package/dist/init/AGENT_START.md +13 -1
- package/dist/init/CLI_COMMAND_MATRIX.md +37 -0
- package/dist/init/README.md +25 -0
- package/dist/init/config.json +11 -0
- package/dist/init/core/rule-3-cli-contract.md +7 -0
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +35 -2
- package/dist/init/init-manifest.json +7 -7
- package/dist/util/argparse.js +5 -0
- package/dist/util/refs.js +2 -2
- package/package.json +4 -2
|
@@ -34,7 +34,15 @@ function validateEdgeTargets(index, allowMissing, knownSkillSlugs, externalWorks
|
|
|
34
34
|
}
|
|
35
35
|
for (const [edgeKey, values] of edgeLists) {
|
|
36
36
|
for (const value of values) {
|
|
37
|
-
|
|
37
|
+
const targetNode = nodes[value];
|
|
38
|
+
if (targetNode &&
|
|
39
|
+
["epic", "parent", "prev", "next"].includes(edgeKey) &&
|
|
40
|
+
!node.source?.imported &&
|
|
41
|
+
targetNode.source?.imported) {
|
|
42
|
+
pushError(errors, `${qid}: ${edgeKey} cannot target read-only subgraph node ${value}`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!targetNode) {
|
|
38
46
|
const [workspace] = value.split(":");
|
|
39
47
|
if (workspace && externalWorkspaces?.has(workspace)) {
|
|
40
48
|
continue;
|
|
@@ -106,6 +114,18 @@ function pathEndsWithContractRef(nodePath, contractRef) {
|
|
|
106
114
|
return (normalizedNodePath === normalizedContractRef ||
|
|
107
115
|
normalizedNodePath.endsWith(`/${normalizedContractRef}`));
|
|
108
116
|
}
|
|
117
|
+
function resolveNodeRef(index, ws, value) {
|
|
118
|
+
const qid = value.includes(":") ? value : `${ws}:${value}`;
|
|
119
|
+
return index.nodes[qid];
|
|
120
|
+
}
|
|
121
|
+
function resolveTypedNodeRef(index, ws, value, type) {
|
|
122
|
+
const node = resolveNodeRef(index, ws, value);
|
|
123
|
+
return node?.type === type ? node : undefined;
|
|
124
|
+
}
|
|
125
|
+
function isExternalWorkspaceRef(value, externalWorkspaces) {
|
|
126
|
+
const [workspace] = value.split(":");
|
|
127
|
+
return Boolean(workspace && value.includes(":") && externalWorkspaces?.has(workspace));
|
|
128
|
+
}
|
|
109
129
|
function validateAgentWorkflowSpecWorkContracts(index, allowMissing, errors) {
|
|
110
130
|
const workNodesByWorkspace = {};
|
|
111
131
|
for (const node of Object.values(index.nodes)) {
|
|
@@ -156,20 +176,7 @@ function validateAgentWorkflowSpecWorkContracts(index, allowMissing, errors) {
|
|
|
156
176
|
}
|
|
157
177
|
}
|
|
158
178
|
}
|
|
159
|
-
function validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, errors) {
|
|
160
|
-
const workNodesByWorkspaceAndId = {};
|
|
161
|
-
for (const node of Object.values(index.nodes)) {
|
|
162
|
-
if (node.type !== "work") {
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
if (!workNodesByWorkspaceAndId[node.ws]) {
|
|
166
|
-
workNodesByWorkspaceAndId[node.ws] = {};
|
|
167
|
-
}
|
|
168
|
-
workNodesByWorkspaceAndId[node.ws][node.id] = {
|
|
169
|
-
qid: node.qid,
|
|
170
|
-
version: typeof node.attributes.version === "string" ? node.attributes.version : undefined,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
179
|
+
function validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, externalWorkspaces, errors) {
|
|
173
180
|
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
174
181
|
if (node.type !== "work_order") {
|
|
175
182
|
continue;
|
|
@@ -178,8 +185,11 @@ function validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, errors) {
|
|
|
178
185
|
if (typeof workId !== "string") {
|
|
179
186
|
continue;
|
|
180
187
|
}
|
|
181
|
-
const workNode =
|
|
188
|
+
const workNode = resolveTypedNodeRef(index, node.ws, workId, "work");
|
|
182
189
|
if (!workNode) {
|
|
190
|
+
if (isExternalWorkspaceRef(workId, externalWorkspaces)) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
183
193
|
if (allowMissing) {
|
|
184
194
|
continue;
|
|
185
195
|
}
|
|
@@ -188,23 +198,13 @@ function validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, errors) {
|
|
|
188
198
|
}
|
|
189
199
|
const workVersion = node.attributes.work_version;
|
|
190
200
|
if (typeof workVersion === "string" &&
|
|
191
|
-
workNode.version
|
|
192
|
-
workVersion !== workNode.version) {
|
|
193
|
-
pushError(errors, `${qid}: work_version ${workVersion} does not match ${workNode.qid} version ${workNode.version}`);
|
|
201
|
+
typeof workNode.attributes.version === "string" &&
|
|
202
|
+
workVersion !== workNode.attributes.version) {
|
|
203
|
+
pushError(errors, `${qid}: work_version ${workVersion} does not match ${workNode.qid} version ${workNode.attributes.version}`);
|
|
194
204
|
}
|
|
195
205
|
}
|
|
196
206
|
}
|
|
197
|
-
function validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, errors) {
|
|
198
|
-
const workOrderIdsByWorkspace = {};
|
|
199
|
-
for (const node of Object.values(index.nodes)) {
|
|
200
|
-
if (node.type !== "work_order") {
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if (!workOrderIdsByWorkspace[node.ws]) {
|
|
204
|
-
workOrderIdsByWorkspace[node.ws] = new Set();
|
|
205
|
-
}
|
|
206
|
-
workOrderIdsByWorkspace[node.ws].add(node.id);
|
|
207
|
-
}
|
|
207
|
+
function validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, externalWorkspaces, errors) {
|
|
208
208
|
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
209
209
|
if (node.type !== "receipt") {
|
|
210
210
|
continue;
|
|
@@ -213,7 +213,10 @@ function validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, errors)
|
|
|
213
213
|
if (typeof workOrderId !== "string") {
|
|
214
214
|
continue;
|
|
215
215
|
}
|
|
216
|
-
if (
|
|
216
|
+
if (resolveTypedNodeRef(index, node.ws, workOrderId, "work_order")) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (isExternalWorkspaceRef(workOrderId, externalWorkspaces)) {
|
|
217
220
|
continue;
|
|
218
221
|
}
|
|
219
222
|
if (allowMissing) {
|
|
@@ -238,7 +241,17 @@ function buildSpecRolesByWorkspace(index) {
|
|
|
238
241
|
}
|
|
239
242
|
return specRolesByWorkspace;
|
|
240
243
|
}
|
|
241
|
-
function
|
|
244
|
+
function resolveSpecRole(index, ws, value) {
|
|
245
|
+
const node = resolveTypedNodeRef(index, ws, value, "spec");
|
|
246
|
+
if (!node) {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
qid: node.qid,
|
|
251
|
+
role: typeof node.attributes.role === "string" ? node.attributes.role : undefined,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function validateAgentWorkflowSubagentRefs(index, allowMissing, externalWorkspaces, errors) {
|
|
242
255
|
const specRolesByWorkspace = buildSpecRolesByWorkspace(index);
|
|
243
256
|
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
244
257
|
if (node.type !== "spec" && node.type !== "work") {
|
|
@@ -252,8 +265,13 @@ function validateAgentWorkflowSubagentRefs(index, allowMissing, errors) {
|
|
|
252
265
|
if (typeof value !== "string") {
|
|
253
266
|
continue;
|
|
254
267
|
}
|
|
255
|
-
const specNode =
|
|
268
|
+
const specNode = value.includes(":")
|
|
269
|
+
? resolveSpecRole(index, node.ws, value)
|
|
270
|
+
: specRolesByWorkspace[node.ws]?.[value];
|
|
256
271
|
if (!specNode) {
|
|
272
|
+
if (isExternalWorkspaceRef(value, externalWorkspaces)) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
257
275
|
if (allowMissing) {
|
|
258
276
|
continue;
|
|
259
277
|
}
|
|
@@ -266,28 +284,7 @@ function validateAgentWorkflowSubagentRefs(index, allowMissing, errors) {
|
|
|
266
284
|
}
|
|
267
285
|
}
|
|
268
286
|
}
|
|
269
|
-
function validateAgentWorkflowDisputeRefs(index, allowMissing, errors) {
|
|
270
|
-
const workOrderIdsByWorkspace = {};
|
|
271
|
-
const receiptNodesByWorkspaceAndId = {};
|
|
272
|
-
for (const node of Object.values(index.nodes)) {
|
|
273
|
-
if (node.type === "work_order") {
|
|
274
|
-
if (!workOrderIdsByWorkspace[node.ws]) {
|
|
275
|
-
workOrderIdsByWorkspace[node.ws] = new Set();
|
|
276
|
-
}
|
|
277
|
-
workOrderIdsByWorkspace[node.ws].add(node.id);
|
|
278
|
-
}
|
|
279
|
-
if (node.type === "receipt") {
|
|
280
|
-
if (!receiptNodesByWorkspaceAndId[node.ws]) {
|
|
281
|
-
receiptNodesByWorkspaceAndId[node.ws] = {};
|
|
282
|
-
}
|
|
283
|
-
receiptNodesByWorkspaceAndId[node.ws][node.id] = {
|
|
284
|
-
qid: node.qid,
|
|
285
|
-
workOrderId: typeof node.attributes.work_order_id === "string"
|
|
286
|
-
? node.attributes.work_order_id
|
|
287
|
-
: undefined,
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
}
|
|
287
|
+
function validateAgentWorkflowDisputeRefs(index, allowMissing, externalWorkspaces, errors) {
|
|
291
288
|
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
292
289
|
if (node.type !== "dispute") {
|
|
293
290
|
continue;
|
|
@@ -296,23 +293,35 @@ function validateAgentWorkflowDisputeRefs(index, allowMissing, errors) {
|
|
|
296
293
|
if (typeof workOrderId !== "string") {
|
|
297
294
|
continue;
|
|
298
295
|
}
|
|
299
|
-
if (!
|
|
296
|
+
if (!resolveTypedNodeRef(index, node.ws, workOrderId, "work_order") &&
|
|
297
|
+
!isExternalWorkspaceRef(workOrderId, externalWorkspaces) &&
|
|
298
|
+
!allowMissing) {
|
|
300
299
|
pushError(errors, `${qid}: work_order_id references missing WORK_ORDER.md ${workOrderId}`);
|
|
301
300
|
}
|
|
302
301
|
const receiptId = node.attributes.receipt_id;
|
|
303
302
|
if (typeof receiptId !== "string") {
|
|
304
303
|
continue;
|
|
305
304
|
}
|
|
306
|
-
const receiptNode =
|
|
305
|
+
const receiptNode = resolveTypedNodeRef(index, node.ws, receiptId, "receipt");
|
|
307
306
|
if (!receiptNode) {
|
|
307
|
+
if (isExternalWorkspaceRef(receiptId, externalWorkspaces)) {
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
308
310
|
if (allowMissing) {
|
|
309
311
|
continue;
|
|
310
312
|
}
|
|
311
313
|
pushError(errors, `${qid}: receipt_id references missing RECEIPT.md ${receiptId}`);
|
|
312
314
|
continue;
|
|
313
315
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
+
const receiptWorkOrderId = typeof receiptNode.attributes.work_order_id === "string"
|
|
317
|
+
? receiptNode.attributes.work_order_id
|
|
318
|
+
: undefined;
|
|
319
|
+
const receiptWorkOrderQid = receiptWorkOrderId
|
|
320
|
+
? receiptWorkOrderId.includes(":") ? receiptWorkOrderId : `${receiptNode.ws}:${receiptWorkOrderId}`
|
|
321
|
+
: undefined;
|
|
322
|
+
const disputeWorkOrderQid = workOrderId.includes(":") ? workOrderId : `${node.ws}:${workOrderId}`;
|
|
323
|
+
if (receiptWorkOrderQid !== undefined && receiptWorkOrderQid !== disputeWorkOrderQid) {
|
|
324
|
+
pushError(errors, `${qid}: receipt_id ${receiptId} belongs to work_order_id ${receiptWorkOrderId}, not ${workOrderId}`);
|
|
316
325
|
}
|
|
317
326
|
}
|
|
318
327
|
}
|
|
@@ -331,6 +340,9 @@ function validateAgentWorkflowNodeIdRef(qid, ws, field, value, nodeIdsByWorkspac
|
|
|
331
340
|
if (workspace && value.includes(":") && externalWorkspaces?.has(workspace)) {
|
|
332
341
|
return;
|
|
333
342
|
}
|
|
343
|
+
if (value.includes(":") && nodeIdsByWorkspace[workspace]?.has(value.split(":").slice(1).join(":"))) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
334
346
|
if (nodeIdsByWorkspace[ws]?.has(value)) {
|
|
335
347
|
return;
|
|
336
348
|
}
|
|
@@ -514,10 +526,10 @@ function collectGraphErrors(index, options = {}) {
|
|
|
514
526
|
validateEdgeTargets(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors);
|
|
515
527
|
validatePrevNextSymmetry(index, allowMissing, errors);
|
|
516
528
|
validateAgentWorkflowSpecWorkContracts(index, allowMissing, errors);
|
|
517
|
-
validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, errors);
|
|
518
|
-
validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, errors);
|
|
519
|
-
validateAgentWorkflowSubagentRefs(index, allowMissing, errors);
|
|
520
|
-
validateAgentWorkflowDisputeRefs(index, allowMissing, errors);
|
|
529
|
+
validateAgentWorkflowWorkOrderWorkRefs(index, allowMissing, externalWorkspaces, errors);
|
|
530
|
+
validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, externalWorkspaces, errors);
|
|
531
|
+
validateAgentWorkflowSubagentRefs(index, allowMissing, externalWorkspaces, errors);
|
|
532
|
+
validateAgentWorkflowDisputeRefs(index, allowMissing, externalWorkspaces, errors);
|
|
521
533
|
validateAgentWorkflowFeedbackProposalRefs(index, allowMissing, knownSkillSlugs, externalWorkspaces, errors);
|
|
522
534
|
validateArchiveUriRefs(index, allowMissing, errors);
|
|
523
535
|
validateGoalRefs(index, allowMissing, errors);
|
package/dist/init/AGENT_START.md
CHANGED
|
@@ -31,13 +31,25 @@ Agent operating prompt:
|
|
|
31
31
|
- Use `mdkg skill list`, `mdkg skill search`, and `mdkg skill show <slug>` for skill discovery.
|
|
32
32
|
- Use `mdkg capability list/search/show` for deterministic skills, `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
|
|
33
33
|
- Use `mdkg index` to refresh JSON compatibility caches and `.mdkg/index/mdkg.sqlite` when SQLite mode is enabled.
|
|
34
|
+
- Treat `.mdkg/db` as project application state; use `mdkg db init` to create
|
|
35
|
+
the generic scaffold and enable `db.enabled` without creating an active
|
|
36
|
+
runtime SQLite database. Use `mdkg db migrate` after init to create or update
|
|
37
|
+
the runtime SQLite database with mdkg-owned generic foundation migrations.
|
|
38
|
+
Use `mdkg db verify` and `mdkg db stats` for non-mutating health and summary
|
|
39
|
+
receipts. Use `mdkg db snapshot seal` for explicit sealed checkpoints,
|
|
40
|
+
`mdkg db snapshot verify/status` for checkpoint health, and
|
|
41
|
+
`mdkg db snapshot dump/diff` for deterministic review aids. Keep
|
|
42
|
+
`.mdkg/db/runtime/` and WAL/SHM/journal/lock/temp files ignored unless a
|
|
43
|
+
sealed artifact policy explicitly says otherwise.
|
|
34
44
|
- Use `mdkg archive add/list/show/verify/compress` for committed source and artifact sidecars under `.mdkg/archive`.
|
|
35
45
|
- Use `mdkg work ...` helpers for semantic mirror contracts, work orders, receipts, and artifact registration.
|
|
36
46
|
- Treat work contracts, orders, and receipts as committed semantic mirrors only; never store raw secrets, credentials, live payment state, ledger mutations, or canonical marketplace state in mdkg.
|
|
37
47
|
- Use `artifact://...` for external/runtime-managed artifacts and `archive://...` for committed mdkg archive sidecars.
|
|
38
48
|
- Use `mdkg bundle create/list/show/verify` for explicit full `.mdkg` graph snapshot bundles.
|
|
39
|
-
- Use `mdkg subgraph add/list/verify` to register child bundle snapshots as read-only planning context.
|
|
49
|
+
- Use `mdkg subgraph add/list/verify/sync/materialize` to register child bundle snapshots as read-only planning context, refresh root-owned child bundle snapshots, and optionally generate ignored inspection trees.
|
|
40
50
|
- Use `mdkg capability resolve` to rank local and subgraph capabilities for orchestration planning.
|
|
51
|
+
- Use `mdkg subgraph sync --dry-run --json` before refreshing root-owned child bundle snapshots, then `mdkg subgraph sync --json` when the receipt is acceptable.
|
|
52
|
+
- Use `mdkg subgraph materialize ... --target .mdkg/subgraphs --gitignore` only for generated read-only inspection trees; never mutate materialized files.
|
|
41
53
|
- Use `mdkg pack <id> --visibility public|internal` only when you need a public-safe or internal-safe pack; no flag remains private-capable local behavior.
|
|
42
54
|
- Mark archive sidecars public only with explicit `mdkg archive add --visibility public` intent.
|
|
43
55
|
- Treat sidecar `.md` plus deterministic `.zip` caches as the commit-eligible archive record; validation and `mdkg archive verify` both check ZIP payload integrity.
|
|
@@ -27,6 +27,39 @@ Index backend:
|
|
|
27
27
|
- fresh mdkg workspaces default to `index.backend: sqlite`
|
|
28
28
|
- `.mdkg/index/mdkg.sqlite` is rebuildable and commit-eligible when intentionally tracked
|
|
29
29
|
- JSON compatibility caches remain generated and ignored by default
|
|
30
|
+
- `mdkg db index rebuild` writes the same derived caches as `mdkg index`
|
|
31
|
+
- `mdkg db index status` reports graph cache health without mutating files
|
|
32
|
+
- `mdkg db index verify` fails on missing, stale, corrupt, schema-mismatched, or SQLite source-fingerprint-mismatched cache state
|
|
33
|
+
|
|
34
|
+
Project database commands:
|
|
35
|
+
- `mdkg db index rebuild [--tolerant] [--json]`
|
|
36
|
+
- `mdkg db index status [--json]`
|
|
37
|
+
- `mdkg db index verify [--json]`
|
|
38
|
+
- `mdkg db init [--json]`
|
|
39
|
+
- `mdkg db migrate [--json]`
|
|
40
|
+
- `mdkg db verify [--json]`
|
|
41
|
+
- `mdkg db stats [--json]`
|
|
42
|
+
- `mdkg db snapshot seal [--json]`
|
|
43
|
+
- `mdkg db snapshot verify [--json]`
|
|
44
|
+
- `mdkg db snapshot status [--json]`
|
|
45
|
+
- `mdkg db snapshot dump [--snapshot <path>] [--output <path>] [--json]`
|
|
46
|
+
- `mdkg db snapshot diff <left-snapshot> <right-snapshot> [--json]`
|
|
47
|
+
- `.mdkg/db` is project application state, separate from `.mdkg/index`
|
|
48
|
+
- `mdkg db init` creates the generic `.mdkg/db` scaffold, writes
|
|
49
|
+
`.mdkg/db/project-db.json`, enables `db.enabled`, and does not create an
|
|
50
|
+
active runtime SQLite database
|
|
51
|
+
- `mdkg db migrate` creates or updates the configured active runtime SQLite
|
|
52
|
+
database and applies mdkg-owned generic foundation migrations only
|
|
53
|
+
- `mdkg db migrate` records migration order, checksums, and applied timestamps
|
|
54
|
+
in the configured migration table
|
|
55
|
+
- `mdkg db verify` checks config, layout, runtime SQLite integrity, migration
|
|
56
|
+
metadata, receipt directory policy, and transient runtime files
|
|
57
|
+
- `mdkg db stats` reports table counts, database size, migration state,
|
|
58
|
+
transient runtime files, receipt-file count, and state snapshot presence
|
|
59
|
+
- `mdkg db snapshot seal` writes an opt-in sealed checkpoint and manifest under
|
|
60
|
+
`.mdkg/db/state`; `snapshot verify/status/dump/diff` inspect and review that
|
|
61
|
+
checkpoint without treating raw binary diffs as human-readable truth
|
|
62
|
+
- active `.mdkg/db/runtime/` files and `.mdkg/db` WAL/SHM/journal/lock/temp files are ignored by default
|
|
30
63
|
|
|
31
64
|
Validation commands:
|
|
32
65
|
- `mdkg validate [--out <path>] [--quiet] [--json]`
|
|
@@ -133,8 +166,12 @@ Subgraph orchestration:
|
|
|
133
166
|
- `mdkg subgraph disable <alias> [--json]`
|
|
134
167
|
- `mdkg subgraph verify [alias|--all] [--json]`
|
|
135
168
|
- `mdkg subgraph refresh [alias|--all] [--json]`
|
|
169
|
+
- `mdkg subgraph sync [alias|--all] [--dry-run] [--allow-dirty] [--json]`
|
|
170
|
+
- `mdkg subgraph materialize [alias|--all] --target <path> [--clean] [--gitignore] [--json]`
|
|
136
171
|
- subgraphs are read-only planning views and use subgraph-alias qids such as `child_repo:task-1`
|
|
137
172
|
- subgraph refresh reloads configured bundle sources only and never mutates child repos
|
|
173
|
+
- subgraph sync builds root-owned bundle snapshots from configured clean child Git repo `source_path` entries
|
|
174
|
+
- subgraph materialize extracts generated inspection trees under a target directory; `.mdkg/subgraphs/` is local generated state
|
|
138
175
|
- public/internal subgraphs require public bundle profiles
|
|
139
176
|
|
|
140
177
|
Work semantic mirrors:
|
package/dist/init/README.md
CHANGED
|
@@ -13,6 +13,7 @@ mdkg is pre-v1 public alpha software. Graph, cache, bundle, and DAL contracts ma
|
|
|
13
13
|
- `archive/`: sidecar metadata and deterministic compressed source/artifact caches
|
|
14
14
|
- `bundles/`: optional committed full graph snapshot bundles
|
|
15
15
|
- `index/`: generated JSON caches plus optional commit-eligible `mdkg.sqlite`
|
|
16
|
+
- `db/`: future project application database layout and receipts
|
|
16
17
|
- `pack/`: generated context packs (do not commit)
|
|
17
18
|
|
|
18
19
|
## Next Commands
|
|
@@ -59,11 +60,31 @@ Ensure ignore files include:
|
|
|
59
60
|
- `.mdkg/index/*.sqlite-wal`
|
|
60
61
|
- `.mdkg/index/*.sqlite-shm`
|
|
61
62
|
- `.mdkg/index/*.sqlite-journal`
|
|
63
|
+
- `.mdkg/db/runtime/`
|
|
64
|
+
- `.mdkg/db/**/*.sqlite-wal`
|
|
65
|
+
- `.mdkg/db/**/*.sqlite-shm`
|
|
66
|
+
- `.mdkg/db/**/*.sqlite-journal`
|
|
67
|
+
- `.mdkg/db/**/*.lock`
|
|
68
|
+
- `.mdkg/db/**/*.tmp`
|
|
62
69
|
- `.mdkg/pack/`
|
|
63
70
|
- `.mdkg/archive/**/source/`
|
|
64
71
|
|
|
65
72
|
Fresh mdkg workspaces default to `index.backend: sqlite`; `.mdkg/index/mdkg.sqlite` is a rebuildable cache and may be committed when the repo intentionally tracks it and it stays reasonably small.
|
|
66
73
|
|
|
74
|
+
`.mdkg/db` is reserved for project application database state, separate from
|
|
75
|
+
`.mdkg/index`. Run `mdkg db init` to create the generic scaffold, write
|
|
76
|
+
`.mdkg/db/project-db.json`, and enable `db.enabled`; it does not create an
|
|
77
|
+
active runtime SQLite database. Run `mdkg db migrate` after init to create or
|
|
78
|
+
update the active runtime SQLite database with mdkg-owned generic foundation
|
|
79
|
+
migrations. Use `mdkg db verify` for non-mutating health checks and
|
|
80
|
+
`mdkg db stats` for table counts, DB size, migration state, and receipt-file
|
|
81
|
+
counts. Use `mdkg db snapshot seal` to create an opt-in sealed checkpoint under
|
|
82
|
+
`.mdkg/db/state`, then use `mdkg db snapshot verify/status` for integrity and
|
|
83
|
+
freshness checks. Use `mdkg db snapshot dump/diff` as deterministic review aids
|
|
84
|
+
for SQLite snapshots. Keep active runtime DB files and transient
|
|
85
|
+
WAL/SHM/journal, lock, and temp files ignored. Commit schema files, manifests,
|
|
86
|
+
receipts, and sealed state snapshots only by explicit repo policy.
|
|
87
|
+
|
|
67
88
|
Recommended:
|
|
68
89
|
|
|
69
90
|
```bash
|
|
@@ -97,6 +118,10 @@ mdkg capability resolve "child capability" --json
|
|
|
97
118
|
mdkg subgraph verify child_repo --json
|
|
98
119
|
```
|
|
99
120
|
|
|
121
|
+
Use `mdkg subgraph sync child_repo --dry-run --json` before writing a refreshed root-owned child bundle snapshot, then `mdkg subgraph sync child_repo --json` when the receipt is acceptable. `sync` inspects the configured child Git repo `source_path`, refuses dirty tracked changes by default, verifies the new bundle, and records `source_repo` as `<branch>@<sha>` without committing, pulling, pushing, checking out, resetting, or mutating child mdkg Markdown.
|
|
122
|
+
|
|
123
|
+
Use `mdkg subgraph materialize child_repo --target .mdkg/subgraphs --gitignore --json` only when you need a generated read-only inspection tree. Materialized views are local generated state and are not root graph nodes.
|
|
124
|
+
|
|
100
125
|
Subgraph nodes use the subgraph alias as their qid prefix and can be inspected or packed, but mutations must happen in the owning child repo.
|
|
101
126
|
|
|
102
127
|
## Archive and Work Mirrors
|
package/dist/init/config.json
CHANGED
|
@@ -21,6 +21,17 @@
|
|
|
21
21
|
"output_dir": ".mdkg/bundles",
|
|
22
22
|
"default_profile": "private"
|
|
23
23
|
},
|
|
24
|
+
"db": {
|
|
25
|
+
"enabled": false,
|
|
26
|
+
"schema_version": 1,
|
|
27
|
+
"root_path": ".mdkg/db",
|
|
28
|
+
"schema_path": ".mdkg/db/schema",
|
|
29
|
+
"migrations_path": ".mdkg/db/schema/migrations",
|
|
30
|
+
"runtime_path": ".mdkg/db/runtime/project.sqlite",
|
|
31
|
+
"state_path": ".mdkg/db/state/project.sqlite",
|
|
32
|
+
"receipts_path": ".mdkg/db/receipts",
|
|
33
|
+
"migration_table": "mdkg_schema_migration"
|
|
34
|
+
},
|
|
24
35
|
"subgraphs": {},
|
|
25
36
|
"pack": {
|
|
26
37
|
"default_depth": 2,
|
|
@@ -254,8 +254,15 @@ Common flags:
|
|
|
254
254
|
- `mdkg subgraph disable <alias> [--json]`
|
|
255
255
|
- `mdkg subgraph verify [alias|--all] [--json]`
|
|
256
256
|
- `mdkg subgraph refresh [alias|--all] [--json]`
|
|
257
|
+
- `mdkg subgraph sync [alias|--all] [--dry-run] [--allow-dirty] [--json]`
|
|
258
|
+
- `mdkg subgraph materialize [alias|--all] --target <path> [--clean] [--gitignore] [--json]`
|
|
257
259
|
- subgraphs are read-only projected graph views; child repos remain owners of real mutations and commits
|
|
258
260
|
- `subgraph refresh` reloads configured bundle sources only and never builds or mutates child repos
|
|
261
|
+
- `subgraph sync` is the explicit child-bundle build command; it uses configured root-relative `source_path`, requires a contained child Git repo with `.mdkg`, refuses dirty tracked child changes unless `--allow-dirty` is supplied, writes configured root-owned bundle paths, verifies bundles, and updates `source_repo` to `<branch>@<sha>`
|
|
262
|
+
- `subgraph sync --dry-run` writes no bundles, config, or indexes and reports intended paths, bundle hashes, dirty state, and source repo
|
|
263
|
+
- `subgraph materialize` extracts configured bundles into generated read-only inspection trees under `<target>/<alias>`, writes `.mdkg-materialized.json`, and only cleans existing alias directories with both `--clean` and a materialization marker
|
|
264
|
+
- `.mdkg/subgraphs/` materialized views are ignored by local graph scanning, search, validation, packing, bundle creation, and SQLite hydration
|
|
265
|
+
- root-authored relationship/reference fields may point at configured subgraph qids; local ownership fields (`epic`, `parent`, `prev`, `next`) remain local-only
|
|
259
266
|
- `subgraph verify` exits nonzero for stale, missing, corrupt, profile-mismatched, or duplicate-id subgraphs
|
|
260
267
|
- public/internal subgraphs require `expected_profile: public`; private bundle profiles cannot be promoted through subgraph visibility
|
|
261
268
|
- legacy `mdkg bundle import ...` exits with guidance to run `mdkg upgrade --apply` and use `mdkg subgraph ...`
|
|
@@ -10,7 +10,7 @@ relates: []
|
|
|
10
10
|
refs: []
|
|
11
11
|
aliases: []
|
|
12
12
|
created: 2026-01-06
|
|
13
|
-
updated: 2026-
|
|
13
|
+
updated: 2026-06-03
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Repo safety and ignores
|
|
@@ -23,6 +23,8 @@ 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/db/runtime/` active project database files and `.mdkg/db` transient WAL, SHM, journal, lock, and temp files must not be committed.
|
|
27
|
+
- `.mdkg/db/schema/`, `.mdkg/db/receipts/`, manifests, and sealed state snapshots are commit-eligible only by explicit repo policy.
|
|
26
28
|
- `.mdkg/state/` stores local workflow convenience state and must not be committed.
|
|
27
29
|
- `.mdkg/bundles/` may be committed only when the repo intentionally tracks private or public snapshot bundles.
|
|
28
30
|
|
|
@@ -38,6 +40,12 @@ The repo MUST ignore at minimum:
|
|
|
38
40
|
- `.mdkg/index/*.sqlite-wal`
|
|
39
41
|
- `.mdkg/index/*.sqlite-shm`
|
|
40
42
|
- `.mdkg/index/*.sqlite-journal`
|
|
43
|
+
- `.mdkg/db/runtime/`
|
|
44
|
+
- `.mdkg/db/**/*.sqlite-wal`
|
|
45
|
+
- `.mdkg/db/**/*.sqlite-shm`
|
|
46
|
+
- `.mdkg/db/**/*.sqlite-journal`
|
|
47
|
+
- `.mdkg/db/**/*.lock`
|
|
48
|
+
- `.mdkg/db/**/*.tmp`
|
|
41
49
|
- `.mdkg/state/`
|
|
42
50
|
- `.mdkg/pack/`
|
|
43
51
|
- `.mdkg/archive/**/source/`
|
|
@@ -49,6 +57,12 @@ Recommended `.gitignore` entries:
|
|
|
49
57
|
- `.mdkg/index/*.sqlite-wal`
|
|
50
58
|
- `.mdkg/index/*.sqlite-shm`
|
|
51
59
|
- `.mdkg/index/*.sqlite-journal`
|
|
60
|
+
- `.mdkg/db/runtime/`
|
|
61
|
+
- `.mdkg/db/**/*.sqlite-wal`
|
|
62
|
+
- `.mdkg/db/**/*.sqlite-shm`
|
|
63
|
+
- `.mdkg/db/**/*.sqlite-journal`
|
|
64
|
+
- `.mdkg/db/**/*.lock`
|
|
65
|
+
- `.mdkg/db/**/*.tmp`
|
|
52
66
|
- `.mdkg/state/`
|
|
53
67
|
- `.mdkg/pack/`
|
|
54
68
|
- `.mdkg/archive/**/source/`
|
|
@@ -79,6 +93,12 @@ If the repo is containerized:
|
|
|
79
93
|
- `.mdkg/index/*.sqlite-wal`
|
|
80
94
|
- `.mdkg/index/*.sqlite-shm`
|
|
81
95
|
- `.mdkg/index/*.sqlite-journal`
|
|
96
|
+
- `.mdkg/db/runtime/`
|
|
97
|
+
- `.mdkg/db/**/*.sqlite-wal`
|
|
98
|
+
- `.mdkg/db/**/*.sqlite-shm`
|
|
99
|
+
- `.mdkg/db/**/*.sqlite-journal`
|
|
100
|
+
- `.mdkg/db/**/*.lock`
|
|
101
|
+
- `.mdkg/db/**/*.tmp`
|
|
82
102
|
- `node_modules/`
|
|
83
103
|
- `dist/` (if built in container)
|
|
84
104
|
- any other local artifacts
|
|
@@ -90,7 +110,7 @@ For application builds:
|
|
|
90
110
|
|
|
91
111
|
`mdkg init` updates ignore files by default for safety:
|
|
92
112
|
|
|
93
|
-
- `.gitignore` appends generated index cache/temp/lock patterns, `.mdkg/state/`, `.mdkg/pack/`, and raw archive source ignores.
|
|
113
|
+
- `.gitignore` appends generated index cache/temp/lock patterns, project DB runtime/transient patterns, `.mdkg/state/`, `.mdkg/pack/`, and raw archive source ignores.
|
|
94
114
|
- `.npmignore` appends `.mdkg/`, generated index cache/temp/lock patterns, and `.mdkg/pack/`.
|
|
95
115
|
- `--no-update-ignores` disables these default writes
|
|
96
116
|
|
|
@@ -108,6 +128,19 @@ Explicit flags remain available and take precedence:
|
|
|
108
128
|
- `.mdkg/state/` contains local workflow convenience state such as selected goals and MUST stay ignored.
|
|
109
129
|
- Index rebuild should be deterministic and safe to regenerate at any time.
|
|
110
130
|
|
|
131
|
+
## Project DB safety
|
|
132
|
+
|
|
133
|
+
- `.mdkg/db/` is reserved for project application database state, separate from
|
|
134
|
+
the rebuildable `.mdkg/index/` graph cache.
|
|
135
|
+
- The generic layout is `.mdkg/db/schema/`, `.mdkg/db/runtime/`,
|
|
136
|
+
`.mdkg/db/state/`, and `.mdkg/db/receipts/`.
|
|
137
|
+
- Active runtime DB files under `.mdkg/db/runtime/` and transient WAL, SHM,
|
|
138
|
+
journal, lock, and temp files under `.mdkg/db/` stay ignored by default.
|
|
139
|
+
- Schema files, manifests, receipt artifacts, and opt-in sealed snapshots are
|
|
140
|
+
commit-eligible only by explicit repo policy.
|
|
141
|
+
- `mdkg doctor` should warn when active project DB runtime/transient files are
|
|
142
|
+
present so they are not mistaken for sealed state.
|
|
143
|
+
|
|
111
144
|
## Bundle safety
|
|
112
145
|
|
|
113
146
|
- `.mdkg/bundles/` stores explicit snapshot artifacts and is not ignored by default.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"tool": "mdkg",
|
|
4
|
-
"mdkg_version": "0.1.
|
|
4
|
+
"mdkg_version": "0.1.7",
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
7
7
|
"path": ".mdkg/config.json",
|
|
8
8
|
"category": "config",
|
|
9
|
-
"sha256": "
|
|
9
|
+
"sha256": "8055c72aa3c55f8a49d532a735bc29e3baa2e2bf478e9d092b83bec9e46fa78c"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": ".mdkg/core/core.md",
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
{
|
|
37
37
|
"path": ".mdkg/core/rule-3-cli-contract.md",
|
|
38
38
|
"category": "core",
|
|
39
|
-
"sha256": "
|
|
39
|
+
"sha256": "f61b84ff6e5abae91365c4f623ccbd78f25dfcfef09822fefb3abf0119d65739"
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"path": ".mdkg/core/rule-4-repo-safety-and-ignores.md",
|
|
43
43
|
"category": "core",
|
|
44
|
-
"sha256": "
|
|
44
|
+
"sha256": "3c7a4e34febf05b3202af4bb21cbbbeb430c2b872e3a7030920bbc6b045bd0b8"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"path": ".mdkg/core/rule-5-release-and-versioning.md",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
{
|
|
62
62
|
"path": ".mdkg/README.md",
|
|
63
63
|
"category": "mdkg_doc",
|
|
64
|
-
"sha256": "
|
|
64
|
+
"sha256": "57a55e0f3743415f5ba1d166d3abf61b2ad868cc11d0e7083b7fd8075dae95a1"
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"path": ".mdkg/skills/build-pack-and-execute-task/SKILL.md",
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
{
|
|
187
187
|
"path": "AGENT_START.md",
|
|
188
188
|
"category": "startup_doc",
|
|
189
|
-
"sha256": "
|
|
189
|
+
"sha256": "d9ba16476749bd96c986f356b40a7abe4b1321b10260f61f85198220c11ac994"
|
|
190
190
|
},
|
|
191
191
|
{
|
|
192
192
|
"path": "AGENTS.md",
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
{
|
|
202
202
|
"path": "CLI_COMMAND_MATRIX.md",
|
|
203
203
|
"category": "startup_doc",
|
|
204
|
-
"sha256": "
|
|
204
|
+
"sha256": "51c8f3e6fff4c2a0c385e39c2c41a0b26136ca9d2efcd4593f0099c3cdc0a4a8"
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
"path": "llms.txt",
|
package/dist/util/argparse.js
CHANGED
|
@@ -84,6 +84,8 @@ const VALUE_FLAGS = new Set([
|
|
|
84
84
|
"--source-repo",
|
|
85
85
|
"--max-stale-seconds",
|
|
86
86
|
"--requires",
|
|
87
|
+
"--target",
|
|
88
|
+
"--snapshot",
|
|
87
89
|
]);
|
|
88
90
|
const BOOLEAN_FLAGS = new Set([
|
|
89
91
|
"--tolerant",
|
|
@@ -118,6 +120,9 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
118
120
|
"--clear-blocked-by",
|
|
119
121
|
"--all",
|
|
120
122
|
"--fresh-only",
|
|
123
|
+
"--allow-dirty",
|
|
124
|
+
"--clean",
|
|
125
|
+
"--gitignore",
|
|
121
126
|
]);
|
|
122
127
|
const FLAG_ALIASES = {
|
|
123
128
|
"--o": "--out",
|
package/dist/util/refs.js
CHANGED
|
@@ -27,7 +27,7 @@ function isSha256Ref(value) {
|
|
|
27
27
|
return SHA256_RE.test(value);
|
|
28
28
|
}
|
|
29
29
|
function isPortableOrUriRef(value) {
|
|
30
|
-
return (0, id_1.
|
|
30
|
+
return (0, id_1.isPortableIdRef)(value.toLowerCase()) || isUriRef(value);
|
|
31
31
|
}
|
|
32
32
|
function validatePortableOrUriRef(value) {
|
|
33
33
|
if (isUriRef(value)) {
|
|
@@ -36,5 +36,5 @@ function validatePortableOrUriRef(value) {
|
|
|
36
36
|
}
|
|
37
37
|
return true;
|
|
38
38
|
}
|
|
39
|
-
return value === value.toLowerCase() && (0, id_1.
|
|
39
|
+
return value === value.toLowerCase() && (0, id_1.isPortableIdRef)(value);
|
|
40
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mdkg",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Markdown Knowledge Graph",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
"smoke:upgrade": "npm run build && node scripts/smoke-upgrade.js",
|
|
17
17
|
"smoke:init": "npm run build && node scripts/smoke-init.js",
|
|
18
18
|
"smoke:capabilities": "npm run build && node scripts/smoke-capabilities.js",
|
|
19
|
+
"smoke:db": "npm run build && node scripts/smoke-db.js",
|
|
20
|
+
"smoke:db-snapshot": "npm run build && node scripts/smoke-db-snapshot.js",
|
|
19
21
|
"smoke:archive-work": "npm run build && node scripts/smoke-archive-work.js",
|
|
20
22
|
"smoke:bundle": "npm run build && node scripts/smoke-bundle.js",
|
|
21
23
|
"smoke:bundle-import": "npm run smoke:subgraph",
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
"cli:snapshot": "npm run build && node scripts/cli_help_snapshot.js",
|
|
27
29
|
"cli:check": "npm run build && node scripts/cli_help_snapshot.js --check",
|
|
28
30
|
"prepack": "npm run build && node scripts/assert-publish-ready.js",
|
|
29
|
-
"prepublishOnly": "npm run test && npm run cli:check && 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:archive-work && 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",
|
|
31
|
+
"prepublishOnly": "npm run test && npm run cli:check && 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-snapshot && npm run smoke:archive-work && 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",
|
|
30
32
|
"postinstall": "node scripts/postinstall.js",
|
|
31
33
|
"smoke:subgraph": "npm run build && node scripts/smoke-subgraph.js"
|
|
32
34
|
},
|