mdkg 0.1.10 → 0.3.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 +69 -0
- package/README.md +40 -15
- package/dist/cli.js +293 -13
- package/dist/commands/capability.js +13 -8
- package/dist/commands/db.js +185 -1
- package/dist/commands/format.js +1 -1
- package/dist/commands/spec.js +101 -0
- package/dist/commands/work.js +569 -20
- 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/graph/agent_file_types.js +95 -7
- package/dist/graph/capabilities_indexer.js +89 -2
- package/dist/graph/frontmatter.js +6 -0
- package/dist/graph/node.js +8 -2
- package/dist/init/AGENT_START.md +15 -9
- package/dist/init/CLI_COMMAND_MATRIX.md +33 -5
- package/dist/init/README.md +36 -11
- package/dist/init/init-manifest.json +64 -9
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +8 -7
- package/dist/init/templates/default/receipt.md +12 -1
- package/dist/init/templates/default/spec.md +8 -6
- package/dist/init/templates/default/work.md +5 -1
- package/dist/init/templates/default/work_order.md +11 -0
- package/dist/init/templates/skills/base.SKILL.md +66 -0
- package/dist/init/templates/specs/agent.SPEC.md +80 -0
- package/dist/init/templates/specs/api.SPEC.md +33 -0
- package/dist/init/templates/specs/base.SPEC.md +120 -0
- package/dist/init/templates/specs/capability.SPEC.md +45 -0
- package/dist/init/templates/specs/integration.SPEC.md +25 -0
- package/dist/init/templates/specs/model.SPEC.md +21 -0
- package/dist/init/templates/specs/project.SPEC.md +39 -0
- package/dist/init/templates/specs/runtime-agent.SPEC.md +49 -0
- package/dist/init/templates/specs/runtime-image.SPEC.md +21 -0
- package/dist/init/templates/specs/tool.SPEC.md +25 -0
- package/dist/util/argparse.js +8 -0
- package/package.json +5 -2
package/dist/commands/work.js
CHANGED
|
@@ -6,11 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.runWorkContractNewCommand = runWorkContractNewCommand;
|
|
7
7
|
exports.runWorkOrderNewCommand = runWorkOrderNewCommand;
|
|
8
8
|
exports.runWorkOrderUpdateCommand = runWorkOrderUpdateCommand;
|
|
9
|
+
exports.runWorkOrderStatusCommand = runWorkOrderStatusCommand;
|
|
10
|
+
exports.runWorkTriggerCommand = runWorkTriggerCommand;
|
|
9
11
|
exports.runWorkReceiptNewCommand = runWorkReceiptNewCommand;
|
|
10
12
|
exports.runWorkReceiptUpdateCommand = runWorkReceiptUpdateCommand;
|
|
13
|
+
exports.runWorkReceiptVerifyCommand = runWorkReceiptVerifyCommand;
|
|
11
14
|
exports.runWorkArtifactAddCommand = runWorkArtifactAddCommand;
|
|
12
15
|
const fs_1 = __importDefault(require("fs"));
|
|
13
16
|
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
14
18
|
const config_1 = require("../core/config");
|
|
15
19
|
const frontmatter_1 = require("../graph/frontmatter");
|
|
16
20
|
const indexer_1 = require("../graph/indexer");
|
|
@@ -21,15 +25,20 @@ const loader_1 = require("../templates/loader");
|
|
|
21
25
|
const date_1 = require("../util/date");
|
|
22
26
|
const errors_1 = require("../util/errors");
|
|
23
27
|
const id_1 = require("../util/id");
|
|
28
|
+
const refs_1 = require("../util/refs");
|
|
24
29
|
const qid_1 = require("../util/qid");
|
|
25
30
|
const atomic_1 = require("../util/atomic");
|
|
26
31
|
const lock_1 = require("../util/lock");
|
|
27
32
|
const event_support_1 = require("./event_support");
|
|
28
33
|
const archive_1 = require("./archive");
|
|
34
|
+
const project_db_1 = require("../core/project_db");
|
|
35
|
+
const project_db_migrations_1 = require("../core/project_db_migrations");
|
|
36
|
+
const project_db_queue_1 = require("../core/project_db_queue");
|
|
29
37
|
const PRICING_MODELS = new Set(["free", "included", "quoted", "fixed", "metered", "subscription"]);
|
|
30
38
|
const ORDER_STATUSES = new Set(["submitted", "accepted", "running", "completed", "cancelled", "failed"]);
|
|
31
39
|
const RECEIPT_STATUSES = new Set(["recorded", "verified", "rejected", "superseded"]);
|
|
32
40
|
const OUTCOMES = new Set(["success", "partial", "failure"]);
|
|
41
|
+
const REDACTION_POLICIES = new Set(["refs_and_hashes_only", "redacted_summary", "external_private"]);
|
|
33
42
|
function parseCsvList(raw) {
|
|
34
43
|
if (!raw) {
|
|
35
44
|
return [];
|
|
@@ -70,6 +79,83 @@ function normalizeEnum(value, flag, allowed) {
|
|
|
70
79
|
}
|
|
71
80
|
return normalized;
|
|
72
81
|
}
|
|
82
|
+
function normalizeSha256Ref(value, flag) {
|
|
83
|
+
if (value === undefined) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const normalized = value.toLowerCase();
|
|
87
|
+
if (!(0, refs_1.isSha256Ref)(normalized)) {
|
|
88
|
+
throw new errors_1.UsageError(`${flag} must be sha256:<64 lowercase hex chars>`);
|
|
89
|
+
}
|
|
90
|
+
return normalized;
|
|
91
|
+
}
|
|
92
|
+
function normalizeSha256Refs(value, flag) {
|
|
93
|
+
return parseCsvList(value).map((hash) => normalizeSha256Ref(hash, flag));
|
|
94
|
+
}
|
|
95
|
+
function stableJson(value) {
|
|
96
|
+
if (Array.isArray(value)) {
|
|
97
|
+
return `[${value.map((item) => stableJson(item)).join(",")}]`;
|
|
98
|
+
}
|
|
99
|
+
if (value && typeof value === "object") {
|
|
100
|
+
const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b));
|
|
101
|
+
return `{${entries
|
|
102
|
+
.map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`)
|
|
103
|
+
.join(",")}}`;
|
|
104
|
+
}
|
|
105
|
+
return JSON.stringify(value);
|
|
106
|
+
}
|
|
107
|
+
function hashStablePayload(value) {
|
|
108
|
+
return `sha256:${crypto_1.default.createHash("sha256").update(stableJson(value)).digest("hex")}`;
|
|
109
|
+
}
|
|
110
|
+
function buildWorkOrderPayloadHash(options) {
|
|
111
|
+
return hashStablePayload({
|
|
112
|
+
work_id: options.workId,
|
|
113
|
+
work_version: options.workVersion,
|
|
114
|
+
requester: options.requester,
|
|
115
|
+
request_ref: options.requestRef,
|
|
116
|
+
trigger_ref: options.triggerRef,
|
|
117
|
+
input_refs: options.inputRefs,
|
|
118
|
+
queue_refs: options.queueRefs,
|
|
119
|
+
requested_outputs: options.requestedOutputs,
|
|
120
|
+
constraint_refs: options.constraintRefs,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function portableSegment(value) {
|
|
124
|
+
return (value
|
|
125
|
+
.toLowerCase()
|
|
126
|
+
.replace(/[^a-z0-9_]+/g, ".")
|
|
127
|
+
.replace(/^[._-]+|[._-]+$/g, "")
|
|
128
|
+
.slice(0, 80) || "work");
|
|
129
|
+
}
|
|
130
|
+
function normalizeQueueName(value) {
|
|
131
|
+
if (value === undefined) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
const normalized = value.toLowerCase();
|
|
135
|
+
if (!(0, id_1.isPortableId)(normalized)) {
|
|
136
|
+
throw new errors_1.UsageError("--enqueue must be a lowercase portable queue name");
|
|
137
|
+
}
|
|
138
|
+
return normalized;
|
|
139
|
+
}
|
|
140
|
+
function queueRefForWorkOrder(queueName, orderId) {
|
|
141
|
+
return `queue://project-db/${queueName}/${orderId}`;
|
|
142
|
+
}
|
|
143
|
+
function loadWorkTriggerQueueDatabase(root, queueName) {
|
|
144
|
+
const config = (0, config_1.loadConfig)(root);
|
|
145
|
+
const verification = (0, project_db_migrations_1.verifyProjectDb)(root, config);
|
|
146
|
+
if (!verification.ok) {
|
|
147
|
+
throw new errors_1.ValidationError("work trigger --enqueue requires a valid project DB; run mdkg db init, mdkg db migrate, and mdkg db verify");
|
|
148
|
+
}
|
|
149
|
+
const databasePath = (0, project_db_1.resolveConfiguredProjectDbLayout)(root, config.db).runtimeFile;
|
|
150
|
+
const queue = (0, project_db_queue_1.readProjectQueue)(databasePath, queueName);
|
|
151
|
+
if (!queue) {
|
|
152
|
+
throw new errors_1.NotFoundError(`project DB queue not found: ${queueName}; run mdkg db queue create ${queueName}`);
|
|
153
|
+
}
|
|
154
|
+
if (queue.status !== "active") {
|
|
155
|
+
throw new errors_1.ValidationError(`project DB queue ${queueName} is paused; run mdkg db queue resume ${queueName}`);
|
|
156
|
+
}
|
|
157
|
+
return databasePath;
|
|
158
|
+
}
|
|
73
159
|
function slugifyTitle(title) {
|
|
74
160
|
const slug = title
|
|
75
161
|
.trim()
|
|
@@ -113,6 +199,67 @@ function requireReferenceNode(index, ws, idOrQid, type, label) {
|
|
|
113
199
|
}
|
|
114
200
|
return node;
|
|
115
201
|
}
|
|
202
|
+
function resolveReadableWorkNode(index, idOrQid, ws, type, label) {
|
|
203
|
+
const resolved = (0, qid_1.resolveQid)(index, idOrQid, ws);
|
|
204
|
+
if (resolved.status !== "ok") {
|
|
205
|
+
throw new errors_1.NotFoundError((0, qid_1.formatResolveError)(label, idOrQid, resolved, ws));
|
|
206
|
+
}
|
|
207
|
+
const node = index.nodes[resolved.qid];
|
|
208
|
+
if (!node || node.type !== type) {
|
|
209
|
+
throw new errors_1.NotFoundError(`${label} not found: ${idOrQid}`);
|
|
210
|
+
}
|
|
211
|
+
return node;
|
|
212
|
+
}
|
|
213
|
+
function resolveTriggerWorkNode(index, ws, refRaw) {
|
|
214
|
+
const ref = normalizePortableIdRef(refRaw, "<work-or-capability-ref>");
|
|
215
|
+
const resolved = (0, qid_1.resolveQid)(index, ref, ws);
|
|
216
|
+
if (resolved.status !== "ok") {
|
|
217
|
+
throw new errors_1.NotFoundError((0, qid_1.formatResolveError)("work contract or capability", refRaw, resolved, ws));
|
|
218
|
+
}
|
|
219
|
+
const node = index.nodes[resolved.qid];
|
|
220
|
+
if (!node) {
|
|
221
|
+
throw new errors_1.NotFoundError(`work contract or capability not found: ${refRaw}`);
|
|
222
|
+
}
|
|
223
|
+
if (node.type === "work") {
|
|
224
|
+
return { workNode: node };
|
|
225
|
+
}
|
|
226
|
+
if (node.type !== "spec") {
|
|
227
|
+
throw new errors_1.UsageError(`work trigger requires a WORK.md or SPEC.md ref, got ${node.type}: ${node.qid}`);
|
|
228
|
+
}
|
|
229
|
+
const candidates = new Map();
|
|
230
|
+
const specDir = path_1.default.posix.dirname(node.path);
|
|
231
|
+
for (const contractPath of toStringList(node.attributes.work_contracts)) {
|
|
232
|
+
const normalizedPath = path_1.default.posix.normalize(path_1.default.posix.join(specDir, contractPath));
|
|
233
|
+
for (const candidate of Object.values(index.nodes)) {
|
|
234
|
+
if (candidate.type === "work" && candidate.ws === node.ws && candidate.path === normalizedPath) {
|
|
235
|
+
candidates.set(candidate.qid, candidate);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (const qid of node.edges.relates) {
|
|
240
|
+
const candidate = index.nodes[qid];
|
|
241
|
+
if (candidate?.type === "work") {
|
|
242
|
+
candidates.set(candidate.qid, candidate);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const reverseRelates = index.reverse_edges[node.qid]?.relates ?? [];
|
|
246
|
+
for (const qid of reverseRelates) {
|
|
247
|
+
const candidate = index.nodes[qid];
|
|
248
|
+
if (candidate?.type === "work") {
|
|
249
|
+
candidates.set(candidate.qid, candidate);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const workNodes = Array.from(candidates.values()).sort((a, b) => a.qid.localeCompare(b.qid));
|
|
253
|
+
if (workNodes.length === 0) {
|
|
254
|
+
throw new errors_1.NotFoundError(`SPEC.md ${node.qid} has no resolvable WORK.md contract`);
|
|
255
|
+
}
|
|
256
|
+
if (workNodes.length > 1) {
|
|
257
|
+
throw new errors_1.UsageError(`SPEC.md ${node.qid} has multiple work contracts; trigger one explicitly: ${workNodes
|
|
258
|
+
.map((workNode) => workNode.qid)
|
|
259
|
+
.join(", ")}`);
|
|
260
|
+
}
|
|
261
|
+
return { workNode: workNodes[0], sourceNode: node };
|
|
262
|
+
}
|
|
116
263
|
function nodeReceipt(root, node) {
|
|
117
264
|
return {
|
|
118
265
|
workspace: node.ws,
|
|
@@ -123,6 +270,190 @@ function nodeReceipt(root, node) {
|
|
|
123
270
|
title: node.title,
|
|
124
271
|
};
|
|
125
272
|
}
|
|
273
|
+
function resolveOptionalQid(index, ws, idOrQid) {
|
|
274
|
+
if (!idOrQid) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
const resolved = (0, qid_1.resolveQid)(index, idOrQid, ws);
|
|
278
|
+
return resolved.status === "ok" ? resolved.qid : undefined;
|
|
279
|
+
}
|
|
280
|
+
function listReceiptsForOrder(index, order) {
|
|
281
|
+
const orderRefs = new Set([order.id, order.qid, `${order.ws}:${order.id}`]);
|
|
282
|
+
return Object.values(index.nodes)
|
|
283
|
+
.filter((node) => node.type === "receipt" && orderRefs.has(String(node.attributes.work_order_id ?? "")))
|
|
284
|
+
.sort((a, b) => a.qid.localeCompare(b.qid));
|
|
285
|
+
}
|
|
286
|
+
function buildWorkOrderStatusReceipt(index, order) {
|
|
287
|
+
const workId = typeof order.attributes.work_id === "string" ? order.attributes.work_id : undefined;
|
|
288
|
+
const receipts = listReceiptsForOrder(index, order).map((receipt) => ({
|
|
289
|
+
id: receipt.id,
|
|
290
|
+
qid: receipt.qid,
|
|
291
|
+
path: receipt.path,
|
|
292
|
+
title: receipt.title,
|
|
293
|
+
receipt_status: typeof receipt.attributes.receipt_status === "string" ? receipt.attributes.receipt_status : undefined,
|
|
294
|
+
outcome: typeof receipt.attributes.outcome === "string" ? receipt.attributes.outcome : undefined,
|
|
295
|
+
redaction_policy: typeof receipt.attributes.redaction_policy === "string" ? receipt.attributes.redaction_policy : undefined,
|
|
296
|
+
artifacts: receipt.artifacts,
|
|
297
|
+
proof_refs: toStringList(receipt.attributes.proof_refs),
|
|
298
|
+
attestation_refs: toStringList(receipt.attributes.attestation_refs),
|
|
299
|
+
evidence_hashes: toStringList(receipt.attributes.evidence_hashes),
|
|
300
|
+
input_hashes: toStringList(receipt.attributes.input_hashes),
|
|
301
|
+
output_hashes: toStringList(receipt.attributes.output_hashes),
|
|
302
|
+
updated: receipt.updated,
|
|
303
|
+
}));
|
|
304
|
+
return {
|
|
305
|
+
kind: "work_order_status",
|
|
306
|
+
order: {
|
|
307
|
+
workspace: order.ws,
|
|
308
|
+
id: order.id,
|
|
309
|
+
qid: order.qid,
|
|
310
|
+
path: order.path,
|
|
311
|
+
title: order.title,
|
|
312
|
+
status: typeof order.attributes.order_status === "string" ? order.attributes.order_status : undefined,
|
|
313
|
+
work_id: workId,
|
|
314
|
+
work_qid: resolveOptionalQid(index, order.ws, workId),
|
|
315
|
+
requester: typeof order.attributes.requester === "string" ? order.attributes.requester : undefined,
|
|
316
|
+
request_ref: typeof order.attributes.request_ref === "string" ? order.attributes.request_ref : undefined,
|
|
317
|
+
trigger_ref: typeof order.attributes.trigger_ref === "string" ? order.attributes.trigger_ref : undefined,
|
|
318
|
+
payload_hash: typeof order.attributes.payload_hash === "string" ? order.attributes.payload_hash : undefined,
|
|
319
|
+
input_refs: toStringList(order.attributes.input_refs),
|
|
320
|
+
queue_refs: toStringList(order.attributes.queue_refs),
|
|
321
|
+
requested_outputs: toStringList(order.attributes.requested_outputs),
|
|
322
|
+
constraint_refs: toStringList(order.attributes.constraint_refs),
|
|
323
|
+
artifact_policy: typeof order.attributes.artifact_policy === "string" ? order.attributes.artifact_policy : undefined,
|
|
324
|
+
artifacts: order.artifacts,
|
|
325
|
+
created: order.created,
|
|
326
|
+
updated: order.updated,
|
|
327
|
+
},
|
|
328
|
+
receipt_count: receipts.length,
|
|
329
|
+
receipts,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function buildArchiveIdsByWorkspace(index) {
|
|
333
|
+
const byWorkspace = {};
|
|
334
|
+
for (const node of Object.values(index.nodes)) {
|
|
335
|
+
if (node.type !== "archive") {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (!byWorkspace[node.ws]) {
|
|
339
|
+
byWorkspace[node.ws] = new Set();
|
|
340
|
+
}
|
|
341
|
+
byWorkspace[node.ws].add(node.id);
|
|
342
|
+
}
|
|
343
|
+
return byWorkspace;
|
|
344
|
+
}
|
|
345
|
+
function verifyArchiveRefs(index, ws, refsByField, errors) {
|
|
346
|
+
const archiveIdsByWorkspace = buildArchiveIdsByWorkspace(index);
|
|
347
|
+
for (const [field, refs] of Object.entries(refsByField)) {
|
|
348
|
+
for (const [indexValue, ref] of refs.entries()) {
|
|
349
|
+
if (!ref.startsWith("archive://")) {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const archiveId = (0, refs_1.archiveIdFromUri)(ref);
|
|
353
|
+
if (!archiveId) {
|
|
354
|
+
errors.push(`${field}[${indexValue}] has malformed archive ref ${ref}`);
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (!archiveIdsByWorkspace[ws]?.has(archiveId)) {
|
|
358
|
+
errors.push(`${field}[${indexValue}] references missing archive ${ref}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function addVerifyCheck(checks, errors, name, ok, detail) {
|
|
364
|
+
checks.push({ name, ok, detail });
|
|
365
|
+
if (!ok) {
|
|
366
|
+
errors.push(detail);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function buildWorkReceiptVerifyReceipt(index, receipt) {
|
|
370
|
+
const errors = [];
|
|
371
|
+
const warnings = [];
|
|
372
|
+
const checks = [];
|
|
373
|
+
const workOrderId = typeof receipt.attributes.work_order_id === "string" ? receipt.attributes.work_order_id : undefined;
|
|
374
|
+
const workOrder = workOrderId
|
|
375
|
+
? resolveTypedReadableNode(index, receipt.ws, workOrderId, "work_order")
|
|
376
|
+
: undefined;
|
|
377
|
+
const workId = typeof workOrder?.attributes.work_id === "string" ? workOrder.attributes.work_id : undefined;
|
|
378
|
+
const workNode = workId ? resolveTypedReadableNode(index, workOrder?.ws ?? receipt.ws, workId, "work") : undefined;
|
|
379
|
+
const artifacts = receipt.artifacts;
|
|
380
|
+
const proofRefs = toStringList(receipt.attributes.proof_refs);
|
|
381
|
+
const attestationRefs = toStringList(receipt.attributes.attestation_refs);
|
|
382
|
+
const evidenceHashes = toStringList(receipt.attributes.evidence_hashes);
|
|
383
|
+
const inputHashes = toStringList(receipt.attributes.input_hashes);
|
|
384
|
+
const outputHashes = toStringList(receipt.attributes.output_hashes);
|
|
385
|
+
const evidenceCount = artifacts.length +
|
|
386
|
+
proofRefs.length +
|
|
387
|
+
attestationRefs.length +
|
|
388
|
+
evidenceHashes.length +
|
|
389
|
+
inputHashes.length +
|
|
390
|
+
outputHashes.length;
|
|
391
|
+
addVerifyCheck(checks, errors, "work_order_link", workOrder !== undefined, workOrder ? `linked to ${workOrder.qid}` : `work_order_id references missing WORK_ORDER.md ${workOrderId ?? ""}`.trim());
|
|
392
|
+
addVerifyCheck(checks, errors, "work_link", !workOrder || workNode !== undefined, workNode ? `linked to ${workNode.qid}` : workOrder ? `work_id references missing WORK.md ${workId ?? ""}`.trim() : "work order missing");
|
|
393
|
+
addVerifyCheck(checks, errors, "outcome", typeof receipt.attributes.outcome === "string", typeof receipt.attributes.outcome === "string" ? `outcome ${receipt.attributes.outcome}` : "outcome is missing");
|
|
394
|
+
addVerifyCheck(checks, errors, "receipt_status", receipt.attributes.receipt_status !== "rejected", receipt.attributes.receipt_status === "rejected"
|
|
395
|
+
? "receipt_status is rejected"
|
|
396
|
+
: `receipt_status ${String(receipt.attributes.receipt_status ?? "unknown")}`);
|
|
397
|
+
addVerifyCheck(checks, errors, "evidence_present", evidenceCount > 0, evidenceCount > 0 ? `${evidenceCount} evidence reference(s) present` : "receipt has no artifacts, proof refs, attestations, or hashes");
|
|
398
|
+
const archiveErrors = [];
|
|
399
|
+
verifyArchiveRefs(index, receipt.ws, {
|
|
400
|
+
artifacts,
|
|
401
|
+
proof_refs: proofRefs,
|
|
402
|
+
attestation_refs: attestationRefs,
|
|
403
|
+
}, archiveErrors);
|
|
404
|
+
addVerifyCheck(checks, errors, "archive_refs", archiveErrors.length === 0, archiveErrors.length === 0 ? "archive refs resolve" : archiveErrors.join("; "));
|
|
405
|
+
if (typeof receipt.attributes.redaction_policy !== "string") {
|
|
406
|
+
warnings.push("redaction_policy is missing; legacy receipt remains readable but not explicitly redaction-scoped");
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
addVerifyCheck(checks, errors, "redaction_policy", true, `redaction_policy ${receipt.attributes.redaction_policy}`);
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
kind: "work_receipt_verify",
|
|
413
|
+
ok: errors.length === 0,
|
|
414
|
+
receipt: {
|
|
415
|
+
workspace: receipt.ws,
|
|
416
|
+
id: receipt.id,
|
|
417
|
+
qid: receipt.qid,
|
|
418
|
+
path: receipt.path,
|
|
419
|
+
title: receipt.title,
|
|
420
|
+
receipt_status: typeof receipt.attributes.receipt_status === "string" ? receipt.attributes.receipt_status : undefined,
|
|
421
|
+
outcome: typeof receipt.attributes.outcome === "string" ? receipt.attributes.outcome : undefined,
|
|
422
|
+
work_order_id: workOrderId,
|
|
423
|
+
work_order_qid: workOrder?.qid,
|
|
424
|
+
redaction_policy: typeof receipt.attributes.redaction_policy === "string" ? receipt.attributes.redaction_policy : undefined,
|
|
425
|
+
artifacts,
|
|
426
|
+
proof_refs: proofRefs,
|
|
427
|
+
attestation_refs: attestationRefs,
|
|
428
|
+
evidence_hashes: evidenceHashes,
|
|
429
|
+
input_hashes: inputHashes,
|
|
430
|
+
output_hashes: outputHashes,
|
|
431
|
+
updated: receipt.updated,
|
|
432
|
+
},
|
|
433
|
+
work_order: workOrder
|
|
434
|
+
? {
|
|
435
|
+
id: workOrder.id,
|
|
436
|
+
qid: workOrder.qid,
|
|
437
|
+
path: workOrder.path,
|
|
438
|
+
status: typeof workOrder.attributes.order_status === "string" ? workOrder.attributes.order_status : undefined,
|
|
439
|
+
work_id: workId,
|
|
440
|
+
work_qid: workNode?.qid,
|
|
441
|
+
payload_hash: typeof workOrder.attributes.payload_hash === "string" ? workOrder.attributes.payload_hash : undefined,
|
|
442
|
+
}
|
|
443
|
+
: undefined,
|
|
444
|
+
checks,
|
|
445
|
+
errors,
|
|
446
|
+
warnings,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
function resolveTypedReadableNode(index, ws, idOrQid, type) {
|
|
450
|
+
const resolved = (0, qid_1.resolveQid)(index, idOrQid, ws);
|
|
451
|
+
if (resolved.status !== "ok") {
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
const node = index.nodes[resolved.qid];
|
|
455
|
+
return node?.type === type ? node : undefined;
|
|
456
|
+
}
|
|
126
457
|
function writeFrontmatterFile(filePath, frontmatter, body) {
|
|
127
458
|
const lines = (0, frontmatter_1.formatFrontmatter)(frontmatter, frontmatter_1.DEFAULT_FRONTMATTER_KEY_ORDER);
|
|
128
459
|
const content = ["---", ...lines, "---", body.trimStart()].join("\n");
|
|
@@ -211,13 +542,62 @@ function printReceipt(action, receipt, json) {
|
|
|
211
542
|
}
|
|
212
543
|
console.log(`work ${action}: ${receipt.qid} (${receipt.path})`);
|
|
213
544
|
}
|
|
545
|
+
function createWorkOrderForWork(options) {
|
|
546
|
+
const workVersion = String(options.workNode.attributes.version ?? "0.1.0");
|
|
547
|
+
const requestRef = options.requestRef ?? "request.redacted";
|
|
548
|
+
const triggerRef = options.triggerRef ?? "trigger.manual";
|
|
549
|
+
const inputRefs = parseCsvList(options.inputRefs);
|
|
550
|
+
const queueRefs = parseCsvList(options.queueRefs);
|
|
551
|
+
const requestedOutputs = options.requestedOutputs !== undefined
|
|
552
|
+
? parseCsvList(options.requestedOutputs)
|
|
553
|
+
: toStringList(options.workNode.attributes.outputs);
|
|
554
|
+
const constraintRefs = parseCsvList(options.constraintRefs);
|
|
555
|
+
const payloadHash = normalizeSha256Ref(options.payloadHash, "--payload-hash") ??
|
|
556
|
+
buildWorkOrderPayloadHash({
|
|
557
|
+
workId: options.workId,
|
|
558
|
+
workVersion,
|
|
559
|
+
requester: options.requester,
|
|
560
|
+
requestRef,
|
|
561
|
+
triggerRef,
|
|
562
|
+
inputRefs,
|
|
563
|
+
queueRefs,
|
|
564
|
+
requestedOutputs,
|
|
565
|
+
constraintRefs,
|
|
566
|
+
});
|
|
567
|
+
const receipt = createAgentWorkflowNode({
|
|
568
|
+
root: options.root,
|
|
569
|
+
ws: options.ws,
|
|
570
|
+
type: "work_order",
|
|
571
|
+
title: options.title,
|
|
572
|
+
id: options.id,
|
|
573
|
+
now: options.now,
|
|
574
|
+
overrides: {
|
|
575
|
+
work_id: options.workId,
|
|
576
|
+
work_version: workVersion,
|
|
577
|
+
requester: options.requester,
|
|
578
|
+
order_status: "submitted",
|
|
579
|
+
request_ref: requestRef,
|
|
580
|
+
trigger_ref: triggerRef,
|
|
581
|
+
payload_hash: payloadHash,
|
|
582
|
+
input_refs: inputRefs,
|
|
583
|
+
queue_refs: queueRefs,
|
|
584
|
+
requested_outputs: requestedOutputs,
|
|
585
|
+
constraint_refs: constraintRefs,
|
|
586
|
+
artifact_policy: "commit_sidecar_and_zip",
|
|
587
|
+
relates: [options.workId],
|
|
588
|
+
},
|
|
589
|
+
});
|
|
590
|
+
return { receipt, payloadHash, workId: options.workId, workVersion };
|
|
591
|
+
}
|
|
214
592
|
function runWorkContractNewCommandLocked(options) {
|
|
215
593
|
const config = (0, config_1.loadConfig)(options.root);
|
|
216
594
|
const ws = normalizeWorkspace(options.ws);
|
|
217
595
|
const { index } = (0, index_cache_1.loadIndex)({ root: options.root, config });
|
|
218
596
|
const agentId = normalizePortableIdRef(options.agentId, "--agent-id");
|
|
597
|
+
const kind = options.kind.toLowerCase();
|
|
219
598
|
const resolvedAgent = (0, qid_1.resolveQid)(index, agentId, ws);
|
|
220
599
|
const relates = resolvedAgent.status === "ok" && index.nodes[resolvedAgent.qid]?.type === "spec" ? [agentId] : [];
|
|
600
|
+
const requiredCapabilities = parseCsvList(options.requiredCapabilities);
|
|
221
601
|
const receipt = createAgentWorkflowNode({
|
|
222
602
|
root: options.root,
|
|
223
603
|
ws,
|
|
@@ -227,9 +607,9 @@ function runWorkContractNewCommandLocked(options) {
|
|
|
227
607
|
now: options.now,
|
|
228
608
|
overrides: {
|
|
229
609
|
agent_id: agentId,
|
|
230
|
-
kind
|
|
610
|
+
kind,
|
|
231
611
|
pricing_model: normalizeEnum(options.pricingModel ?? "quoted", "--pricing-model", PRICING_MODELS),
|
|
232
|
-
required_capabilities:
|
|
612
|
+
required_capabilities: requiredCapabilities.length > 0 ? requiredCapabilities : [kind],
|
|
233
613
|
inputs: parseCsvList(options.inputs),
|
|
234
614
|
outputs: parseCsvList(options.outputs),
|
|
235
615
|
receipt_required: true,
|
|
@@ -244,28 +624,146 @@ function runWorkOrderNewCommandLocked(options) {
|
|
|
244
624
|
const { index } = (0, index_cache_1.loadIndex)({ root: options.root, config });
|
|
245
625
|
const workId = normalizePortableIdRef(options.workId, "--work-id");
|
|
246
626
|
const workNode = requireReferenceNode(index, ws, workId, "work", "work contract");
|
|
247
|
-
const
|
|
248
|
-
const receipt = createAgentWorkflowNode({
|
|
627
|
+
const created = createWorkOrderForWork({
|
|
249
628
|
root: options.root,
|
|
250
629
|
ws,
|
|
251
|
-
type: "work_order",
|
|
252
630
|
title: options.title,
|
|
253
631
|
id: options.id,
|
|
632
|
+
workId,
|
|
633
|
+
workNode,
|
|
634
|
+
requester: options.requester,
|
|
635
|
+
requestRef: options.requestRef,
|
|
636
|
+
triggerRef: options.triggerRef,
|
|
637
|
+
payloadHash: options.payloadHash,
|
|
638
|
+
inputRefs: options.inputRefs,
|
|
639
|
+
queueRefs: options.queueRefs,
|
|
640
|
+
requestedOutputs: options.requestedOutputs,
|
|
641
|
+
constraintRefs: options.constraintRefs,
|
|
642
|
+
now: options.now,
|
|
643
|
+
});
|
|
644
|
+
printReceipt("order created", created.receipt, options.json);
|
|
645
|
+
}
|
|
646
|
+
function runWorkTriggerCommandLocked(options) {
|
|
647
|
+
const config = (0, config_1.loadConfig)(options.root);
|
|
648
|
+
const ws = normalizeWorkspace(options.ws);
|
|
649
|
+
const { index } = (0, index_cache_1.loadIndex)({ root: options.root, config });
|
|
650
|
+
const { workNode, sourceNode } = resolveTriggerWorkNode(index, ws, options.targetRef);
|
|
651
|
+
const requester = options.requester ?? "user.local";
|
|
652
|
+
const requestRef = "request.redacted";
|
|
653
|
+
const triggerRef = "trigger.mdkg-work-trigger";
|
|
654
|
+
const requestedOutputs = toStringList(workNode.attributes.outputs);
|
|
655
|
+
const payloadHash = buildWorkOrderPayloadHash({
|
|
656
|
+
workId: workNode.id,
|
|
657
|
+
workVersion: String(workNode.attributes.version ?? "0.1.0"),
|
|
658
|
+
requester,
|
|
659
|
+
requestRef,
|
|
660
|
+
triggerRef,
|
|
661
|
+
inputRefs: [],
|
|
662
|
+
queueRefs: [],
|
|
663
|
+
requestedOutputs,
|
|
664
|
+
constraintRefs: [],
|
|
665
|
+
});
|
|
666
|
+
const id = options.id
|
|
667
|
+
? normalizePortableId(options.id, "--id")
|
|
668
|
+
: `order.${portableSegment(workNode.id)}.${payloadHash.slice("sha256:".length, "sha256:".length + 12)}`;
|
|
669
|
+
const title = options.title ?? `Trigger ${workNode.title}`;
|
|
670
|
+
const enqueueQueue = normalizeQueueName(options.enqueue);
|
|
671
|
+
const queueRef = enqueueQueue ? queueRefForWorkOrder(enqueueQueue, id) : undefined;
|
|
672
|
+
const queueDatabasePath = enqueueQueue ? loadWorkTriggerQueueDatabase(options.root, enqueueQueue) : undefined;
|
|
673
|
+
const created = createWorkOrderForWork({
|
|
674
|
+
root: options.root,
|
|
675
|
+
ws,
|
|
676
|
+
title,
|
|
677
|
+
id,
|
|
678
|
+
workId: workNode.id,
|
|
679
|
+
workNode,
|
|
680
|
+
requester,
|
|
681
|
+
requestRef,
|
|
682
|
+
triggerRef,
|
|
683
|
+
payloadHash,
|
|
684
|
+
queueRefs: queueRef,
|
|
254
685
|
now: options.now,
|
|
255
|
-
overrides: {
|
|
256
|
-
work_id: workId,
|
|
257
|
-
work_version: workVersion,
|
|
258
|
-
requester: options.requester,
|
|
259
|
-
order_status: "submitted",
|
|
260
|
-
request_ref: options.requestRef ?? "request.redacted",
|
|
261
|
-
input_refs: parseCsvList(options.inputRefs),
|
|
262
|
-
requested_outputs: parseCsvList(options.requestedOutputs),
|
|
263
|
-
constraint_refs: parseCsvList(options.constraintRefs),
|
|
264
|
-
artifact_policy: "commit_sidecar_and_zip",
|
|
265
|
-
relates: [workId],
|
|
266
|
-
},
|
|
267
686
|
});
|
|
268
|
-
|
|
687
|
+
let queueDelivery;
|
|
688
|
+
if (enqueueQueue && queueDatabasePath && queueRef) {
|
|
689
|
+
const queuePayload = {
|
|
690
|
+
kind: "mdkg.work_order.triggered",
|
|
691
|
+
schema_version: 1,
|
|
692
|
+
target_ref: options.targetRef,
|
|
693
|
+
work_id: workNode.id,
|
|
694
|
+
work_qid: workNode.qid,
|
|
695
|
+
work_order_id: created.receipt.id,
|
|
696
|
+
work_order_qid: created.receipt.qid,
|
|
697
|
+
work_order_path: created.receipt.path,
|
|
698
|
+
requester,
|
|
699
|
+
request_ref: requestRef,
|
|
700
|
+
trigger_ref: triggerRef,
|
|
701
|
+
payload_hash: created.payloadHash,
|
|
702
|
+
queue_ref: queueRef,
|
|
703
|
+
executed: false,
|
|
704
|
+
};
|
|
705
|
+
if (sourceNode) {
|
|
706
|
+
queuePayload.source_qid = sourceNode.qid;
|
|
707
|
+
}
|
|
708
|
+
const delivery = (0, project_db_queue_1.enqueueProjectQueueMessage)(queueDatabasePath, {
|
|
709
|
+
queue_name: enqueueQueue,
|
|
710
|
+
message_id: created.receipt.id,
|
|
711
|
+
dedupe_key: created.receipt.qid,
|
|
712
|
+
payload: queuePayload,
|
|
713
|
+
now_ms: options.now?.getTime(),
|
|
714
|
+
});
|
|
715
|
+
queueDelivery = {
|
|
716
|
+
queue_name: enqueueQueue,
|
|
717
|
+
queue_ref: queueRef,
|
|
718
|
+
message_id: created.receipt.id,
|
|
719
|
+
message: delivery.message,
|
|
720
|
+
created: delivery.created,
|
|
721
|
+
duplicate: delivery.duplicate,
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
const event = (0, event_support_1.appendAutomaticEvent)({
|
|
725
|
+
root: options.root,
|
|
726
|
+
ws,
|
|
727
|
+
kind: queueDelivery ? "WORK_TRIGGER_ENQUEUED" : "WORK_TRIGGERED",
|
|
728
|
+
status: "ok",
|
|
729
|
+
refs: [created.receipt.id, workNode.id, ...(queueRef ? [queueRef] : [])],
|
|
730
|
+
notes: queueDelivery
|
|
731
|
+
? `work trigger created order mirror and enqueued ${queueDelivery.message_id} on project DB queue ${queueDelivery.queue_name}; no work executed`
|
|
732
|
+
: "work trigger created order mirror; no work executed",
|
|
733
|
+
now: options.now,
|
|
734
|
+
});
|
|
735
|
+
if (options.json) {
|
|
736
|
+
console.log(JSON.stringify({
|
|
737
|
+
action: "triggered",
|
|
738
|
+
node: created.receipt,
|
|
739
|
+
trigger: {
|
|
740
|
+
target_ref: options.targetRef,
|
|
741
|
+
source_qid: sourceNode?.qid,
|
|
742
|
+
work_qid: workNode.qid,
|
|
743
|
+
payload_hash: created.payloadHash,
|
|
744
|
+
executed: false,
|
|
745
|
+
enqueue: queueDelivery
|
|
746
|
+
? {
|
|
747
|
+
requested: true,
|
|
748
|
+
queue_name: queueDelivery.queue_name,
|
|
749
|
+
queue_ref: queueDelivery.queue_ref,
|
|
750
|
+
message_id: queueDelivery.message_id,
|
|
751
|
+
enqueued: true,
|
|
752
|
+
created: queueDelivery.created,
|
|
753
|
+
duplicate: queueDelivery.duplicate,
|
|
754
|
+
message_status: queueDelivery.message.status,
|
|
755
|
+
message_payload_hash: queueDelivery.message.payload_hash,
|
|
756
|
+
}
|
|
757
|
+
: { requested: false },
|
|
758
|
+
event_appended: event !== undefined,
|
|
759
|
+
},
|
|
760
|
+
}, null, 2));
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
console.log(`work triggered: ${created.receipt.qid} (${created.receipt.path})`);
|
|
764
|
+
if (queueDelivery) {
|
|
765
|
+
console.log(`queue enqueued: ${queueDelivery.queue_name}/${queueDelivery.message_id}`);
|
|
766
|
+
}
|
|
269
767
|
}
|
|
270
768
|
function runWorkOrderUpdateCommandLocked(options) {
|
|
271
769
|
const loaded = loadMutableAgentNode(options.root, options.id, options.ws, "work_order");
|
|
@@ -273,12 +771,27 @@ function runWorkOrderUpdateCommandLocked(options) {
|
|
|
273
771
|
loaded.frontmatter.order_status = normalizeEnum(options.status, "--status", ORDER_STATUSES);
|
|
274
772
|
}
|
|
275
773
|
loaded.frontmatter.input_refs = appendUnique(toStringList(loaded.frontmatter.input_refs), parseCsvList(options.addInputRefs));
|
|
774
|
+
loaded.frontmatter.queue_refs = appendUnique(toStringList(loaded.frontmatter.queue_refs), parseCsvList(options.addQueueRefs));
|
|
276
775
|
loaded.frontmatter.artifacts = appendUnique(toStringList(loaded.frontmatter.artifacts), parseCsvList(options.addArtifacts));
|
|
277
776
|
loaded.frontmatter.updated = (0, date_1.formatDate)(options.now ?? new Date());
|
|
278
777
|
writeFrontmatterFile(loaded.filePath, loaded.frontmatter, loaded.body);
|
|
279
778
|
maybeReindex(options.root, loaded.config);
|
|
280
779
|
printReceipt("order updated", nodeReceipt(options.root, loaded.node), options.json);
|
|
281
780
|
}
|
|
781
|
+
function runWorkOrderStatusCommandLocked(options) {
|
|
782
|
+
const config = (0, config_1.loadConfig)(options.root);
|
|
783
|
+
const ws = normalizeWorkspace(options.ws);
|
|
784
|
+
const { index } = (0, index_cache_1.loadIndex)({ root: options.root, config });
|
|
785
|
+
const order = resolveReadableWorkNode(index, options.id, ws, "work_order", "work order");
|
|
786
|
+
const receipt = buildWorkOrderStatusReceipt(index, order);
|
|
787
|
+
if (options.json) {
|
|
788
|
+
console.log(JSON.stringify(receipt, null, 2));
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
console.log(`${receipt.order.qid}: ${receipt.order.status ?? "unknown"}`);
|
|
792
|
+
console.log(`work: ${receipt.order.work_qid ?? receipt.order.work_id ?? "unknown"}`);
|
|
793
|
+
console.log(`receipts: ${receipt.receipt_count}`);
|
|
794
|
+
}
|
|
282
795
|
function runWorkReceiptNewCommandLocked(options) {
|
|
283
796
|
const config = (0, config_1.loadConfig)(options.root);
|
|
284
797
|
const ws = normalizeWorkspace(options.ws);
|
|
@@ -297,11 +810,13 @@ function runWorkReceiptNewCommandLocked(options) {
|
|
|
297
810
|
receipt_status: normalizeEnum(options.receiptStatus ?? "recorded", "--receipt-status", RECEIPT_STATUSES),
|
|
298
811
|
outcome: normalizeEnum(options.outcome, "--outcome", OUTCOMES),
|
|
299
812
|
cost_ref: options.costRef ?? "cost.redacted",
|
|
813
|
+
redaction_policy: normalizeEnum(options.redactionPolicy ?? "refs_and_hashes_only", "--redaction-policy", REDACTION_POLICIES),
|
|
300
814
|
artifacts: parseCsvList(options.artifacts),
|
|
301
815
|
proof_refs: parseCsvList(options.proofRefs),
|
|
302
816
|
attestation_refs: parseCsvList(options.attestationRefs),
|
|
303
|
-
|
|
304
|
-
|
|
817
|
+
evidence_hashes: normalizeSha256Refs(options.evidenceHashes, "--evidence-hashes"),
|
|
818
|
+
input_hashes: normalizeSha256Refs(options.inputHashes, "--input-hashes"),
|
|
819
|
+
output_hashes: normalizeSha256Refs(options.outputHashes, "--output-hashes"),
|
|
305
820
|
relates: [workOrderId],
|
|
306
821
|
},
|
|
307
822
|
});
|
|
@@ -315,11 +830,36 @@ function runWorkReceiptUpdateCommandLocked(options) {
|
|
|
315
830
|
loaded.frontmatter.artifacts = appendUnique(toStringList(loaded.frontmatter.artifacts), parseCsvList(options.addArtifacts));
|
|
316
831
|
loaded.frontmatter.proof_refs = appendUnique(toStringList(loaded.frontmatter.proof_refs), parseCsvList(options.addProofRefs));
|
|
317
832
|
loaded.frontmatter.attestation_refs = appendUnique(toStringList(loaded.frontmatter.attestation_refs), parseCsvList(options.addAttestationRefs));
|
|
833
|
+
loaded.frontmatter.evidence_hashes = appendUnique(toStringList(loaded.frontmatter.evidence_hashes), normalizeSha256Refs(options.addEvidenceHashes, "--add-evidence-hashes"));
|
|
318
834
|
loaded.frontmatter.updated = (0, date_1.formatDate)(options.now ?? new Date());
|
|
319
835
|
writeFrontmatterFile(loaded.filePath, loaded.frontmatter, loaded.body);
|
|
320
836
|
maybeReindex(options.root, loaded.config);
|
|
321
837
|
printReceipt("receipt updated", nodeReceipt(options.root, loaded.node), options.json);
|
|
322
838
|
}
|
|
839
|
+
function runWorkReceiptVerifyCommandLocked(options) {
|
|
840
|
+
const config = (0, config_1.loadConfig)(options.root);
|
|
841
|
+
const ws = normalizeWorkspace(options.ws);
|
|
842
|
+
const { index } = (0, index_cache_1.loadIndex)({ root: options.root, config });
|
|
843
|
+
const receiptNode = resolveReadableWorkNode(index, options.id, ws, "receipt", "receipt");
|
|
844
|
+
const receipt = buildWorkReceiptVerifyReceipt(index, receiptNode);
|
|
845
|
+
if (options.json) {
|
|
846
|
+
console.log(JSON.stringify(receipt, null, 2));
|
|
847
|
+
if (!receipt.ok) {
|
|
848
|
+
throw new errors_1.ValidationError("receipt verification failed");
|
|
849
|
+
}
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
console.log(`${receipt.receipt.qid}: ${receipt.ok ? "ok" : "failed"}`);
|
|
853
|
+
for (const check of receipt.checks) {
|
|
854
|
+
console.log(`- ${check.name}: ${check.ok ? "ok" : "failed"} - ${check.detail}`);
|
|
855
|
+
}
|
|
856
|
+
for (const warning of receipt.warnings) {
|
|
857
|
+
console.log(`warning: ${warning}`);
|
|
858
|
+
}
|
|
859
|
+
if (!receipt.ok) {
|
|
860
|
+
throw new errors_1.ValidationError("receipt verification failed");
|
|
861
|
+
}
|
|
862
|
+
}
|
|
323
863
|
function runWorkArtifactAddCommandLocked(options) {
|
|
324
864
|
const config = (0, config_1.loadConfig)(options.root);
|
|
325
865
|
const ws = normalizeWorkspace(options.ws);
|
|
@@ -388,12 +928,21 @@ function runWorkOrderNewCommand(options) {
|
|
|
388
928
|
function runWorkOrderUpdateCommand(options) {
|
|
389
929
|
return withWorkLock(options.root, () => runWorkOrderUpdateCommandLocked(options));
|
|
390
930
|
}
|
|
931
|
+
function runWorkOrderStatusCommand(options) {
|
|
932
|
+
return runWorkOrderStatusCommandLocked(options);
|
|
933
|
+
}
|
|
934
|
+
function runWorkTriggerCommand(options) {
|
|
935
|
+
return withWorkLock(options.root, () => runWorkTriggerCommandLocked(options));
|
|
936
|
+
}
|
|
391
937
|
function runWorkReceiptNewCommand(options) {
|
|
392
938
|
return withWorkLock(options.root, () => runWorkReceiptNewCommandLocked(options));
|
|
393
939
|
}
|
|
394
940
|
function runWorkReceiptUpdateCommand(options) {
|
|
395
941
|
return withWorkLock(options.root, () => runWorkReceiptUpdateCommandLocked(options));
|
|
396
942
|
}
|
|
943
|
+
function runWorkReceiptVerifyCommand(options) {
|
|
944
|
+
return runWorkReceiptVerifyCommandLocked(options);
|
|
945
|
+
}
|
|
397
946
|
function runWorkArtifactAddCommand(options) {
|
|
398
947
|
return withWorkLock(options.root, () => runWorkArtifactAddCommandLocked(options));
|
|
399
948
|
}
|