@vibe-engineer/artifacts 0.1.0 → 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.
@@ -16,16 +16,16 @@ var ARTIFACT_KINDS = [
16
16
  "skill_manifest"
17
17
  ];
18
18
  var SCHEMA_FILES = {
19
- "work_brief": "schemas/work-brief.schema.json",
20
- "implementation_plan": "schemas/implementation-plan.schema.json",
21
- "verification_delta": "schemas/verification-delta.schema.json",
22
- "build_result": "schemas/build-result.schema.json",
23
- "ship_packet": "schemas/ship-packet.schema.json",
24
- "evidence_packet": "schemas/evidence-packet.schema.json",
25
- "agent_registry_entry": "schemas/agent-registry-entry.schema.json",
26
- "context_file_header": "schemas/context-file-header.schema.json",
27
- "schematic_manifest": "schemas/schematic-manifest.schema.json",
28
- "skill_manifest": "schemas/skill-manifest.schema.json"
19
+ work_brief: "schemas/work-brief.schema.json",
20
+ implementation_plan: "schemas/implementation-plan.schema.json",
21
+ verification_delta: "schemas/verification-delta.schema.json",
22
+ build_result: "schemas/build-result.schema.json",
23
+ ship_packet: "schemas/ship-packet.schema.json",
24
+ evidence_packet: "schemas/evidence-packet.schema.json",
25
+ agent_registry_entry: "schemas/agent-registry-entry.schema.json",
26
+ context_file_header: "schemas/context-file-header.schema.json",
27
+ schematic_manifest: "schemas/schematic-manifest.schema.json",
28
+ skill_manifest: "schemas/skill-manifest.schema.json"
29
29
  };
30
30
  var packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
31
31
  function schemaPathForKind(kind) {
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  loadAllSchemas,
6
6
  loadSchema,
7
7
  schemaPathForKind
8
- } from "./chunk-XQLK7EDB.js";
8
+ } from "./chunk-FCLM65RB.js";
9
9
 
10
10
  // src/errors.js
