mdkg 0.1.10 → 0.2.0
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 +26 -0
- package/README.md +14 -11
- package/dist/cli.js +147 -6
- package/dist/commands/db.js +185 -1
- package/dist/core/project_db_migrations.js +24 -0
- package/dist/core/project_db_queue.js +186 -0
- package/dist/core/project_db_snapshot.js +28 -3
- package/dist/init/AGENT_START.md +10 -8
- package/dist/init/CLI_COMMAND_MATRIX.md +10 -5
- package/dist/init/README.md +11 -9
- package/dist/init/init-manifest.json +60 -5
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +8 -7
- package/dist/init/templates/skills/base.SKILL.md +66 -0
- package/dist/init/templates/specs/agent.SPEC.md +39 -0
- package/dist/init/templates/specs/api.SPEC.md +32 -0
- package/dist/init/templates/specs/base.SPEC.md +87 -0
- package/dist/init/templates/specs/capability.SPEC.md +32 -0
- package/dist/init/templates/specs/integration.SPEC.md +24 -0
- package/dist/init/templates/specs/model.SPEC.md +20 -0
- package/dist/init/templates/specs/omniruntime-agent.SPEC.md +39 -0
- package/dist/init/templates/specs/project.SPEC.md +26 -0
- package/dist/init/templates/specs/runtime-image.SPEC.md +20 -0
- package/dist/init/templates/specs/tool.SPEC.md +24 -0
- package/package.json +3 -2
|
@@ -10,6 +10,14 @@ exports.failProjectQueueMessage = failProjectQueueMessage;
|
|
|
10
10
|
exports.deadLetterProjectQueueMessage = deadLetterProjectQueueMessage;
|
|
11
11
|
exports.releaseExpiredProjectQueueLeases = releaseExpiredProjectQueueLeases;
|
|
12
12
|
exports.readProjectQueueStats = readProjectQueueStats;
|
|
13
|
+
exports.createProjectQueue = createProjectQueue;
|
|
14
|
+
exports.pauseProjectQueue = pauseProjectQueue;
|
|
15
|
+
exports.resumeProjectQueue = resumeProjectQueue;
|
|
16
|
+
exports.readProjectQueue = readProjectQueue;
|
|
17
|
+
exports.listProjectQueues = listProjectQueues;
|
|
18
|
+
exports.readProjectQueueMessage = readProjectQueueMessage;
|
|
19
|
+
exports.listProjectQueueMessages = listProjectQueueMessages;
|
|
20
|
+
exports.readProjectQueueSnapshotSummary = readProjectQueueSnapshotSummary;
|
|
13
21
|
const crypto_1 = __importDefault(require("crypto"));
|
|
14
22
|
function loadDatabaseCtor() {
|
|
15
23
|
try {
|
|
@@ -91,12 +99,44 @@ function toMessage(row) {
|
|
|
91
99
|
last_error: row.last_error === null || row.last_error === undefined ? null : String(row.last_error),
|
|
92
100
|
};
|
|
93
101
|
}
|
|
102
|
+
function toQueue(row) {
|
|
103
|
+
return {
|
|
104
|
+
queue_name: String(row.queue_name),
|
|
105
|
+
status: String(row.status),
|
|
106
|
+
paused_reason: row.paused_reason === null || row.paused_reason === undefined ? null : String(row.paused_reason),
|
|
107
|
+
created_at_ms: Number(row.created_at_ms),
|
|
108
|
+
updated_at_ms: Number(row.updated_at_ms),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
94
111
|
function getMessage(db, queueName, messageId) {
|
|
95
112
|
const row = db
|
|
96
113
|
.prepare("SELECT * FROM project_queue_message WHERE queue_name = ? AND message_id = ?")
|
|
97
114
|
.get(queueName, messageId);
|
|
98
115
|
return row ? toMessage(row) : null;
|
|
99
116
|
}
|
|
117
|
+
function getQueue(db, queueName) {
|
|
118
|
+
const row = db.prepare("SELECT * FROM project_queue WHERE queue_name = ?").get(queueName);
|
|
119
|
+
return row ? toQueue(row) : null;
|
|
120
|
+
}
|
|
121
|
+
function ensureQueue(db, queueName, currentNow) {
|
|
122
|
+
const existing = getQueue(db, queueName);
|
|
123
|
+
if (existing) {
|
|
124
|
+
return existing;
|
|
125
|
+
}
|
|
126
|
+
db
|
|
127
|
+
.prepare("INSERT INTO project_queue (queue_name, status, paused_reason, created_at_ms, updated_at_ms) VALUES (?, 'active', NULL, ?, ?)")
|
|
128
|
+
.run(queueName, currentNow, currentNow);
|
|
129
|
+
const queue = getQueue(db, queueName);
|
|
130
|
+
if (!queue) {
|
|
131
|
+
throw new Error(`queue could not be loaded after create: ${queueName}`);
|
|
132
|
+
}
|
|
133
|
+
return queue;
|
|
134
|
+
}
|
|
135
|
+
function requireQueueActive(queue, action) {
|
|
136
|
+
if (queue.status === "paused") {
|
|
137
|
+
throw new Error(`queue ${queue.queue_name} is paused; cannot ${action}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
100
140
|
function withDb(databasePath, fn) {
|
|
101
141
|
const DatabaseSync = loadDatabaseCtor();
|
|
102
142
|
const db = new DatabaseSync(databasePath);
|
|
@@ -139,6 +179,7 @@ function enqueueProjectQueueMessage(databasePath, input) {
|
|
|
139
179
|
const payloadJson = stableJson(input.payload);
|
|
140
180
|
const hash = payloadHash(payloadJson);
|
|
141
181
|
return withDb(databasePath, (db) => withImmediateTransaction(db, () => {
|
|
182
|
+
requireQueueActive(ensureQueue(db, input.queue_name, currentNow), "enqueue");
|
|
142
183
|
if (input.dedupe_key) {
|
|
143
184
|
const duplicate = db
|
|
144
185
|
.prepare("SELECT * FROM project_queue_message WHERE queue_name = ? AND dedupe_key = ?")
|
|
@@ -167,6 +208,7 @@ function claimProjectQueueMessage(databasePath, input) {
|
|
|
167
208
|
assertPositiveInteger(input.lease_ms, "lease_ms");
|
|
168
209
|
const currentNow = nowMs(input.now_ms);
|
|
169
210
|
return withDb(databasePath, (db) => withImmediateTransaction(db, () => {
|
|
211
|
+
requireQueueActive(ensureQueue(db, input.queue_name, currentNow), "claim");
|
|
170
212
|
const row = db
|
|
171
213
|
.prepare([
|
|
172
214
|
"SELECT * FROM project_queue_message",
|
|
@@ -315,3 +357,147 @@ function readProjectQueueStats(databasePath, input = {}) {
|
|
|
315
357
|
};
|
|
316
358
|
});
|
|
317
359
|
}
|
|
360
|
+
function createProjectQueue(databasePath, input) {
|
|
361
|
+
assertNonEmpty(input.queue_name, "queue_name");
|
|
362
|
+
const currentNow = nowMs(input.now_ms);
|
|
363
|
+
if (input.reason !== undefined && input.reason !== null) {
|
|
364
|
+
assertNonEmpty(input.reason, "reason");
|
|
365
|
+
}
|
|
366
|
+
return withDb(databasePath, (db) => withImmediateTransaction(db, () => {
|
|
367
|
+
const existing = getQueue(db, input.queue_name);
|
|
368
|
+
if (existing) {
|
|
369
|
+
return { created: false, queue: existing };
|
|
370
|
+
}
|
|
371
|
+
const status = input.paused ? "paused" : "active";
|
|
372
|
+
db
|
|
373
|
+
.prepare("INSERT INTO project_queue (queue_name, status, paused_reason, created_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?)")
|
|
374
|
+
.run(input.queue_name, status, input.paused ? input.reason ?? null : null, currentNow, currentNow);
|
|
375
|
+
const queue = getQueue(db, input.queue_name);
|
|
376
|
+
if (!queue) {
|
|
377
|
+
throw new Error(`queue could not be loaded after create: ${input.queue_name}`);
|
|
378
|
+
}
|
|
379
|
+
return { created: true, queue };
|
|
380
|
+
}));
|
|
381
|
+
}
|
|
382
|
+
function pauseProjectQueue(databasePath, input) {
|
|
383
|
+
assertNonEmpty(input.queue_name, "queue_name");
|
|
384
|
+
if (input.reason !== undefined && input.reason !== null) {
|
|
385
|
+
assertNonEmpty(input.reason, "reason");
|
|
386
|
+
}
|
|
387
|
+
const currentNow = nowMs(input.now_ms);
|
|
388
|
+
return withDb(databasePath, (db) => withImmediateTransaction(db, () => {
|
|
389
|
+
ensureQueue(db, input.queue_name, currentNow);
|
|
390
|
+
db
|
|
391
|
+
.prepare("UPDATE project_queue SET status = 'paused', paused_reason = ?, updated_at_ms = ? WHERE queue_name = ?")
|
|
392
|
+
.run(input.reason ?? null, currentNow, input.queue_name);
|
|
393
|
+
const queue = getQueue(db, input.queue_name);
|
|
394
|
+
if (!queue) {
|
|
395
|
+
throw new Error(`queue could not be loaded after pause: ${input.queue_name}`);
|
|
396
|
+
}
|
|
397
|
+
return queue;
|
|
398
|
+
}));
|
|
399
|
+
}
|
|
400
|
+
function resumeProjectQueue(databasePath, input) {
|
|
401
|
+
assertNonEmpty(input.queue_name, "queue_name");
|
|
402
|
+
const currentNow = nowMs(input.now_ms);
|
|
403
|
+
return withDb(databasePath, (db) => withImmediateTransaction(db, () => {
|
|
404
|
+
ensureQueue(db, input.queue_name, currentNow);
|
|
405
|
+
db
|
|
406
|
+
.prepare("UPDATE project_queue SET status = 'active', paused_reason = NULL, updated_at_ms = ? WHERE queue_name = ?")
|
|
407
|
+
.run(currentNow, input.queue_name);
|
|
408
|
+
const queue = getQueue(db, input.queue_name);
|
|
409
|
+
if (!queue) {
|
|
410
|
+
throw new Error(`queue could not be loaded after resume: ${input.queue_name}`);
|
|
411
|
+
}
|
|
412
|
+
return queue;
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
415
|
+
function readProjectQueue(databasePath, queueName) {
|
|
416
|
+
assertNonEmpty(queueName, "queue_name");
|
|
417
|
+
return withDb(databasePath, (db) => getQueue(db, queueName));
|
|
418
|
+
}
|
|
419
|
+
function listProjectQueues(databasePath) {
|
|
420
|
+
return withDb(databasePath, (db) => db.prepare("SELECT * FROM project_queue ORDER BY queue_name ASC").all().map(toQueue));
|
|
421
|
+
}
|
|
422
|
+
function readProjectQueueMessage(databasePath, queueName, messageId) {
|
|
423
|
+
assertNonEmpty(queueName, "queue_name");
|
|
424
|
+
assertNonEmpty(messageId, "message_id");
|
|
425
|
+
return withDb(databasePath, (db) => getMessage(db, queueName, messageId));
|
|
426
|
+
}
|
|
427
|
+
function listProjectQueueMessages(databasePath, input) {
|
|
428
|
+
assertNonEmpty(input.queue_name, "queue_name");
|
|
429
|
+
const limit = input.limit ?? 50;
|
|
430
|
+
assertPositiveInteger(limit, "limit");
|
|
431
|
+
if (input.status && input.status !== "all" && !["ready", "leased", "acked", "dead_letter"].includes(input.status)) {
|
|
432
|
+
throw new Error("status must be ready, leased, acked, dead_letter, or all");
|
|
433
|
+
}
|
|
434
|
+
return withDb(databasePath, (db) => {
|
|
435
|
+
const sql = input.status && input.status !== "all"
|
|
436
|
+
? [
|
|
437
|
+
"SELECT * FROM project_queue_message",
|
|
438
|
+
"WHERE queue_name = ? AND status = ?",
|
|
439
|
+
"ORDER BY available_at_ms ASC, created_at_ms ASC, message_id ASC",
|
|
440
|
+
"LIMIT ?",
|
|
441
|
+
].join(" ")
|
|
442
|
+
: [
|
|
443
|
+
"SELECT * FROM project_queue_message",
|
|
444
|
+
"WHERE queue_name = ?",
|
|
445
|
+
"ORDER BY available_at_ms ASC, created_at_ms ASC, message_id ASC",
|
|
446
|
+
"LIMIT ?",
|
|
447
|
+
].join(" ");
|
|
448
|
+
const params = input.status && input.status !== "all" ? [input.queue_name, input.status, limit] : [input.queue_name, limit];
|
|
449
|
+
return db.prepare(sql).all(...params).map(toMessage);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
function readProjectQueueSnapshotSummary(databasePath) {
|
|
453
|
+
return withDb(databasePath, (db) => {
|
|
454
|
+
const rows = db
|
|
455
|
+
.prepare([
|
|
456
|
+
"SELECT q.queue_name, q.status, q.paused_reason,",
|
|
457
|
+
"COUNT(m.message_id) AS total,",
|
|
458
|
+
"SUM(CASE WHEN m.status = 'ready' THEN 1 ELSE 0 END) AS ready,",
|
|
459
|
+
"SUM(CASE WHEN m.status = 'leased' THEN 1 ELSE 0 END) AS leased,",
|
|
460
|
+
"SUM(CASE WHEN m.status = 'acked' THEN 1 ELSE 0 END) AS acked,",
|
|
461
|
+
"SUM(CASE WHEN m.status = 'dead_letter' THEN 1 ELSE 0 END) AS dead_letter",
|
|
462
|
+
"FROM project_queue q",
|
|
463
|
+
"LEFT JOIN project_queue_message m ON m.queue_name = q.queue_name",
|
|
464
|
+
"GROUP BY q.queue_name, q.status, q.paused_reason",
|
|
465
|
+
"ORDER BY q.queue_name ASC",
|
|
466
|
+
].join(" "))
|
|
467
|
+
.all();
|
|
468
|
+
const queues = rows.map((row) => ({
|
|
469
|
+
queue_name: String(row.queue_name),
|
|
470
|
+
status: String(row.status),
|
|
471
|
+
paused_reason: row.paused_reason === null || row.paused_reason === undefined ? null : String(row.paused_reason),
|
|
472
|
+
total: Number(row.total ?? 0),
|
|
473
|
+
ready: Number(row.ready ?? 0),
|
|
474
|
+
leased: Number(row.leased ?? 0),
|
|
475
|
+
acked: Number(row.acked ?? 0),
|
|
476
|
+
dead_letter: Number(row.dead_letter ?? 0),
|
|
477
|
+
}));
|
|
478
|
+
const summary = {
|
|
479
|
+
queues,
|
|
480
|
+
total: 0,
|
|
481
|
+
ready: 0,
|
|
482
|
+
leased: 0,
|
|
483
|
+
acked: 0,
|
|
484
|
+
dead_letter: 0,
|
|
485
|
+
paused_ready: 0,
|
|
486
|
+
active_ready: 0,
|
|
487
|
+
};
|
|
488
|
+
for (const queue of queues) {
|
|
489
|
+
summary.total += queue.total;
|
|
490
|
+
summary.ready += queue.ready;
|
|
491
|
+
summary.leased += queue.leased;
|
|
492
|
+
summary.acked += queue.acked;
|
|
493
|
+
summary.dead_letter += queue.dead_letter;
|
|
494
|
+
if (queue.status === "paused") {
|
|
495
|
+
summary.paused_ready += queue.ready;
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
summary.active_ready += queue.ready;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return summary;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
@@ -18,6 +18,7 @@ const version_1 = require("./version");
|
|
|
18
18
|
const atomic_1 = require("../util/atomic");
|
|
19
19
|
const errors_1 = require("../util/errors");
|
|
20
20
|
const project_db_migrations_1 = require("./project_db_migrations");
|
|
21
|
+
const project_db_queue_1 = require("./project_db_queue");
|
|
21
22
|
function loadDatabaseCtor() {
|
|
22
23
|
try {
|
|
23
24
|
const loaded = require("node:sqlite");
|
|
@@ -170,7 +171,7 @@ function readManifest(filePath) {
|
|
|
170
171
|
}
|
|
171
172
|
return manifest;
|
|
172
173
|
}
|
|
173
|
-
function buildManifest(root, config, snapshotFile, runtimeHash) {
|
|
174
|
+
function buildManifest(root, config, snapshotFile, runtimeHash, queuePolicy, queueSummary) {
|
|
174
175
|
const layout = (0, project_db_1.resolveConfiguredProjectDbLayout)(root, config.db);
|
|
175
176
|
const metadata = collectSnapshotMetadata(snapshotFile, config.db.migration_table);
|
|
176
177
|
return {
|
|
@@ -188,17 +189,39 @@ function buildManifest(root, config, snapshotFile, runtimeHash) {
|
|
|
188
189
|
byte_size: fs_1.default.statSync(snapshotFile).size,
|
|
189
190
|
table_counts: metadata.table_counts,
|
|
190
191
|
migrations: metadata.migrations,
|
|
192
|
+
queue_policy: queuePolicy,
|
|
193
|
+
queue_summary: queueSummary,
|
|
191
194
|
};
|
|
192
195
|
}
|
|
196
|
+
function assertQueueSnapshotPolicy(policy, summary) {
|
|
197
|
+
if (policy === "drain") {
|
|
198
|
+
if (summary.ready > 0 || summary.leased > 0) {
|
|
199
|
+
throw new errors_1.ValidationError(`db snapshot seal requires drained queues; found ready=${summary.ready}, leased=${summary.leased}`);
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (policy === "paused") {
|
|
204
|
+
if (summary.leased > 0) {
|
|
205
|
+
throw new errors_1.ValidationError(`db snapshot seal --queue-policy paused requires no leased messages; found leased=${summary.leased}`);
|
|
206
|
+
}
|
|
207
|
+
if (summary.active_ready > 0) {
|
|
208
|
+
throw new errors_1.ValidationError(`db snapshot seal --queue-policy paused requires ready messages to be in paused queues; found active_ready=${summary.active_ready}`);
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
throw new errors_1.ValidationError(`unsupported queue snapshot policy: ${policy}`);
|
|
213
|
+
}
|
|
193
214
|
function warningListFromVerify(root, config) {
|
|
194
215
|
return (0, project_db_migrations_1.verifyProjectDb)(root, config).warnings;
|
|
195
216
|
}
|
|
196
|
-
function sealProjectDbSnapshot(root, config) {
|
|
217
|
+
function sealProjectDbSnapshot(root, config, queuePolicy = "drain") {
|
|
197
218
|
const verification = (0, project_db_migrations_1.verifyProjectDb)(root, config);
|
|
198
219
|
if (!verification.ok) {
|
|
199
220
|
throw new errors_1.ValidationError(`db snapshot seal requires a valid project DB; run mdkg db verify`);
|
|
200
221
|
}
|
|
201
222
|
const layout = (0, project_db_1.resolveConfiguredProjectDbLayout)(root, config.db);
|
|
223
|
+
const queueSummary = (0, project_db_queue_1.readProjectQueueSnapshotSummary)(layout.runtimeFile);
|
|
224
|
+
assertQueueSnapshotPolicy(queuePolicy, queueSummary);
|
|
202
225
|
const oldHash = fs_1.default.existsSync(layout.stateFile) ? sha256File(layout.stateFile) : null;
|
|
203
226
|
fs_1.default.mkdirSync(layout.stateDir, { recursive: true });
|
|
204
227
|
const tempSnapshot = path_1.default.join(layout.stateDir, `.project.sqlite.${process.pid}-${Date.now()}.tmp`);
|
|
@@ -228,7 +251,7 @@ function sealProjectDbSnapshot(root, config) {
|
|
|
228
251
|
}
|
|
229
252
|
try {
|
|
230
253
|
const runtimeHash = sha256File(layout.runtimeFile);
|
|
231
|
-
const manifest = buildManifest(root, config, tempSnapshot, runtimeHash);
|
|
254
|
+
const manifest = buildManifest(root, config, tempSnapshot, runtimeHash, queuePolicy, queueSummary);
|
|
232
255
|
(0, atomic_1.atomicWriteFile)(tempManifest, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
233
256
|
fs_1.default.renameSync(tempSnapshot, layout.stateFile);
|
|
234
257
|
fs_1.default.renameSync(tempManifest, layout.stateManifest);
|
|
@@ -243,6 +266,8 @@ function sealProjectDbSnapshot(root, config) {
|
|
|
243
266
|
byte_size: manifest.byte_size,
|
|
244
267
|
table_counts: manifest.table_counts,
|
|
245
268
|
migrations: manifest.migrations,
|
|
269
|
+
queue_policy: queuePolicy,
|
|
270
|
+
queue_summary: queueSummary,
|
|
246
271
|
warnings: warningListFromVerify(root, config),
|
|
247
272
|
};
|
|
248
273
|
}
|
package/dist/init/AGENT_START.md
CHANGED
|
@@ -34,15 +34,17 @@ Agent operating prompt:
|
|
|
34
34
|
- Treat `.mdkg/db` as project application state; use `mdkg db init` to create
|
|
35
35
|
the generic scaffold and enable `db.enabled` without creating an active
|
|
36
36
|
runtime SQLite database. Use `mdkg db migrate` after init to create or update
|
|
37
|
-
the runtime SQLite database with mdkg-owned foundation plus
|
|
38
|
-
node:sqlite queue, event/receipt/reducer,
|
|
39
|
-
migrations. Queue state is delivery infrastructure, not
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
the runtime SQLite database with mdkg-owned foundation plus public local
|
|
38
|
+
node:sqlite queue delivery, internal event/receipt/reducer, writer lease/CAS,
|
|
39
|
+
and queue control migrations. Queue state is delivery infrastructure, not
|
|
40
|
+
canonical event history; use `mdkg db queue ...` to create, pause, enqueue,
|
|
41
|
+
claim, settle, inspect, and drain local queues. Event rows are durable local
|
|
42
|
+
project DB history; receipts, reducers, writer leases, and materializers are
|
|
43
|
+
internal local helper surfaces, with no public `mdkg db event`,
|
|
44
|
+
`mdkg db reducer`, `mdkg db lease`, or `mdkg db materializer` CLI yet. Use `mdkg db verify` and `mdkg db stats` for
|
|
44
45
|
non-mutating health and summary receipts. Use `mdkg db snapshot seal` for
|
|
45
|
-
explicit sealed checkpoints,
|
|
46
|
+
explicit sealed checkpoints; default queue policy is drain, and
|
|
47
|
+
`--queue-policy paused` is only for intentionally paused queues,
|
|
46
48
|
`mdkg db snapshot verify/status` for checkpoint health, and
|
|
47
49
|
`mdkg db snapshot dump/diff` for deterministic review aids. Keep
|
|
48
50
|
`.mdkg/db/runtime/` and WAL/SHM/journal/lock/temp files ignored unless a
|
|
@@ -39,7 +39,8 @@ Project database commands:
|
|
|
39
39
|
- `mdkg db migrate [--json]`
|
|
40
40
|
- `mdkg db verify [--json]`
|
|
41
41
|
- `mdkg db stats [--json]`
|
|
42
|
-
- `mdkg db
|
|
42
|
+
- `mdkg db queue create|pause|resume|enqueue|claim|ack|fail|dead-letter|release-expired|stats|list|show ... [--json]`
|
|
43
|
+
- `mdkg db snapshot seal [--queue-policy drain|paused] [--json]`
|
|
43
44
|
- `mdkg db snapshot verify [--json]`
|
|
44
45
|
- `mdkg db snapshot status [--json]`
|
|
45
46
|
- `mdkg db snapshot dump [--snapshot <path>] [--output <path>] [--json]`
|
|
@@ -53,8 +54,10 @@ Project database commands:
|
|
|
53
54
|
queue, event/receipt/reducer, and writer lease/CAS foundation migrations
|
|
54
55
|
- `mdkg db migrate` records migration order, checksums, and applied timestamps
|
|
55
56
|
in the configured migration table
|
|
56
|
-
- queue
|
|
57
|
-
|
|
57
|
+
- `mdkg db queue ...` exposes durable local delivery operations backed by
|
|
58
|
+
node:sqlite; queue rows are delivery state, not canonical event history
|
|
59
|
+
- paused queues reject enqueue and claim, but ack/fail/dead-letter and
|
|
60
|
+
release-expired remain available so leased work can settle
|
|
58
61
|
- event tables are durable local history for project DB state transitions;
|
|
59
62
|
receipts, typed reducers, writer leases, and materializers remain internal
|
|
60
63
|
helper surfaces in this release, with no public `mdkg db event`,
|
|
@@ -64,8 +67,10 @@ Project database commands:
|
|
|
64
67
|
- `mdkg db stats` reports table counts, database size, migration state,
|
|
65
68
|
transient runtime files, receipt-file count, and state snapshot presence
|
|
66
69
|
- `mdkg db snapshot seal` writes an opt-in sealed checkpoint and manifest under
|
|
67
|
-
`.mdkg/db/state`;
|
|
68
|
-
|
|
70
|
+
`.mdkg/db/state`; default `--queue-policy drain` requires no ready or leased
|
|
71
|
+
messages, while `--queue-policy paused` allows ready messages only in paused
|
|
72
|
+
queues. `snapshot verify/status/dump/diff` inspect and review that checkpoint
|
|
73
|
+
without treating raw binary diffs as human-readable truth
|
|
69
74
|
- active `.mdkg/db/runtime/` files and `.mdkg/db` WAL/SHM/journal/lock/temp files are ignored by default
|
|
70
75
|
|
|
71
76
|
Validation commands:
|
package/dist/init/README.md
CHANGED
|
@@ -75,17 +75,19 @@ Fresh mdkg workspaces default to `index.backend: sqlite`; `.mdkg/index/mdkg.sqli
|
|
|
75
75
|
`.mdkg/index`. Run `mdkg db init` to create the generic scaffold, write
|
|
76
76
|
`.mdkg/db/project-db.json`, and enable `db.enabled`; it does not create an
|
|
77
77
|
active runtime SQLite database. Run `mdkg db migrate` after init to create or
|
|
78
|
-
update the active runtime SQLite database with mdkg-owned foundation plus
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
event history
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
update the active runtime SQLite database with mdkg-owned foundation plus public
|
|
79
|
+
local node:sqlite queue delivery, internal event/receipt/reducer, writer
|
|
80
|
+
lease/CAS, and queue control migrations. Queue state is delivery
|
|
81
|
+
infrastructure, not canonical event history; use `mdkg db queue ...` to create,
|
|
82
|
+
pause, enqueue, claim, settle, inspect, and drain local queues. Event rows are
|
|
83
|
+
durable local project DB history; receipts, reducers, writer leases, and
|
|
84
|
+
materializers are internal local helper surfaces, with no public `mdkg db event`,
|
|
85
|
+
`mdkg db reducer`, `mdkg db lease`, or `mdkg db materializer` CLI yet. Use `mdkg db verify` for non-mutating health checks and
|
|
85
86
|
`mdkg db stats` for table counts, DB size, migration state, and receipt-file
|
|
86
87
|
counts. Use `mdkg db snapshot seal` to create an opt-in sealed checkpoint under
|
|
87
|
-
`.mdkg/db/state
|
|
88
|
-
|
|
88
|
+
`.mdkg/db/state`; the default queue policy is drain, and
|
|
89
|
+
`--queue-policy paused` is only for intentionally paused queues. Then use
|
|
90
|
+
`mdkg db snapshot verify/status` for integrity and freshness checks. Use `mdkg db snapshot dump/diff` as deterministic review aids
|
|
89
91
|
for SQLite snapshots. Keep active runtime DB files and transient
|
|
90
92
|
WAL/SHM/journal, lock, and temp files ignored. Commit schema files, manifests,
|
|
91
93
|
receipts, and sealed state snapshots only by explicit repo policy.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"tool": "mdkg",
|
|
4
|
-
"mdkg_version": "0.
|
|
4
|
+
"mdkg_version": "0.2.0",
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
7
7
|
"path": ".mdkg/config.json",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
{
|
|
62
62
|
"path": ".mdkg/README.md",
|
|
63
63
|
"category": "mdkg_doc",
|
|
64
|
-
"sha256": "
|
|
64
|
+
"sha256": "14ba3fa0657a43345ae81631024519955868fa34081b7517cb253b0be96cf163"
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"path": ".mdkg/skills/build-pack-and-execute-task/SKILL.md",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
{
|
|
82
82
|
"path": ".mdkg/skills/verify-close-and-checkpoint/SKILL.md",
|
|
83
83
|
"category": "default_skill",
|
|
84
|
-
"sha256": "
|
|
84
|
+
"sha256": "3e4137b7b6a71f088dee79b5ee2f4743aefa3b43adae07337307db89a24416b6"
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
87
|
"path": ".mdkg/templates/default/archive.md",
|
|
@@ -183,10 +183,65 @@
|
|
|
183
183
|
"category": "template",
|
|
184
184
|
"sha256": "9d8b971ded7a587105fb8b14bb79f68b612fa6e1962cf06859bab82e2aee57c7"
|
|
185
185
|
},
|
|
186
|
+
{
|
|
187
|
+
"path": ".mdkg/templates/skills/base.SKILL.md",
|
|
188
|
+
"category": "template",
|
|
189
|
+
"sha256": "08a1bd65297173a1dc9df95776775d406337a419d4bc51863593b6f28777ebdb"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"path": ".mdkg/templates/specs/agent.SPEC.md",
|
|
193
|
+
"category": "template",
|
|
194
|
+
"sha256": "6facd5a424fa91d23f7df3e357c98ca4d31691410fad024d5bc8ff3781b0f571"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"path": ".mdkg/templates/specs/api.SPEC.md",
|
|
198
|
+
"category": "template",
|
|
199
|
+
"sha256": "42f6119478241a3c7dd12a2a25bd03b30d9c2bc60528287136ea044f20b215c4"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"path": ".mdkg/templates/specs/base.SPEC.md",
|
|
203
|
+
"category": "template",
|
|
204
|
+
"sha256": "cff1ee53e9369184e2d92194f165f131254d4439bc79bcbbaaae4a13d616c97b"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"path": ".mdkg/templates/specs/capability.SPEC.md",
|
|
208
|
+
"category": "template",
|
|
209
|
+
"sha256": "755c24dea04f687da4714d0a12489e1ae36c5f17b838c2e24bb993378a7d9510"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"path": ".mdkg/templates/specs/integration.SPEC.md",
|
|
213
|
+
"category": "template",
|
|
214
|
+
"sha256": "990005a805bc6e6397f03e0de1ca69d536ae9d55719782a3075781289b44b941"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"path": ".mdkg/templates/specs/model.SPEC.md",
|
|
218
|
+
"category": "template",
|
|
219
|
+
"sha256": "eb73ed195139cf5655ba70c948aaaa28fc2c85d2db1b6258d703f10e73bf3713"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"path": ".mdkg/templates/specs/omniruntime-agent.SPEC.md",
|
|
223
|
+
"category": "template",
|
|
224
|
+
"sha256": "343c7c148faae0c2b24364c276ce345757b5725a750cfebeee4cdeb3dde55009"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"path": ".mdkg/templates/specs/project.SPEC.md",
|
|
228
|
+
"category": "template",
|
|
229
|
+
"sha256": "5ade0aa05907b9ec418c41ee051493d8ecc8ad3d45608ab74fc3cbe2974e79a4"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"path": ".mdkg/templates/specs/runtime-image.SPEC.md",
|
|
233
|
+
"category": "template",
|
|
234
|
+
"sha256": "24c1b2fb0bd0d63bbce41ee36b43f9edf531b26438bca2706ad1ab556eaabbf0"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"path": ".mdkg/templates/specs/tool.SPEC.md",
|
|
238
|
+
"category": "template",
|
|
239
|
+
"sha256": "18340481891bba180dd077d82b86248ede885131fb75675b775ea0c3749ee5c0"
|
|
240
|
+
},
|
|
186
241
|
{
|
|
187
242
|
"path": "AGENT_START.md",
|
|
188
243
|
"category": "startup_doc",
|
|
189
|
-
"sha256": "
|
|
244
|
+
"sha256": "5948ed5222b2cbce0468191d00287ce5dbc1aaa434640f4daa676afb92d48d4b"
|
|
190
245
|
},
|
|
191
246
|
{
|
|
192
247
|
"path": "AGENTS.md",
|
|
@@ -201,7 +256,7 @@
|
|
|
201
256
|
{
|
|
202
257
|
"path": "CLI_COMMAND_MATRIX.md",
|
|
203
258
|
"category": "startup_doc",
|
|
204
|
-
"sha256": "
|
|
259
|
+
"sha256": "baf9792f0bd50ce44de2dc16babc73f631a1191acff853fdc4caa7d452f50561"
|
|
205
260
|
},
|
|
206
261
|
{
|
|
207
262
|
"path": "llms.txt",
|
|
@@ -46,13 +46,14 @@ Finish work with evidence, validation, and minimal memory drift.
|
|
|
46
46
|
Use this local repo-only checklist before publishing mdkg:
|
|
47
47
|
|
|
48
48
|
1. Confirm package intent and version in `package.json`, `package-lock.json`, `README.md`, `CLI_COMMAND_MATRIX.md`, and `CHANGELOG.md`.
|
|
49
|
-
2.
|
|
50
|
-
3.
|
|
51
|
-
4. Run `npm
|
|
52
|
-
5.
|
|
53
|
-
6.
|
|
54
|
-
7.
|
|
55
|
-
8.
|
|
49
|
+
2. Confirm release-line intent before bumping: when a change crosses a capability-track boundary, prefer the next minor release line over patch-style continuation. For the current project DB track, follow `0.1.9 -> 0.2.0` rather than naming the next planned source line `0.1.10`.
|
|
50
|
+
3. Use a clean npm cache: `export NPM_CONFIG_CACHE=/private/tmp/mdkg-npm-cache`.
|
|
51
|
+
4. Run `npm ci`, `npm run build`, `node scripts/assert-publish-ready.js`, `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`, and `npm run smoke:visibility`.
|
|
52
|
+
5. Run `npm pack --dry-run --json` and confirm the tarball includes `dist/cli.js`, compiled folders, `dist/init/`, release docs, and `scripts/postinstall.js`.
|
|
53
|
+
6. Confirm registry state with `npm view mdkg version --registry=https://registry.npmjs.org/`.
|
|
54
|
+
7. Publish only after the registry still shows the previous version and npm auth is known to have write access.
|
|
55
|
+
8. If publishing fails with 2FA or token policy errors, do not commit; fix npm auth or package policy, then rerun publish.
|
|
56
|
+
9. After successful publish, verify `npm view mdkg version` and `npm view mdkg dist-tags`, then commit the release changes.
|
|
56
57
|
|
|
57
58
|
## Bundle-Aware Commit Gate
|
|
58
59
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{skill_slug}}
|
|
3
|
+
description: {{description}}
|
|
4
|
+
tags: [stage:plan, writer:orchestrator]
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
authors: [{{owner}}]
|
|
7
|
+
links: []
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Purpose
|
|
11
|
+
|
|
12
|
+
Describe the repeatable workflow and the durable outcome this skill produces.
|
|
13
|
+
|
|
14
|
+
## When To Use
|
|
15
|
+
|
|
16
|
+
- Trigger condition.
|
|
17
|
+
|
|
18
|
+
## Inputs
|
|
19
|
+
|
|
20
|
+
- Required context or artifacts.
|
|
21
|
+
|
|
22
|
+
## Outputs
|
|
23
|
+
|
|
24
|
+
- Result, patch, artifact, report, or handoff.
|
|
25
|
+
|
|
26
|
+
## Required Capabilities
|
|
27
|
+
|
|
28
|
+
- Capability needed by the worker or orchestrator.
|
|
29
|
+
|
|
30
|
+
## Resources Touched
|
|
31
|
+
|
|
32
|
+
- Files, repos, services, or mdkg nodes the skill may inspect or mutate.
|
|
33
|
+
|
|
34
|
+
## Steps
|
|
35
|
+
|
|
36
|
+
1. Ground in source and mdkg truth.
|
|
37
|
+
2. Execute the smallest deterministic workflow.
|
|
38
|
+
3. Record evidence.
|
|
39
|
+
|
|
40
|
+
## Validation Checks
|
|
41
|
+
|
|
42
|
+
- Command or review gate.
|
|
43
|
+
|
|
44
|
+
## Closeout Evidence
|
|
45
|
+
|
|
46
|
+
- Evidence required before work can be considered done.
|
|
47
|
+
|
|
48
|
+
## Failure Modes
|
|
49
|
+
|
|
50
|
+
- Known blocker or ambiguity.
|
|
51
|
+
|
|
52
|
+
## Safety Rules
|
|
53
|
+
|
|
54
|
+
- No secrets or unrelated broad mutation.
|
|
55
|
+
|
|
56
|
+
## Related SPECs
|
|
57
|
+
|
|
58
|
+
- SPEC refs.
|
|
59
|
+
|
|
60
|
+
## Projection Targets
|
|
61
|
+
|
|
62
|
+
- Runtime or agent config projections, if any.
|
|
63
|
+
|
|
64
|
+
## Open Questions
|
|
65
|
+
|
|
66
|
+
- Question to resolve before implementation.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: base.SPEC.md
|
|
3
|
+
template_kind: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Role
|
|
7
|
+
|
|
8
|
+
Define the durable agent role and trigger conditions.
|
|
9
|
+
|
|
10
|
+
# Allowed Resources
|
|
11
|
+
|
|
12
|
+
- Resources the agent may read or write.
|
|
13
|
+
|
|
14
|
+
# Forbidden Actions
|
|
15
|
+
|
|
16
|
+
- Actions this agent must never perform.
|
|
17
|
+
|
|
18
|
+
# Input Context
|
|
19
|
+
|
|
20
|
+
- Required room, goal, task, pack, or queue context.
|
|
21
|
+
|
|
22
|
+
# Output Contract
|
|
23
|
+
|
|
24
|
+
- Required report, patch, receipt, or handoff.
|
|
25
|
+
|
|
26
|
+
# Receipt / Evidence Contract
|
|
27
|
+
|
|
28
|
+
- Attempt, validation, and final evidence requirements.
|
|
29
|
+
|
|
30
|
+
# Escalation Behavior
|
|
31
|
+
|
|
32
|
+
- When to stop, ask, or return a blocker.
|
|
33
|
+
|
|
34
|
+
# Projection Targets
|
|
35
|
+
|
|
36
|
+
- `.codex/agents` TOML
|
|
37
|
+
- future OmniRuntime AgentManifest
|
|
38
|
+
- future OmniTx capability object
|
|
39
|
+
- future OmniPL agent definition
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: base.SPEC.md
|
|
3
|
+
template_kind: api
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Service Name
|
|
7
|
+
|
|
8
|
+
API or service identity.
|
|
9
|
+
|
|
10
|
+
# Methods
|
|
11
|
+
|
|
12
|
+
- Method name, request, response, and streaming behavior.
|
|
13
|
+
|
|
14
|
+
# Idempotency
|
|
15
|
+
|
|
16
|
+
- Idempotency keys and replay behavior.
|
|
17
|
+
|
|
18
|
+
# Auth
|
|
19
|
+
|
|
20
|
+
- Required principal, policy, and capability context.
|
|
21
|
+
|
|
22
|
+
# Errors
|
|
23
|
+
|
|
24
|
+
- Error taxonomy and fail-closed behavior.
|
|
25
|
+
|
|
26
|
+
# Versioning
|
|
27
|
+
|
|
28
|
+
- Package/version and compatibility policy.
|
|
29
|
+
|
|
30
|
+
# Conformance Tests
|
|
31
|
+
|
|
32
|
+
- Fixture and integration proof requirements.
|