11
11
  var ValidationErrorCode = Object.freeze({
@@ -35,7 +35,15 @@ var ValidationErrorCode = Object.freeze({
35
35
  MALFORMED_EXTENSION: "MALFORMED_EXTENSION",
36
36
  SCHEMA_INTERNAL_ERROR: "SCHEMA_INTERNAL_ERROR"
37
37
  });
38
- function makeValidationError({ artifactPath, artifactKind, schemaId, schemaVersion, pointer, code, message }) {
38
+ function makeValidationError({
39
+ artifactPath,
40
+ artifactKind,
41
+ schemaId,
42
+ schemaVersion,
43
+ pointer,
44
+ code,
45
+ message
46
+ }) {
39
47
  return {
40
48
  artifactPath: artifactPath ?? null,
41
49
  artifactKind: artifactKind ?? null,
@@ -51,7 +59,25 @@ function makeValidationError({ artifactPath, artifactKind, schemaId, schemaVersi
51
59
  import fs from "fs";
52
60
  import path from "path";
53
61
  import Ajv2020 from "ajv/dist/2020.js";
54
- var CORE_FIELDS = /* @__PURE__ */ new Set(["schemaVersion", "artifactKind", "artifactId", "title", "createdAt", "updatedAt", "producer", "status", "ownership", "links", "extensions", "description", "tags", "sourceRefs", "approvedBy", "supersessionReason", "retention"]);
62
+ var CORE_FIELDS = /* @__PURE__ */ new Set([
63
+ "schemaVersion",
64
+ "artifactKind",
65
+ "artifactId",
66
+ "title",
67
+ "createdAt",
68
+ "updatedAt",
69
+ "producer",
70
+ "status",
71
+ "ownership",
72
+ "links",
73
+ "extensions",
74
+ "description",
75
+ "tags",
76
+ "sourceRefs",
77
+ "approvedBy",
78
+ "supersessionReason",
79
+ "retention"
80
+ ]);
55
81
  var VERIFICATION_CATALOG_LAYERS = Object.freeze([
56
82
  "safety_hooks",
57
83
  "typecheck",
@@ -89,9 +115,12 @@ function createContext(data, artifactPath, schema) {
89
115
  };
90
116
  }
91
117
  function ajvErrorPointer(error) {
92
- if (error.keyword === "required" && error.params?.missingProperty) return pointerJoin(error.instancePath || "", error.params.missingProperty);
93
- if (error.keyword === "additionalProperties" && error.params?.additionalProperty) return pointerJoin(error.instancePath || "", error.params.additionalProperty);
94
- if (error.keyword === "propertyNames" && error.params?.propertyName) return pointerJoin(error.instancePath || "", error.params.propertyName);
118
+ if (error.keyword === "required" && error.params?.missingProperty)
119
+ return pointerJoin(error.instancePath || "", error.params.missingProperty);
120
+ if (error.keyword === "additionalProperties" && error.params?.additionalProperty)
121
+ return pointerJoin(error.instancePath || "", error.params.additionalProperty);
122
+ if (error.keyword === "propertyNames" && error.params?.propertyName)
123
+ return pointerJoin(error.instancePath || "", error.params.propertyName);
95
124
  return error.instancePath || "";
96
125
  }
97
126
  function ajvErrorCode(error) {
@@ -121,12 +150,14 @@ function ajvErrorCode(error) {
121
150
  }
122
151
  }
123
152
  function normalizeAjvErrors(ajvErrors, ctx) {
124
- return (ajvErrors ?? []).map((error) => makeValidationError({
125
- ...ctx,
126
- pointer: ajvErrorPointer(error),
127
- code: ajvErrorCode(error),
128
- message: error.message ?? `Schema validation failed for keyword ${error.keyword}.`
129
- }));
153
+ return (ajvErrors ?? []).map(
154
+ (error) => makeValidationError({
155
+ ...ctx,
156
+ pointer: ajvErrorPointer(error),
157
+ code: ajvErrorCode(error),
158
+ message: error.message ?? `Schema validation failed for keyword ${error.keyword}.`
159
+ })
160
+ );
130
161
  }
131
162
  function createAjv() {
132
163
  return new Ajv2020({
@@ -162,15 +193,39 @@ function validateVersionAndKind(data, expectedKind, errors, ctx) {
162
193
  return;
163
194
  }
164
195
  if (typeof data.schemaVersion !== "string" || !/^\d+\.\d+\.\d+$/.test(data.schemaVersion)) {
165
- addError(errors, ctx, "/schemaVersion", ValidationErrorCode.UNSUPPORTED_VERSION, "schemaVersion must be semantic version 1.0.0.");
196
+ addError(
197
+ errors,
198
+ ctx,
199
+ "/schemaVersion",
200
+ ValidationErrorCode.UNSUPPORTED_VERSION,
201
+ "schemaVersion must be semantic version 1.0.0."
202
+ );
166
203
  } else if (data.schemaVersion !== SUPPORTED_SCHEMA_VERSION) {
167
- addError(errors, ctx, "/schemaVersion", ValidationErrorCode.UNSUPPORTED_VERSION, `Unsupported artifact schemaVersion ${data.schemaVersion}.`);
204
+ addError(
205
+ errors,
206
+ ctx,
207
+ "/schemaVersion",
208
+ ValidationErrorCode.UNSUPPORTED_VERSION,
209
+ `Unsupported artifact schemaVersion ${data.schemaVersion}.`
210
+ );
168
211
  }
169
212
  if (!ARTIFACT_KINDS.includes(data.artifactKind)) {
170
- addError(errors, ctx, "/artifactKind", ValidationErrorCode.ARTIFACT_KIND_MISMATCH, "Unknown artifactKind.");
213
+ addError(
214
+ errors,
215
+ ctx,
216
+ "/artifactKind",
217
+ ValidationErrorCode.ARTIFACT_KIND_MISMATCH,
218
+ "Unknown artifactKind."
219
+ );
171
220
  }
172
221
  if (expectedKind && data.artifactKind !== expectedKind) {
173
- addError(errors, ctx, "/artifactKind", ValidationErrorCode.ARTIFACT_KIND_MISMATCH, `Expected artifactKind ${expectedKind}.`);
222
+ addError(
223
+ errors,
224
+ ctx,
225
+ "/artifactKind",
226
+ ValidationErrorCode.ARTIFACT_KIND_MISMATCH,
227
+ `Expected artifactKind ${expectedKind}.`
228
+ );
174
229
  }
175
230
  }
176
231
  function linkMatches(link, rel, artifactKind, requiredStatus) {
@@ -182,12 +237,24 @@ function evidencePacketLinkMatches(link) {
182
237
  function requireLink(errors, ctx, pointer, link, rel, artifactKind, requiredStatus) {
183
238
  if (!linkMatches(link, rel, artifactKind, requiredStatus)) {
184
239
  const statusText = requiredStatus ? ` with statusAtLinkTime ${requiredStatus}` : "";
185
- addError(errors, ctx, pointer, ValidationErrorCode.BAD_LINK, `Required ${rel} link to ${artifactKind}${statusText} is missing or malformed.`);
240
+ addError(
241
+ errors,
242
+ ctx,
243
+ pointer,
244
+ ValidationErrorCode.BAD_LINK,
245
+ `Required ${rel} link to ${artifactKind}${statusText} is missing or malformed.`
246
+ );
186
247
  }
187
248
  }
188
249
  function requireEvidencePacketRef(errors, ctx, pointer, link) {
189
250
  if (!evidencePacketLinkMatches(link)) {
190
- addError(errors, ctx, pointer, ValidationErrorCode.EVIDENCE_LINK_REQUIRED, "Verification evidence references must be required evidence_for links to evidence_packet artifacts.");
251
+ addError(
252
+ errors,
253
+ ctx,
254
+ pointer,
255
+ ValidationErrorCode.EVIDENCE_LINK_REQUIRED,
256
+ "Verification evidence references must be required evidence_for links to evidence_packet artifacts."
257
+ );
191
258
  }
192
259
  }
193
260
  function validateVerificationCatalog(data, errors, ctx, basePointer = "") {
@@ -197,31 +264,69 @@ function validateVerificationCatalog(data, errors, ctx, basePointer = "") {
197
264
  if (!isObject(item)) return;
198
265
  if (typeof item.layer === "string") seen.add(item.layer);
199
266
  if (item.action === "not_applicable" && (typeof item.rationale !== "string" || item.rationale.trim() === "")) {
200
- addError(errors, ctx, `${basePointer}/requiredItems/${index}/rationale`, ValidationErrorCode.NOT_APPLICABLE_RATIONALE_REQUIRED, "not_applicable verification catalog items require a rationale.");
267
+ addError(
268
+ errors,
269
+ ctx,
270
+ `${basePointer}/requiredItems/${index}/rationale`,
271
+ ValidationErrorCode.NOT_APPLICABLE_RATIONALE_REQUIRED,
272
+ "not_applicable verification catalog items require a rationale."
273
+ );
201
274
  }
202
275
  if (item.action === "blocked") {
203
276
  if (typeof item.blockedBy !== "string" || item.blockedBy.trim() === "") {
204
- addError(errors, ctx, `${basePointer}/requiredItems/${index}/blockedBy`, ValidationErrorCode.BLOCKED_ITEM_METADATA_REQUIRED, "blocked verification catalog items require blockedBy.");
277
+ addError(
278
+ errors,
279
+ ctx,
280
+ `${basePointer}/requiredItems/${index}/blockedBy`,
281
+ ValidationErrorCode.BLOCKED_ITEM_METADATA_REQUIRED,
282
+ "blocked verification catalog items require blockedBy."
283
+ );
205
284
  }
206
285
  if (typeof item.unblockCondition !== "string" || item.unblockCondition.trim() === "") {
207
- addError(errors, ctx, `${basePointer}/requiredItems/${index}/unblockCondition`, ValidationErrorCode.BLOCKED_ITEM_METADATA_REQUIRED, "blocked verification catalog items require unblockCondition.");
286
+ addError(
287
+ errors,
288
+ ctx,
289
+ `${basePointer}/requiredItems/${index}/unblockCondition`,
290
+ ValidationErrorCode.BLOCKED_ITEM_METADATA_REQUIRED,
291
+ "blocked verification catalog items require unblockCondition."
292
+ );
208
293
  }
209
294
  }
210
295
  });
211
296
  for (const layer of VERIFICATION_CATALOG_LAYERS) {
212
297
  if (!seen.has(layer)) {
213
- addError(errors, ctx, `${basePointer}/requiredItems`, ValidationErrorCode.VERIFICATION_CATALOG_INCOMPLETE, `Verification Delta must include catalog layer ${layer}.`);
298
+ addError(
299
+ errors,
300
+ ctx,
301
+ `${basePointer}/requiredItems`,
302
+ ValidationErrorCode.VERIFICATION_CATALOG_INCOMPLETE,
303
+ `Verification Delta must include catalog layer ${layer}.`
304
+ );
214
305
  }
215
306
  }
216
307
  }
217
308
  function requireEvidenceForLinks(data, errors, ctx) {
218
- if (!Array.isArray(data.links) || !data.links.some((link) => isObject(link) && link.rel === "evidence_for" && link.required === true)) {
219
- addError(errors, ctx, "/links", ValidationErrorCode.EVIDENCE_FOR_REQUIRED, "Evidence Packet must include a required top-level evidence_for link.");
309
+ if (!Array.isArray(data.links) || !data.links.some(
310
+ (link) => isObject(link) && link.rel === "evidence_for" && link.required === true
311
+ )) {
312
+ addError(
313
+ errors,
314
+ ctx,
315
+ "/links",
316
+ ValidationErrorCode.EVIDENCE_FOR_REQUIRED,
317
+ "Evidence Packet must include a required top-level evidence_for link."
318
+ );
220
319
  }
221
320
  if (!Array.isArray(data.subjectRefs) || data.subjectRefs.length === 0) return;
222
321
  data.subjectRefs.forEach((ref, index) => {
223
322
  if (!isObject(ref) || ref.rel !== "evidence_for" || ref.required !== true) {
224
- addError(errors, ctx, `/subjectRefs/${index}`, ValidationErrorCode.EVIDENCE_FOR_REQUIRED, "Evidence Packet subjectRefs must use required evidence_for links.");
323
+ addError(
324
+ errors,
325
+ ctx,
326
+ `/subjectRefs/${index}`,
327
+ ValidationErrorCode.EVIDENCE_FOR_REQUIRED,
328
+ "Evidence Packet subjectRefs must use required evidence_for links."
329
+ );
225
330
  }
226
331
  });
227
332
  }
@@ -230,12 +335,24 @@ function semanticChecks(kind, data, errors, ctx) {
230
335
  if (isObject(data.extensions)) {
231
336
  for (const [namespace, value] of Object.entries(data.extensions)) {
232
337
  if (!isObject(value) || typeof value.schemaVersion !== "string") {
233
- addError(errors, ctx, `/extensions/${namespace}`, ValidationErrorCode.MALFORMED_EXTENSION, "Extension value must be an object with schemaVersion.");
338
+ addError(
339
+ errors,
340
+ ctx,
341
+ `/extensions/${namespace}`,
342
+ ValidationErrorCode.MALFORMED_EXTENSION,
343
+ "Extension value must be an object with schemaVersion."
344
+ );
234
345
  continue;
235
346
  }
236
347
  for (const key of Object.keys(value)) {
237
348
  if (key !== "schemaVersion" && CORE_FIELDS.has(key)) {
238
- addError(errors, ctx, `/extensions/${namespace}/${key}`, ValidationErrorCode.MALFORMED_EXTENSION, `Extension ${namespace} must not redefine core field ${key}.`);
349
+ addError(
350
+ errors,
351
+ ctx,
352
+ `/extensions/${namespace}/${key}`,
353
+ ValidationErrorCode.MALFORMED_EXTENSION,
354
+ `Extension ${namespace} must not redefine core field ${key}.`
355
+ );
239
356
  }
240
357
  }
241
358
  }
@@ -243,92 +360,238 @@ function semanticChecks(kind, data, errors, ctx) {
243
360
  switch (kind) {
244
361
  case "work_brief": {
245
362
  if (!Array.isArray(data.links) || !data.links.some((link) => linkMatches(link, "raw_intent", "work_brief"))) {
246
- addError(errors, ctx, "/links", ValidationErrorCode.BAD_LINK, "Work Brief must include a required raw_intent link.");
363
+ addError(
364
+ errors,
365
+ ctx,
366
+ "/links",
367
+ ValidationErrorCode.BAD_LINK,
368
+ "Work Brief must include a required raw_intent link."
369
+ );
247
370
  }
248
371
  break;
249
372
  }
250
373
  case "implementation_plan": {
251
- requireLink(errors, ctx, "/workBriefRef", data.workBriefRef, "derived_from", "work_brief", "ready");
374
+ requireLink(
375
+ errors,
376
+ ctx,
377
+ "/workBriefRef",
378
+ data.workBriefRef,
379
+ "derived_from",
380
+ "work_brief",
381
+ "ready"
382
+ );
252
383
  if (data.status === "approved" && Array.isArray(data.openBlockers) && data.openBlockers.some((b) => b?.blocking === true)) {
253
- addError(errors, ctx, "/openBlockers", ValidationErrorCode.BAD_STATUS_HANDOFF, "Approved Implementation Plan cannot contain unresolved blocking openBlockers.");
384
+ addError(
385
+ errors,
386
+ ctx,
387
+ "/openBlockers",
388
+ ValidationErrorCode.BAD_STATUS_HANDOFF,
389
+ "Approved Implementation Plan cannot contain unresolved blocking openBlockers."
390
+ );
254
391
  }
255
392
  if (data.verificationDelta?.artifactKind !== "verification_delta") {
256
- addError(errors, ctx, "/verificationDelta/artifactKind", ValidationErrorCode.BAD_LINK, "Implementation Plan must embed a Verification Delta artifact.");
393
+ addError(
394
+ errors,
395
+ ctx,
396
+ "/verificationDelta/artifactKind",
397
+ ValidationErrorCode.BAD_LINK,
398
+ "Implementation Plan must embed a Verification Delta artifact."
399
+ );
257
400
  } else {
258
401
  validateVerificationCatalog(data.verificationDelta, errors, ctx, "/verificationDelta");
259
402
  }
260
403
  break;
261
404
  }
262
405
  case "verification_delta": {
263
- requireLink(errors, ctx, "/implementationPlanRef", data.implementationPlanRef, "verification_delta_of", "implementation_plan");
406
+ requireLink(
407
+ errors,
408
+ ctx,
409
+ "/implementationPlanRef",
410
+ data.implementationPlanRef,
411
+ "verification_delta_of",
412
+ "implementation_plan"
413
+ );
264
414
  if (!Array.isArray(data.requiredItems) || data.requiredItems.length === 0) {
265
- addError(errors, ctx, "/requiredItems", ValidationErrorCode.REQUIRED, "Verification Delta must include required catalog items.");
415
+ addError(
416
+ errors,
417
+ ctx,
418
+ "/requiredItems",
419
+ ValidationErrorCode.REQUIRED,
420
+ "Verification Delta must include required catalog items."
421
+ );
266
422
  }
267
423
  validateVerificationCatalog(data, errors, ctx);
268
424
  break;
269
425
  }
270
426
  case "build_result": {
271
- requireLink(errors, ctx, "/implementationPlanRef", data.implementationPlanRef, "implements", "implementation_plan", "approved");
427
+ requireLink(
428
+ errors,
429
+ ctx,
430
+ "/implementationPlanRef",
431
+ data.implementationPlanRef,
432
+ "implements",
433
+ "implementation_plan",
434
+ "approved"
435
+ );
272
436
  if (!Array.isArray(data.verificationRuns) || data.verificationRuns.length === 0) {
273
- addError(errors, ctx, "/verificationRuns", ValidationErrorCode.REQUIRED, "Build Result must reference Evidence Packets for verification claims.");
437
+ addError(
438
+ errors,
439
+ ctx,
440
+ "/verificationRuns",
441
+ ValidationErrorCode.REQUIRED,
442
+ "Build Result must reference Evidence Packets for verification claims."
443
+ );
274
444
  } else {
275
- data.verificationRuns.forEach((run, index) => requireEvidencePacketRef(errors, ctx, `/verificationRuns/${index}/evidencePacketRef`, run?.evidencePacketRef));
445
+ data.verificationRuns.forEach(
446
+ (run, index) => requireEvidencePacketRef(
447
+ errors,
448
+ ctx,
449
+ `/verificationRuns/${index}/evidencePacketRef`,
450
+ run?.evidencePacketRef
451
+ )
452
+ );
276
453
  }
277
454
  if (Array.isArray(data.testsAndVerificationChanged)) {
278
- data.testsAndVerificationChanged.forEach((item, index) => requireEvidencePacketRef(errors, ctx, `/testsAndVerificationChanged/${index}/evidenceRef`, item?.evidenceRef));
455
+ data.testsAndVerificationChanged.forEach(
456
+ (item, index) => requireEvidencePacketRef(
457
+ errors,
458
+ ctx,
459
+ `/testsAndVerificationChanged/${index}/evidenceRef`,
460
+ item?.evidenceRef
461
+ )
462
+ );
279
463
  }
280
464
  if (Array.isArray(data.warningsAndBlockers)) {
281
- data.warningsAndBlockers.forEach((item, index) => requireEvidencePacketRef(errors, ctx, `/warningsAndBlockers/${index}/evidenceRef`, item?.evidenceRef));
465
+ data.warningsAndBlockers.forEach(
466
+ (item, index) => requireEvidencePacketRef(
467
+ errors,
468
+ ctx,
469
+ `/warningsAndBlockers/${index}/evidenceRef`,
470
+ item?.evidenceRef
471
+ )
472
+ );
282
473
  }
283
- if (data.status === "passed" && Array.isArray(data.warningsAndBlockers) && data.warningsAndBlockers.some((item) => item?.blocking === true && ["critical", "major-local"].includes(item?.severity))) {
284
- addError(errors, ctx, "/warningsAndBlockers", ValidationErrorCode.BAD_STATUS_HANDOFF, "Passed Build Result cannot contain blocking critical or major-local evidence.");
474
+ if (data.status === "passed" && Array.isArray(data.warningsAndBlockers) && data.warningsAndBlockers.some(
475
+ (item) => item?.blocking === true && ["critical", "major-local"].includes(item?.severity)
476
+ )) {
477
+ addError(
478
+ errors,
479
+ ctx,
480
+ "/warningsAndBlockers",
481
+ ValidationErrorCode.BAD_STATUS_HANDOFF,
482
+ "Passed Build Result cannot contain blocking critical or major-local evidence."
483
+ );
285
484
  }
286
485
  break;
287
486
  }
288
487
  case "ship_packet": {
289
- requireLink(errors, ctx, "/buildResultRef", data.buildResultRef, "ship_packet_of", "build_result", "passed");
488
+ requireLink(
489
+ errors,
490
+ ctx,
491
+ "/buildResultRef",
492
+ data.buildResultRef,
493
+ "ship_packet_of",
494
+ "build_result",
495
+ "passed"
496
+ );
290
497
  if (Array.isArray(data.finalVerification)) {
291
- data.finalVerification.forEach((item, index) => requireEvidencePacketRef(errors, ctx, `/finalVerification/${index}/evidencePacketRef`, item?.evidencePacketRef));
498
+ data.finalVerification.forEach(
499
+ (item, index) => requireEvidencePacketRef(
500
+ errors,
501
+ ctx,
502
+ `/finalVerification/${index}/evidencePacketRef`,
503
+ item?.evidencePacketRef
504
+ )
505
+ );
292
506
  }
293
507
  if (isObject(data.contextPreservation) && Array.isArray(data.contextPreservation.driftCheckEvidenceRefs)) {
294
- data.contextPreservation.driftCheckEvidenceRefs.forEach((ref, index) => requireEvidencePacketRef(errors, ctx, `/contextPreservation/driftCheckEvidenceRefs/${index}`, ref));
508
+ data.contextPreservation.driftCheckEvidenceRefs.forEach(
509
+ (ref, index) => requireEvidencePacketRef(
510
+ errors,
511
+ ctx,
512
+ `/contextPreservation/driftCheckEvidenceRefs/${index}`,
513
+ ref
514
+ )
515
+ );
295
516
  }
296
517
  if (data.noPushWithoutApproval !== true || data.commitPreparation?.commitPerformedByAgent !== false || data.prPreparation?.prOpenedByAgent !== false) {
297
- addError(errors, ctx, "/noPushWithoutApproval", ValidationErrorCode.BAD_STATUS_HANDOFF, "Ship Packet must preserve no-push/no-PR-without-approval policy.");
518
+ addError(
519
+ errors,
520
+ ctx,
521
+ "/noPushWithoutApproval",
522
+ ValidationErrorCode.BAD_STATUS_HANDOFF,
523
+ "Ship Packet must preserve no-push/no-PR-without-approval policy."
524
+ );
298
525
  }
299
526
  break;
300
527
  }
301
528
  case "evidence_packet": {
302
529
  requireEvidenceForLinks(data, errors, ctx);
303
530
  if (["fail", "blocked"].includes(data.result) && !isObject(data.failureDetails)) {
304
- addError(errors, ctx, "/failureDetails", ValidationErrorCode.REQUIRED, "Failure or blocked evidence requires failureDetails.");
531
+ addError(
532
+ errors,
533
+ ctx,
534
+ "/failureDetails",
535
+ ValidationErrorCode.REQUIRED,
536
+ "Failure or blocked evidence requires failureDetails."
537
+ );
305
538
  }
306
539
  if (data.evidenceClass === "advisory" && data.blocking === true && data.result !== "advisory") {
307
- addError(errors, ctx, "/blocking", ValidationErrorCode.BAD_STATUS_HANDOFF, "Advisory evidence cannot masquerade as deterministic blocker.");
540
+ addError(
541
+ errors,
542
+ ctx,
543
+ "/blocking",
544
+ ValidationErrorCode.BAD_STATUS_HANDOFF,
545
+ "Advisory evidence cannot masquerade as deterministic blocker."
546
+ );
308
547
  }
309
548
  break;
310
549
  }
311
550
  case "agent_registry_entry": {
312
551
  if (!Array.isArray(data.inputSchemas) || data.inputSchemas.length === 0 || !Array.isArray(data.outputSchemas) || data.outputSchemas.length === 0) {
313
- addError(errors, ctx, "/inputSchemas", ValidationErrorCode.REQUIRED, "Agent registry entries require input and output schema refs.");
552
+ addError(
553
+ errors,
554
+ ctx,
555
+ "/inputSchemas",
556
+ ValidationErrorCode.REQUIRED,
557
+ "Agent registry entries require input and output schema refs."
558
+ );
314
559
  }
315
560
  break;
316
561
  }
317
562
  case "context_file_header": {
318
563
  if (!isObject(data.driftMetadata) || !isObject(data.updateMetadata)) {
319
- addError(errors, ctx, "/driftMetadata", ValidationErrorCode.REQUIRED, "Context headers require update and drift metadata.");
564
+ addError(
565
+ errors,
566
+ ctx,
567
+ "/driftMetadata",
568
+ ValidationErrorCode.REQUIRED,
569
+ "Context headers require update and drift metadata."
570
+ );
320
571
  }
321
572
  break;
322
573
  }
323
574
  case "schematic_manifest": {
324
575
  if (!Array.isArray(data.inputs) || data.inputs.length === 0 || !Array.isArray(data.generatedPaths) || data.generatedPaths.length === 0) {
325
- addError(errors, ctx, "/inputs", ValidationErrorCode.REQUIRED, "Schematic manifests require input schema refs and generated path policy.");
576
+ addError(
577
+ errors,
578
+ ctx,
579
+ "/inputs",
580
+ ValidationErrorCode.REQUIRED,
581
+ "Schematic manifests require input schema refs and generated path policy."
582
+ );
326
583
  }
327
584
  break;
328
585
  }
329
586
  case "skill_manifest": {
330
587
  if (!Array.isArray(data.outputArtifactSchemas) || data.outputArtifactSchemas.length === 0 || !Array.isArray(data.forbiddenActions) || data.forbiddenActions.length === 0) {
331
- addError(errors, ctx, "/outputArtifactSchemas", ValidationErrorCode.REQUIRED, "Skill manifests require output schema refs and forbidden action policy.");
588
+ addError(
589
+ errors,
590
+ ctx,
591
+ "/outputArtifactSchemas",
592
+ ValidationErrorCode.REQUIRED,
593
+ "Skill manifests require output schema refs and forbidden action policy."
594
+ );
332
595
  }
333
596
  break;
334
597
  }
@@ -340,37 +603,100 @@ function validateArtifactKind(kind, data, options = {}) {
340
603
  const errors = [];
341
604
  const validator = compiledRegistry.compiled.get(kind);
342
605
  if (!schema || !validator) {
343
- addError(errors, ctx, "", ValidationErrorCode.SCHEMA_INTERNAL_ERROR, `No schema registered for kind ${kind}.`);
606
+ addError(
607
+ errors,
608
+ ctx,
609
+ "",
610
+ ValidationErrorCode.SCHEMA_INTERNAL_ERROR,
611
+ `No schema registered for kind ${kind}.`
612
+ );
344
613
  return { ok: false, errors };
345
614
  }
346
615
  validateVersionAndKind(data, kind, errors, ctx);
347
616
  const schemaOk = validator(data);
348
617
  if (!schemaOk) errors.push(...normalizeAjvErrors(validator.errors, ctx));
349
618
  semanticChecks(kind, data, errors, ctx);
350
- return errors.length === 0 ? { ok: true, artifact: data, kind, schemaId: schema.$id, schemaVersion: SUPPORTED_SCHEMA_VERSION } : { ok: false, errors };
619
+ return errors.length === 0 ? {
620
+ ok: true,
621
+ artifact: data,
622
+ kind,
623
+ schemaId: schema.$id,
624
+ schemaVersion: SUPPORTED_SCHEMA_VERSION
625
+ } : { ok: false, errors };
351
626
  }
352
627
  function validateArtifact(data, options = {}) {
353
628
  if (!isObject(data)) {
354
- const ctx = { artifactPath: options.artifactPath ?? null, artifactKind: null, schemaVersion: null, schemaId: null };
355
- return { ok: false, errors: [makeValidationError({ ...ctx, pointer: "", code: ValidationErrorCode.NOT_OBJECT, message: "Artifact must be a JSON object." })] };
629
+ const ctx = {
630
+ artifactPath: options.artifactPath ?? null,
631
+ artifactKind: null,
632
+ schemaVersion: null,
633
+ schemaId: null
634
+ };
635
+ return {
636
+ ok: false,
637
+ errors: [
638
+ makeValidationError({
639
+ ...ctx,
640
+ pointer: "",
641
+ code: ValidationErrorCode.NOT_OBJECT,
642
+ message: "Artifact must be a JSON object."
643
+ })
644
+ ]
645
+ };
356
646
  }
357
647
  const kind = data.artifactKind;
358
648
  if (!ARTIFACT_KINDS.includes(kind)) {
359
649
  const ctx = createContext(data, options.artifactPath, null);
360
- return { ok: false, errors: [makeValidationError({ ...ctx, pointer: "/artifactKind", code: ValidationErrorCode.ARTIFACT_KIND_MISMATCH, message: "Unknown artifactKind." })] };
650
+ return {
651
+ ok: false,
652
+ errors: [
653
+ makeValidationError({
654
+ ...ctx,
655
+ pointer: "/artifactKind",
656
+ code: ValidationErrorCode.ARTIFACT_KIND_MISMATCH,
657
+ message: "Unknown artifactKind."
658
+ })
659
+ ]
660
+ };
361
661
  }
362
662
  return validateArtifactKind(kind, data, options);
363
663
  }
364
664
  function validateArtifactFile(filePath, options = {}) {
365
665
  const artifactPath = options.artifactPath ?? filePath;
366
666
  if (path.extname(filePath) !== ".json") {
367
- return { ok: false, errors: [makeValidationError({ artifactPath, artifactKind: options.kind ?? null, schemaId: null, schemaVersion: null, pointer: "", code: ValidationErrorCode.CARRIER_NOT_JSON, message: "Canonical artifact carriers must be UTF-8 JSON files; Markdown, YAML, frontmatter, and chat text are not accepted." })] };
667
+ return {
668
+ ok: false,
669
+ errors: [
670
+ makeValidationError({
671
+ artifactPath,
672
+ artifactKind: options.kind ?? null,
673
+ schemaId: null,
674
+ schemaVersion: null,
675
+ pointer: "",
676
+ code: ValidationErrorCode.CARRIER_NOT_JSON,
677
+ message: "Canonical artifact carriers must be UTF-8 JSON files; Markdown, YAML, frontmatter, and chat text are not accepted."
678
+ })
679
+ ]
680
+ };
368
681
  }
369
682
  let parsed;
370
683
  try {
371
684
  parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
372
685
  } catch (error) {
373
- return { ok: false, errors: [makeValidationError({ artifactPath, artifactKind: options.kind ?? null, schemaId: null, schemaVersion: null, pointer: "", code: ValidationErrorCode.JSON_PARSE_ERROR, message: `Invalid JSON artifact: ${error.message}` })] };
686
+ return {
687
+ ok: false,
688
+ errors: [
689
+ makeValidationError({
690
+ artifactPath,
691
+ artifactKind: options.kind ?? null,
692
+ schemaId: null,
693
+ schemaVersion: null,
694
+ pointer: "",
695
+ code: ValidationErrorCode.JSON_PARSE_ERROR,
696
+ message: `Invalid JSON artifact: ${error.message}`
697
+ })
698
+ ]
699
+ };
374
700
  }
375
701
  return options.kind ? validateArtifactKind(options.kind, parsed, { artifactPath }) : validateArtifact(parsed, { artifactPath });
376
702
  }
@@ -5,7 +5,7 @@ import {
5
5
  loadAllSchemas,
6
6
  loadSchema,
7
7
  schemaPathForKind
8
- } from "./chunk-XQLK7EDB.js";
8
+ } from "./chunk-FCLM65RB.js";
9
9
  export {
10
10
  ARTIFACT_KINDS,
11
11
  SCHEMA_FILES,