@dailephd/my-dev-kit-lab 0.4.2 → 0.4.4

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.
Files changed (113) hide show
  1. package/README.md +28 -113
  2. package/benchmarks/contracts/todo-behavior.md +1 -1
  3. package/benchmarks/projects/task-analytics-large-mixed/README.md +2 -0
  4. package/benchmarks/projects/task-workflow-medium-ts/README.md +3 -1
  5. package/dist/src/evaluation/stageContextDeterminism/calculateStageContextDeterminism.js +52 -0
  6. package/dist/src/evaluation/stageContextDeterminism/canonicalizeStageContextRun.js +53 -0
  7. package/dist/src/evaluation/stageContextDeterminism/index.js +2 -0
  8. package/dist/src/evaluation/stageContextDeterminism/types.js +1 -0
  9. package/dist/src/evaluation/stageContextExpectations/index.js +2 -0
  10. package/dist/src/evaluation/stageContextExpectations/producerReadinessExpectationTypes.js +8 -0
  11. package/dist/src/evaluation/stageContextExpectations/readStageContextExpectationFixtureV1.js +50 -0
  12. package/dist/src/evaluation/stageContextExpectations/readTypes.js +1 -0
  13. package/dist/src/evaluation/stageContextExpectations/types.js +1 -0
  14. package/dist/src/evaluation/stageContextExpectations/validation.js +768 -0
  15. package/dist/src/evaluation/stageContextMetrics/calculateAllocationMetrics.js +96 -0
  16. package/dist/src/evaluation/stageContextMetrics/calculateArtifactStateMetrics.js +130 -0
  17. package/dist/src/evaluation/stageContextMetrics/calculateContextSizeMetrics.js +85 -0
  18. package/dist/src/evaluation/stageContextMetrics/calculateCriticalityMetrics.js +112 -0
  19. package/dist/src/evaluation/stageContextMetrics/calculateExpectationMetrics.js +103 -0
  20. package/dist/src/evaluation/stageContextMetrics/calculateOwnerMetrics.js +84 -0
  21. package/dist/src/evaluation/stageContextMetrics/calculateReadinessAgreement.js +152 -0
  22. package/dist/src/evaluation/stageContextMetrics/calculateResponsibilityMappingMetrics.js +36 -0
  23. package/dist/src/evaluation/stageContextMetrics/calculateSupplementalRawAgreement.js +50 -0
  24. package/dist/src/evaluation/stageContextMetrics/calculateTruncationClassification.js +44 -0
  25. package/dist/src/evaluation/stageContextMetrics/collectContextCapsuleEvidence.js +312 -0
  26. package/dist/src/evaluation/stageContextMetrics/collectRetrievalAuditEvidence.js +35 -0
  27. package/dist/src/evaluation/stageContextMetrics/collectWorkflowInstructionEvidence.js +137 -0
  28. package/dist/src/evaluation/stageContextMetrics/evaluateProducerReadinessBridge.js +127 -0
  29. package/dist/src/evaluation/stageContextMetrics/evaluateV043StageContextExecution.js +247 -0
  30. package/dist/src/evaluation/stageContextMetrics/index.js +17 -0
  31. package/dist/src/evaluation/stageContextMetrics/matchStageContextExpectations.js +38 -0
  32. package/dist/src/evaluation/stageContextMetrics/producerReadinessMetricTypes.js +1 -0
  33. package/dist/src/evaluation/stageContextMetrics/targetKeys.js +35 -0
  34. package/dist/src/evaluation/stageContextMetrics/types.js +1 -0
  35. package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +89 -0
  36. package/dist/src/evaluation/stageContextSelectors/contextCapsuleSelectors.js +126 -0
  37. package/dist/src/evaluation/stageContextSelectors/index.js +4 -0
  38. package/dist/src/evaluation/stageContextSelectors/retrievalAuditRecordSelectors.js +54 -0
  39. package/dist/src/evaluation/stageContextSelectors/workflowInstructionPacketSelectors.js +51 -0
  40. package/dist/src/evaluation/targetImmutability/captureTargetSnapshot.js +208 -0
  41. package/dist/src/evaluation/targetImmutability/compareTargetSnapshots.js +56 -0
  42. package/dist/src/evaluation/targetImmutability/index.js +3 -0
  43. package/dist/src/evaluation/targetImmutability/types.js +1 -0
  44. package/dist/src/evaluation/targetImmutability/validateTargetImmutabilityConfig.js +130 -0
  45. package/dist/src/evaluation/upstreamArtifacts/artifactReadTypes.js +1 -0
  46. package/dist/src/evaluation/upstreamArtifacts/index.js +9 -0
  47. package/dist/src/evaluation/upstreamArtifacts/jsonTypes.js +1 -0
  48. package/dist/src/evaluation/upstreamArtifacts/myDevKitClassificationTypesV1.js +1 -0
  49. package/dist/src/evaluation/upstreamArtifacts/myDevKitContextArtifactsV1.js +1 -0
  50. package/dist/src/evaluation/upstreamArtifacts/myDevKitSemanticTypesV1.js +1 -0
  51. package/dist/src/evaluation/upstreamArtifacts/orchestratorContextReadinessResultV1.js +247 -0
  52. package/dist/src/evaluation/upstreamArtifacts/orchestratorWorkflowInstructionPacketV1.js +1 -0
  53. package/dist/src/evaluation/upstreamArtifacts/readImplementationContextPacketV1.js +9 -0
  54. package/dist/src/evaluation/upstreamArtifacts/readImplementationContextRetrievalReportV1.js +9 -0
  55. package/dist/src/evaluation/upstreamArtifacts/readJsonArtifact.js +53 -0
  56. package/dist/src/evaluation/upstreamArtifacts/readMyDevKitContextCapsuleV1.js +9 -0
  57. package/dist/src/evaluation/upstreamArtifacts/readMyDevKitRetrievalAuditRecordV1.js +9 -0
  58. package/dist/src/evaluation/upstreamArtifacts/readOrchestratorWorkflowInstructionPacketV1.js +9 -0
  59. package/dist/src/evaluation/upstreamArtifacts/readSupplementalContextTextFile.js +29 -0
  60. package/dist/src/evaluation/upstreamArtifacts/readTestContextPacketV1.js +9 -0
  61. package/dist/src/evaluation/upstreamArtifacts/readTestContextRetrievalReportV1.js +9 -0
  62. package/dist/src/evaluation/upstreamArtifacts/runtimeValidation.js +131 -0
  63. package/dist/src/evaluation/upstreamArtifacts/schemaVersion.js +32 -0
  64. package/dist/src/evaluation/upstreamArtifacts/supplementalContextTextParser.js +75 -0
  65. package/dist/src/evaluation/upstreamArtifacts/supplementalContextTypes.js +152 -0
  66. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitContextCapsuleV1.js +1208 -0
  67. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +112 -0
  68. package/dist/src/evaluation/upstreamArtifacts/validateOrchestratorWorkflowInstructionPacketV1.js +235 -0
  69. package/dist/src/evaluation/upstreamArtifacts/validateSupplementalContextDocumentV1.js +148 -0
  70. package/dist/src/experiments/plugins/contextStrategyComparison/executeV043StageContextStrategy.js +46 -0
  71. package/dist/src/experiments/plugins/contextStrategyComparison/index.js +9 -0
  72. package/dist/src/experiments/plugins/contextStrategyComparison/loadV043StrategyArtifacts.js +397 -0
  73. package/dist/src/experiments/plugins/contextStrategyComparison/plugin.js +39 -1
  74. package/dist/src/experiments/plugins/contextStrategyComparison/readV043FullWorkflowLibraryFixture.js +162 -0
  75. package/dist/src/experiments/plugins/contextStrategyComparison/resolveV043StrategyInputs.js +43 -0
  76. package/dist/src/experiments/plugins/contextStrategyComparison/resultMapping.js +3 -0
  77. package/dist/src/experiments/plugins/contextStrategyComparison/runV043StageContextStrategyWithAssurance.js +205 -0
  78. package/dist/src/experiments/plugins/contextStrategyComparison/v043FullWorkflowLibraryFixture.js +1 -0
  79. package/dist/src/experiments/plugins/contextStrategyComparison/v043RunAssuranceTypes.js +1 -0
  80. package/dist/src/experiments/plugins/contextStrategyComparison/v043StrategyExecutionTypes.js +1 -0
  81. package/dist/src/experiments/plugins/contextStrategyComparison/v043StrategyIds.js +13 -0
  82. package/dist/src/experiments/plugins/contextStrategyComparison/v043StrategyInputContracts.js +1 -0
  83. package/dist/src/experiments/plugins/contextStrategyComparison/validateV043RunAssuranceConfig.js +59 -0
  84. package/dist/src/experiments/plugins/contextStrategyComparison/validateV043StrategyInput.js +266 -0
  85. package/dist/src/report/experiments/buildContextStrategyComparisonV043Report.js +520 -0
  86. package/dist/src/report/experiments/buildPluginExperimentReport.js +21 -6
  87. package/dist/src/report/experiments/contextStrategyComparisonV043ReportModel.js +1 -0
  88. package/dist/src/report/experiments/index.js +4 -0
  89. package/dist/src/report/experiments/renderContextStrategyComparisonV043Html.js +296 -0
  90. package/dist/src/report/experiments/renderPluginExperimentReportHtml.js +3 -0
  91. package/dist/src/report/experiments/renderPluginExperimentReportText.js +292 -0
  92. package/dist/src/report/experiments/writePluginExperimentReports.js +3 -0
  93. package/dist/src/securityValidation/attackScenarios/scenarios/secretLeakageScenario.js +215 -9
  94. package/docs/METRICS.md +84 -10
  95. package/package.json +2 -2
  96. package/tests/fixtures/full-workflow-library/complete-v1.0.0.json +24 -0
  97. package/tests/fixtures/full-workflow-library/future-minor-v1.1.0-additive.json +25 -0
  98. package/tests/fixtures/stage-context-expectations/complete-v1.0.0.json +230 -0
  99. package/tests/fixtures/stage-context-expectations/future-minor-v1.1.0-additive.json +232 -0
  100. package/tests/fixtures/stage-context-expectations/invalid/malformed-json.txt +1 -0
  101. package/tests/fixtures/stage-context-expectations/invalid/non-object-root.json +1 -0
  102. package/tests/fixtures/stage-context-expectations/minimal-v1.0.0.json +18 -0
  103. package/tests/fixtures/upstream-artifacts/invalid/malformed-json.txt +1 -0
  104. package/tests/fixtures/upstream-artifacts/invalid/non-object-root.json +1 -0
  105. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/complete-v1.0.0.json +504 -0
  106. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/future-minor-v1.1.0-additive.json +955 -0
  107. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/complete-v1.0.0.json +190 -0
  108. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/future-minor-v1.1.0-additive.json +327 -0
  109. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +13 -0
  110. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +7874 -0
  111. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +1076 -0
  112. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/complete-v1.0.0.json +160 -0
  113. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/future-minor-v1.1.0-additive.json +186 -0
@@ -0,0 +1,768 @@
1
+ const SCHEMA_VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+$/;
2
+ const CASE_ID_PATTERN = /^CASE-[A-Z0-9]+(?:-[A-Z0-9]+)*-[0-9]{3}$/;
3
+ const EXPECTATION_ID_PATTERN = /^(REQ|ALLOW|FORBID)-[A-Z0-9]+(?:-[A-Z0-9]+)*-[0-9]{3}$/;
4
+ const INCLUSION_VALUES = ["required", "allowed", "forbidden"];
5
+ const SOURCE_ARTIFACT_VALUES = [
6
+ "context-capsule",
7
+ "retrieval-audit-record",
8
+ "workflow-instruction-packet",
9
+ "full-workflow-library"
10
+ ];
11
+ const CATEGORY_VALUES = [
12
+ "file",
13
+ "symbol",
14
+ "source-range",
15
+ "contract",
16
+ "validator",
17
+ "constant",
18
+ "error",
19
+ "schema-or-serializer",
20
+ "production-responsibility",
21
+ "test-file",
22
+ "fixture",
23
+ "factory",
24
+ "mock",
25
+ "setup-file",
26
+ "test-configuration",
27
+ "package-script",
28
+ "test-command",
29
+ "workflow",
30
+ "stage",
31
+ "command",
32
+ "rule",
33
+ "report-contract",
34
+ "provenance"
35
+ ];
36
+ const PATH_CATEGORIES = [
37
+ "file",
38
+ "test-file",
39
+ "fixture",
40
+ "factory",
41
+ "mock",
42
+ "setup-file",
43
+ "test-configuration"
44
+ ];
45
+ const SYMBOL_CATEGORIES = [
46
+ "symbol",
47
+ "contract",
48
+ "validator",
49
+ "constant",
50
+ "error",
51
+ "schema-or-serializer"
52
+ ];
53
+ const WORKFLOW_STABLE_ID_CATEGORIES = [
54
+ "workflow",
55
+ "stage",
56
+ "command",
57
+ "rule",
58
+ "report-contract"
59
+ ];
60
+ const INCLUSION_PREFIX = {
61
+ required: "REQ-",
62
+ allowed: "ALLOW-",
63
+ forbidden: "FORBID-"
64
+ };
65
+ const CONTEXT_ADEQUACY_STATUS_VALUES = [
66
+ "context sufficient for implementation",
67
+ "context sufficient with listed assumptions",
68
+ "context insufficient and more retrieval required",
69
+ "context conflict found and user or upstream stage decision required"
70
+ ];
71
+ const FRESHNESS_STATE_VALUES = ["fresh", "stale", "unknown"];
72
+ const PACKET_ADEQUACY_STATUS_VALUES = ["adequate", "inadequate"];
73
+ function failure(sourcePath, code, message, extra) {
74
+ return { ok: false, sourcePath, code, message, ...extra };
75
+ }
76
+ function isPlainObject(value) {
77
+ return typeof value === "object" && value !== null && !Array.isArray(value);
78
+ }
79
+ function isStringArray(value) {
80
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string");
81
+ }
82
+ function isNonNegativeInteger(value) {
83
+ return typeof value === "number" && Number.isInteger(value) && value >= 0;
84
+ }
85
+ function isPositiveInteger(value) {
86
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
87
+ }
88
+ function hasDuplicates(values) {
89
+ return new Set(values).size !== values.length;
90
+ }
91
+ function requireNonEmptyString(root, key, fieldPath, sourcePath) {
92
+ const value = root[key];
93
+ if (value === undefined) {
94
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${fieldPath} is required.`, { fieldPath });
95
+ }
96
+ if (typeof value !== "string") {
97
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath} must be a string.`, { fieldPath });
98
+ }
99
+ if (value.trim().length === 0) {
100
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath} must be a nonempty string.`, { fieldPath });
101
+ }
102
+ return null;
103
+ }
104
+ export function validateStageContextExpectationFixtureV1(value, sourcePath) {
105
+ const root = value;
106
+ if (root.schemaVersion === undefined) {
107
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", "schemaVersion is required.", { fieldPath: "schemaVersion" });
108
+ }
109
+ if (typeof root.schemaVersion !== "string") {
110
+ return failure(sourcePath, "INVALID_FIELD_TYPE", "schemaVersion must be a string.", { fieldPath: "schemaVersion" });
111
+ }
112
+ if (!SCHEMA_VERSION_PATTERN.test(root.schemaVersion)) {
113
+ return failure(sourcePath, "INVALID_SCHEMA_VERSION", `schemaVersion "${root.schemaVersion}" does not match x.y.z.`, {
114
+ fieldPath: "schemaVersion",
115
+ actual: root.schemaVersion
116
+ });
117
+ }
118
+ const schemaVersionValue = root.schemaVersion;
119
+ const schemaMajor = Number(schemaVersionValue.split(".")[0]);
120
+ if (schemaMajor !== 1) {
121
+ return failure(sourcePath, "UNSUPPORTED_SCHEMA_MAJOR", `schemaVersion major "${schemaMajor}" is not supported.`, {
122
+ fieldPath: "schemaVersion",
123
+ actual: schemaVersionValue
124
+ });
125
+ }
126
+ if (root.caseId === undefined) {
127
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", "caseId is required.", { fieldPath: "caseId" });
128
+ }
129
+ if (typeof root.caseId !== "string") {
130
+ return failure(sourcePath, "INVALID_FIELD_TYPE", "caseId must be a string.", { fieldPath: "caseId" });
131
+ }
132
+ if (!CASE_ID_PATTERN.test(root.caseId)) {
133
+ return failure(sourcePath, "INVALID_CASE_ID", `caseId "${root.caseId}" does not match the required pattern.`, {
134
+ fieldPath: "caseId",
135
+ actual: root.caseId
136
+ });
137
+ }
138
+ const titleFailure = requireNonEmptyString(root, "title", "title", sourcePath);
139
+ if (titleFailure)
140
+ return titleFailure;
141
+ const descriptionFailure = requireNonEmptyString(root, "description", "description", sourcePath);
142
+ if (descriptionFailure)
143
+ return descriptionFailure;
144
+ if (root.expectedEvidence === undefined) {
145
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", "expectedEvidence is required.", { fieldPath: "expectedEvidence" });
146
+ }
147
+ if (!Array.isArray(root.expectedEvidence)) {
148
+ return failure(sourcePath, "INVALID_FIELD_TYPE", "expectedEvidence must be an array.", { fieldPath: "expectedEvidence" });
149
+ }
150
+ if (root.expectedEvidence.length === 0) {
151
+ return failure(sourcePath, "EMPTY_EXPECTATION_SET", "expectedEvidence must contain at least one item.", {
152
+ fieldPath: "expectedEvidence"
153
+ });
154
+ }
155
+ if (root.expectedStates === undefined) {
156
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", "expectedStates is required.", { fieldPath: "expectedStates" });
157
+ }
158
+ if (!isPlainObject(root.expectedStates)) {
159
+ return failure(sourcePath, "INVALID_FIELD_TYPE", "expectedStates must be an object.", { fieldPath: "expectedStates" });
160
+ }
161
+ if (root.warnings === undefined) {
162
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", "warnings is required.", { fieldPath: "warnings" });
163
+ }
164
+ if (!isStringArray(root.warnings)) {
165
+ return failure(sourcePath, "INVALID_FIELD_TYPE", "warnings must be an array of strings.", { fieldPath: "warnings" });
166
+ }
167
+ const items = root.expectedEvidence;
168
+ for (let index = 0; index < items.length; index += 1) {
169
+ const itemFailure = validateExpectationItem(items[index], `expectedEvidence[${index}]`, sourcePath);
170
+ if (itemFailure)
171
+ return itemFailure;
172
+ }
173
+ const typedItems = items;
174
+ const seenIds = new Set();
175
+ for (let index = 0; index < typedItems.length; index += 1) {
176
+ const id = typedItems[index].expectationId;
177
+ if (seenIds.has(id)) {
178
+ return failure(sourcePath, "DUPLICATE_EXPECTATION_ID", `expectationId "${id}" is duplicated.`, {
179
+ fieldPath: `expectedEvidence[${index}].expectationId`,
180
+ actual: id
181
+ });
182
+ }
183
+ seenIds.add(id);
184
+ }
185
+ const seenTargets = new Map();
186
+ for (let index = 0; index < typedItems.length; index += 1) {
187
+ const item = typedItems[index];
188
+ const targetKey = buildTargetKey(item);
189
+ const inclusion = item.inclusion;
190
+ const existingInclusion = seenTargets.get(targetKey);
191
+ if (existingInclusion !== undefined) {
192
+ if (existingInclusion === inclusion) {
193
+ return failure(sourcePath, "DUPLICATE_EXPECTATION_TARGET", `Target "${targetKey}" is duplicated with the same inclusion.`, { fieldPath: `expectedEvidence[${index}]`, actual: targetKey });
194
+ }
195
+ return failure(sourcePath, "CONFLICTING_EXPECTATION_INCLUSION", `Target "${targetKey}" has conflicting inclusion values.`, { fieldPath: `expectedEvidence[${index}]`, actual: targetKey });
196
+ }
197
+ seenTargets.set(targetKey, inclusion);
198
+ }
199
+ const statesFailure = validateExpectedStates(root.expectedStates, sourcePath);
200
+ if (statesFailure)
201
+ return statesFailure;
202
+ if (root.producerReadinessExpectations !== undefined) {
203
+ const producerReadinessFailure = validateProducerReadinessExpectations(root.producerReadinessExpectations, sourcePath);
204
+ if (producerReadinessFailure)
205
+ return producerReadinessFailure;
206
+ }
207
+ return {
208
+ ok: true,
209
+ sourcePath,
210
+ schemaVersion: schemaVersionValue,
211
+ schemaMajor: 1,
212
+ fixture: value,
213
+ rawFixture: value
214
+ };
215
+ }
216
+ function validateExpectationItem(itemValue, itemPath, sourcePath) {
217
+ if (!isPlainObject(itemValue)) {
218
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath} must be an object.`, { fieldPath: itemPath });
219
+ }
220
+ const item = itemValue;
221
+ if (item.expectationId === undefined) {
222
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.expectationId is required.`, {
223
+ fieldPath: `${itemPath}.expectationId`
224
+ });
225
+ }
226
+ if (typeof item.expectationId !== "string") {
227
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectationId must be a string.`, {
228
+ fieldPath: `${itemPath}.expectationId`
229
+ });
230
+ }
231
+ if (item.inclusion === undefined) {
232
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.inclusion is required.`, {
233
+ fieldPath: `${itemPath}.inclusion`
234
+ });
235
+ }
236
+ if (typeof item.inclusion !== "string") {
237
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.inclusion must be a string.`, {
238
+ fieldPath: `${itemPath}.inclusion`
239
+ });
240
+ }
241
+ if (!INCLUSION_VALUES.includes(item.inclusion)) {
242
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.inclusion "${item.inclusion}" is not valid.`, {
243
+ fieldPath: `${itemPath}.inclusion`,
244
+ actual: item.inclusion
245
+ });
246
+ }
247
+ if (item.sourceArtifact === undefined) {
248
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.sourceArtifact is required.`, {
249
+ fieldPath: `${itemPath}.sourceArtifact`
250
+ });
251
+ }
252
+ if (typeof item.sourceArtifact !== "string") {
253
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.sourceArtifact must be a string.`, {
254
+ fieldPath: `${itemPath}.sourceArtifact`
255
+ });
256
+ }
257
+ if (!SOURCE_ARTIFACT_VALUES.includes(item.sourceArtifact)) {
258
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.sourceArtifact "${item.sourceArtifact}" is not valid.`, {
259
+ fieldPath: `${itemPath}.sourceArtifact`,
260
+ actual: item.sourceArtifact
261
+ });
262
+ }
263
+ if (item.category === undefined) {
264
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.category is required.`, {
265
+ fieldPath: `${itemPath}.category`
266
+ });
267
+ }
268
+ if (typeof item.category !== "string") {
269
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.category must be a string.`, {
270
+ fieldPath: `${itemPath}.category`
271
+ });
272
+ }
273
+ if (!CATEGORY_VALUES.includes(item.category)) {
274
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.category "${item.category}" is not valid.`, {
275
+ fieldPath: `${itemPath}.category`,
276
+ actual: item.category
277
+ });
278
+ }
279
+ if (item.match === undefined) {
280
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.match is required.`, {
281
+ fieldPath: `${itemPath}.match`
282
+ });
283
+ }
284
+ if (!isPlainObject(item.match)) {
285
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.match must be an object.`, {
286
+ fieldPath: `${itemPath}.match`
287
+ });
288
+ }
289
+ if (item.notes === undefined) {
290
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.notes is required.`, {
291
+ fieldPath: `${itemPath}.notes`
292
+ });
293
+ }
294
+ if (!isStringArray(item.notes)) {
295
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.notes must be an array of strings.`, {
296
+ fieldPath: `${itemPath}.notes`
297
+ });
298
+ }
299
+ const expectationId = item.expectationId;
300
+ if (!EXPECTATION_ID_PATTERN.test(expectationId)) {
301
+ return failure(sourcePath, "INVALID_EXPECTATION_ID", `${itemPath}.expectationId "${expectationId}" does not match the required pattern.`, { fieldPath: `${itemPath}.expectationId`, actual: expectationId });
302
+ }
303
+ const inclusion = item.inclusion;
304
+ const requiredPrefix = INCLUSION_PREFIX[inclusion];
305
+ if (!expectationId.startsWith(requiredPrefix)) {
306
+ return failure(sourcePath, "EXPECTATION_ID_PREFIX_MISMATCH", `${itemPath}.expectationId "${expectationId}" does not have the "${requiredPrefix}" prefix required by inclusion "${inclusion}".`, { fieldPath: `${itemPath}.expectationId`, actual: expectationId });
307
+ }
308
+ const category = item.category;
309
+ const sourceArtifact = item.sourceArtifact;
310
+ const pairFailure = validateCategorySourcePair(category, sourceArtifact, itemPath, sourcePath);
311
+ if (pairFailure)
312
+ return pairFailure;
313
+ const matchFailure = validateMatchFields(category, item.match, itemPath, sourcePath);
314
+ if (matchFailure)
315
+ return matchFailure;
316
+ return null;
317
+ }
318
+ function allowedSourceArtifactsForCategory(category) {
319
+ if (PATH_CATEGORIES.includes(category))
320
+ return ["context-capsule"];
321
+ if (SYMBOL_CATEGORIES.includes(category))
322
+ return ["context-capsule"];
323
+ if (category === "source-range")
324
+ return ["context-capsule"];
325
+ if (category === "production-responsibility")
326
+ return ["context-capsule", "retrieval-audit-record"];
327
+ if (category === "package-script")
328
+ return ["context-capsule"];
329
+ if (category === "test-command")
330
+ return ["context-capsule"];
331
+ if (WORKFLOW_STABLE_ID_CATEGORIES.includes(category)) {
332
+ return ["workflow-instruction-packet", "full-workflow-library"];
333
+ }
334
+ return SOURCE_ARTIFACT_VALUES;
335
+ }
336
+ function validateCategorySourcePair(category, sourceArtifact, itemPath, sourcePath) {
337
+ const allowed = allowedSourceArtifactsForCategory(category);
338
+ if (!allowed.includes(sourceArtifact)) {
339
+ return failure(sourcePath, "INVALID_CATEGORY_SOURCE_PAIR", `${itemPath} category "${category}" is not valid for sourceArtifact "${sourceArtifact}".`, { fieldPath: `${itemPath}.sourceArtifact`, actual: sourceArtifact });
340
+ }
341
+ return null;
342
+ }
343
+ function requireNonEmptyMatchString(match, key, itemPath, sourcePath) {
344
+ const value = match[key];
345
+ if (value === undefined) {
346
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.match.${key} is required.`, {
347
+ fieldPath: `${itemPath}.match.${key}`
348
+ });
349
+ }
350
+ if (typeof value !== "string") {
351
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.match.${key} must be a string.`, {
352
+ fieldPath: `${itemPath}.match.${key}`
353
+ });
354
+ }
355
+ if (value.trim().length === 0) {
356
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.match.${key} must be a nonempty string.`, {
357
+ fieldPath: `${itemPath}.match.${key}`
358
+ });
359
+ }
360
+ return null;
361
+ }
362
+ function validateMatchFields(category, match, itemPath, sourcePath) {
363
+ if (PATH_CATEGORIES.includes(category)) {
364
+ return requireNonEmptyMatchString(match, "path", itemPath, sourcePath);
365
+ }
366
+ if (SYMBOL_CATEGORIES.includes(category)) {
367
+ return requireNonEmptyMatchString(match, "symbolId", itemPath, sourcePath);
368
+ }
369
+ if (category === "source-range") {
370
+ const filePathFailure = requireNonEmptyMatchString(match, "filePath", itemPath, sourcePath);
371
+ if (filePathFailure)
372
+ return filePathFailure;
373
+ if (match.startLine === undefined) {
374
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.match.startLine is required.`, {
375
+ fieldPath: `${itemPath}.match.startLine`
376
+ });
377
+ }
378
+ if (!isPositiveInteger(match.startLine)) {
379
+ return failure(sourcePath, "INVALID_SOURCE_RANGE", `${itemPath}.match.startLine must be a positive integer.`, {
380
+ fieldPath: `${itemPath}.match.startLine`,
381
+ actual: match.startLine
382
+ });
383
+ }
384
+ if (match.endLine === undefined) {
385
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${itemPath}.match.endLine is required.`, {
386
+ fieldPath: `${itemPath}.match.endLine`
387
+ });
388
+ }
389
+ if (!isPositiveInteger(match.endLine)) {
390
+ return failure(sourcePath, "INVALID_SOURCE_RANGE", `${itemPath}.match.endLine must be a positive integer.`, {
391
+ fieldPath: `${itemPath}.match.endLine`,
392
+ actual: match.endLine
393
+ });
394
+ }
395
+ if (match.endLine < match.startLine) {
396
+ return failure(sourcePath, "INVALID_SOURCE_RANGE", `${itemPath}.match.endLine must be >= startLine.`, {
397
+ fieldPath: `${itemPath}.match.endLine`,
398
+ actual: match.endLine
399
+ });
400
+ }
401
+ return null;
402
+ }
403
+ if (category === "production-responsibility") {
404
+ return requireNonEmptyMatchString(match, "responsibilityId", itemPath, sourcePath);
405
+ }
406
+ if (category === "package-script") {
407
+ return requireNonEmptyMatchString(match, "name", itemPath, sourcePath);
408
+ }
409
+ if (category === "test-command") {
410
+ return requireNonEmptyMatchString(match, "commandText", itemPath, sourcePath);
411
+ }
412
+ if (WORKFLOW_STABLE_ID_CATEGORIES.includes(category)) {
413
+ return requireNonEmptyMatchString(match, "id", itemPath, sourcePath);
414
+ }
415
+ return requireNonEmptyMatchString(match, "evidenceId", itemPath, sourcePath);
416
+ }
417
+ function buildTargetKey(item) {
418
+ const category = item.category;
419
+ const sourceArtifact = item.sourceArtifact;
420
+ const match = item.match;
421
+ if (PATH_CATEGORIES.includes(category)) {
422
+ return `${sourceArtifact}|${category}|path:${match.path}`;
423
+ }
424
+ if (SYMBOL_CATEGORIES.includes(category)) {
425
+ return `${sourceArtifact}|${category}|symbolId:${match.symbolId}`;
426
+ }
427
+ if (category === "source-range") {
428
+ return `context-capsule|source-range|filePath:${match.filePath}|startLine:${match.startLine}|endLine:${match.endLine}`;
429
+ }
430
+ if (category === "production-responsibility") {
431
+ return `${sourceArtifact}|production-responsibility|responsibilityId:${match.responsibilityId}`;
432
+ }
433
+ if (category === "package-script") {
434
+ return `context-capsule|package-script|name:${match.name}`;
435
+ }
436
+ if (category === "test-command") {
437
+ return `context-capsule|test-command|commandText:${match.commandText}`;
438
+ }
439
+ if (WORKFLOW_STABLE_ID_CATEGORIES.includes(category)) {
440
+ return `${sourceArtifact}|${category}|id:${match.id}`;
441
+ }
442
+ return `${sourceArtifact}|provenance|evidenceId:${match.evidenceId}`;
443
+ }
444
+ function validateMyDevKitContextArtifactState(value, fieldPath, sourcePath) {
445
+ if (value === undefined)
446
+ return null;
447
+ if (!isPlainObject(value)) {
448
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath} must be an object.`, { fieldPath });
449
+ }
450
+ if (value.contextAdequacyStatus !== undefined &&
451
+ !CONTEXT_ADEQUACY_STATUS_VALUES.includes(value.contextAdequacyStatus)) {
452
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${fieldPath}.contextAdequacyStatus is not valid.`, {
453
+ fieldPath: `${fieldPath}.contextAdequacyStatus`,
454
+ actual: value.contextAdequacyStatus
455
+ });
456
+ }
457
+ if (value.roleAdequacyStatus !== undefined &&
458
+ !CONTEXT_ADEQUACY_STATUS_VALUES.includes(value.roleAdequacyStatus)) {
459
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${fieldPath}.roleAdequacyStatus is not valid.`, {
460
+ fieldPath: `${fieldPath}.roleAdequacyStatus`,
461
+ actual: value.roleAdequacyStatus
462
+ });
463
+ }
464
+ if (value.freshnessState !== undefined && !FRESHNESS_STATE_VALUES.includes(value.freshnessState)) {
465
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${fieldPath}.freshnessState is not valid.`, {
466
+ fieldPath: `${fieldPath}.freshnessState`,
467
+ actual: value.freshnessState
468
+ });
469
+ }
470
+ if (value.truncated !== undefined && typeof value.truncated !== "boolean") {
471
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.truncated must be a boolean.`, {
472
+ fieldPath: `${fieldPath}.truncated`
473
+ });
474
+ }
475
+ if (value.fullFileFallbackUsed !== undefined && !isNonNegativeInteger(value.fullFileFallbackUsed)) {
476
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.fullFileFallbackUsed must be a nonnegative integer.`, {
477
+ fieldPath: `${fieldPath}.fullFileFallbackUsed`,
478
+ actual: value.fullFileFallbackUsed
479
+ });
480
+ }
481
+ if (value.unresolvedItemIds !== undefined) {
482
+ if (!isStringArray(value.unresolvedItemIds) || value.unresolvedItemIds.some((entry) => entry.length === 0)) {
483
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.unresolvedItemIds must be an array of nonempty strings.`, {
484
+ fieldPath: `${fieldPath}.unresolvedItemIds`
485
+ });
486
+ }
487
+ if (hasDuplicates(value.unresolvedItemIds)) {
488
+ return failure(sourcePath, "DUPLICATE_EXPECTED_VALUE", `${fieldPath}.unresolvedItemIds contains duplicates.`, {
489
+ fieldPath: `${fieldPath}.unresolvedItemIds`
490
+ });
491
+ }
492
+ }
493
+ if (value.warningCount !== undefined && !isNonNegativeInteger(value.warningCount)) {
494
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.warningCount must be a nonnegative integer.`, {
495
+ fieldPath: `${fieldPath}.warningCount`,
496
+ actual: value.warningCount
497
+ });
498
+ }
499
+ return null;
500
+ }
501
+ function validateWorkflowPacketState(value, sourcePath) {
502
+ const fieldPath = "expectedStates.workflowInstructionPacket";
503
+ if (value === undefined)
504
+ return null;
505
+ if (!isPlainObject(value)) {
506
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath} must be an object.`, { fieldPath });
507
+ }
508
+ if (value.adequacyStatus !== undefined && !PACKET_ADEQUACY_STATUS_VALUES.includes(value.adequacyStatus)) {
509
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${fieldPath}.adequacyStatus is not valid.`, {
510
+ fieldPath: `${fieldPath}.adequacyStatus`,
511
+ actual: value.adequacyStatus
512
+ });
513
+ }
514
+ if (value.truncated !== undefined && typeof value.truncated !== "boolean") {
515
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.truncated must be a boolean.`, {
516
+ fieldPath: `${fieldPath}.truncated`
517
+ });
518
+ }
519
+ if (value.unresolvedReferences !== undefined) {
520
+ if (!isStringArray(value.unresolvedReferences)) {
521
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.unresolvedReferences must be an array of strings.`, {
522
+ fieldPath: `${fieldPath}.unresolvedReferences`
523
+ });
524
+ }
525
+ if (hasDuplicates(value.unresolvedReferences)) {
526
+ return failure(sourcePath, "DUPLICATE_EXPECTED_VALUE", `${fieldPath}.unresolvedReferences contains duplicates.`, {
527
+ fieldPath: `${fieldPath}.unresolvedReferences`
528
+ });
529
+ }
530
+ }
531
+ if (value.warningCount !== undefined && !isNonNegativeInteger(value.warningCount)) {
532
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.warningCount must be a nonnegative integer.`, {
533
+ fieldPath: `${fieldPath}.warningCount`,
534
+ actual: value.warningCount
535
+ });
536
+ }
537
+ return null;
538
+ }
539
+ function validateTargetImmutabilityState(value, sourcePath) {
540
+ const fieldPath = "expectedStates.targetImmutability";
541
+ if (value === undefined)
542
+ return null;
543
+ if (!isPlainObject(value)) {
544
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath} must be an object.`, { fieldPath });
545
+ }
546
+ if (value.newMutationCount === undefined) {
547
+ return failure(sourcePath, "MISSING_REQUIRED_FIELD", `${fieldPath}.newMutationCount is required.`, {
548
+ fieldPath: `${fieldPath}.newMutationCount`
549
+ });
550
+ }
551
+ if (!isNonNegativeInteger(value.newMutationCount)) {
552
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.newMutationCount must be a nonnegative integer.`, {
553
+ fieldPath: `${fieldPath}.newMutationCount`,
554
+ actual: value.newMutationCount
555
+ });
556
+ }
557
+ return null;
558
+ }
559
+ function validateExpectedStates(statesValue, sourcePath) {
560
+ const contextCapsuleFailure = validateMyDevKitContextArtifactState(statesValue.contextCapsule, "expectedStates.contextCapsule", sourcePath);
561
+ if (contextCapsuleFailure)
562
+ return contextCapsuleFailure;
563
+ const auditFailure = validateMyDevKitContextArtifactState(statesValue.retrievalAuditRecord, "expectedStates.retrievalAuditRecord", sourcePath);
564
+ if (auditFailure)
565
+ return auditFailure;
566
+ const packetFailure = validateWorkflowPacketState(statesValue.workflowInstructionPacket, sourcePath);
567
+ if (packetFailure)
568
+ return packetFailure;
569
+ const immutabilityFailure = validateTargetImmutabilityState(statesValue.targetImmutability, sourcePath);
570
+ if (immutabilityFailure)
571
+ return immutabilityFailure;
572
+ return null;
573
+ }
574
+ // v0.4.4 Batch 2: additive, optional producer/readiness expectation validation. Structural
575
+ // classification only, mirroring the existing expectation-item validation conventions.
576
+ const OWNER_INCLUSION_VALUES = ["required", "allowed", "forbidden"];
577
+ const READINESS_KIND_VALUES = ["implementation", "test"];
578
+ const READINESS_DECISION_VALUES = ["not-required", "ready", "refresh-required"];
579
+ const CRITICALITY_VALUES = ["critical", "noncritical"];
580
+ const PRODUCER_READINESS_SOURCE_ARTIFACT_VALUES = ["context-capsule", "retrieval-audit-record"];
581
+ function requireNonEmptyExpectationId(item, itemPath, sourcePath) {
582
+ return requireNonEmptyString(item, "expectationId", `${itemPath}.expectationId`, sourcePath);
583
+ }
584
+ function validateOwnerExpectation(itemValue, itemPath, sourcePath) {
585
+ if (!isPlainObject(itemValue)) {
586
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath} must be an object.`, { fieldPath: itemPath });
587
+ }
588
+ const idFailure = requireNonEmptyExpectationId(itemValue, itemPath, sourcePath);
589
+ if (idFailure)
590
+ return idFailure;
591
+ if (!OWNER_INCLUSION_VALUES.includes(itemValue.inclusion)) {
592
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.inclusion is not valid.`, {
593
+ fieldPath: `${itemPath}.inclusion`,
594
+ actual: itemValue.inclusion
595
+ });
596
+ }
597
+ if (!PRODUCER_READINESS_SOURCE_ARTIFACT_VALUES.includes(itemValue.sourceArtifact)) {
598
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.sourceArtifact is not valid.`, {
599
+ fieldPath: `${itemPath}.sourceArtifact`,
600
+ actual: itemValue.sourceArtifact
601
+ });
602
+ }
603
+ const ownerIdFailure = requireNonEmptyString(itemValue, "ownerId", `${itemPath}.ownerId`, sourcePath);
604
+ if (ownerIdFailure)
605
+ return ownerIdFailure;
606
+ if (itemValue.notes === undefined || !isStringArray(itemValue.notes)) {
607
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.notes must be an array of strings.`, {
608
+ fieldPath: `${itemPath}.notes`
609
+ });
610
+ }
611
+ return null;
612
+ }
613
+ function validateAllocationExpectation(itemValue, itemPath, sourcePath) {
614
+ if (!isPlainObject(itemValue)) {
615
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath} must be an object.`, { fieldPath: itemPath });
616
+ }
617
+ const idFailure = requireNonEmptyExpectationId(itemValue, itemPath, sourcePath);
618
+ if (idFailure)
619
+ return idFailure;
620
+ const groupIdFailure = requireNonEmptyString(itemValue, "groupId", `${itemPath}.groupId`, sourcePath);
621
+ if (groupIdFailure)
622
+ return groupIdFailure;
623
+ if (itemValue.expectedCapacity !== undefined && itemValue.expectedCapacity !== null && !isNonNegativeInteger(itemValue.expectedCapacity)) {
624
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedCapacity must be a nonnegative integer or null.`, {
625
+ fieldPath: `${itemPath}.expectedCapacity`
626
+ });
627
+ }
628
+ if (itemValue.expectedUsedReservation !== undefined &&
629
+ itemValue.expectedUsedReservation !== null &&
630
+ !isNonNegativeInteger(itemValue.expectedUsedReservation)) {
631
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedUsedReservation must be a nonnegative integer or null.`, {
632
+ fieldPath: `${itemPath}.expectedUsedReservation`
633
+ });
634
+ }
635
+ if (itemValue.expectedRequiredEvidenceIds !== undefined && !isStringArray(itemValue.expectedRequiredEvidenceIds)) {
636
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedRequiredEvidenceIds must be an array of strings.`, {
637
+ fieldPath: `${itemPath}.expectedRequiredEvidenceIds`
638
+ });
639
+ }
640
+ if (itemValue.expectedOmitted !== undefined && typeof itemValue.expectedOmitted !== "boolean") {
641
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedOmitted must be a boolean.`, {
642
+ fieldPath: `${itemPath}.expectedOmitted`
643
+ });
644
+ }
645
+ if (itemValue.notes === undefined || !isStringArray(itemValue.notes)) {
646
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.notes must be an array of strings.`, {
647
+ fieldPath: `${itemPath}.notes`
648
+ });
649
+ }
650
+ return null;
651
+ }
652
+ function validateReadinessExpectation(itemValue, itemPath, sourcePath) {
653
+ if (!isPlainObject(itemValue)) {
654
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath} must be an object.`, { fieldPath: itemPath });
655
+ }
656
+ const idFailure = requireNonEmptyExpectationId(itemValue, itemPath, sourcePath);
657
+ if (idFailure)
658
+ return idFailure;
659
+ if (!READINESS_KIND_VALUES.includes(itemValue.kind)) {
660
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.kind is not valid.`, {
661
+ fieldPath: `${itemPath}.kind`,
662
+ actual: itemValue.kind
663
+ });
664
+ }
665
+ if (itemValue.allowedDecisions !== undefined) {
666
+ if (!isStringArray(itemValue.allowedDecisions) || itemValue.allowedDecisions.some((d) => !READINESS_DECISION_VALUES.includes(d))) {
667
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.allowedDecisions contains an invalid decision value.`, {
668
+ fieldPath: `${itemPath}.allowedDecisions`
669
+ });
670
+ }
671
+ }
672
+ if (itemValue.expectedClassification !== undefined && typeof itemValue.expectedClassification !== "string") {
673
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedClassification must be a string.`, {
674
+ fieldPath: `${itemPath}.expectedClassification`
675
+ });
676
+ }
677
+ if (itemValue.expectedIssueCodes !== undefined && !isStringArray(itemValue.expectedIssueCodes)) {
678
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedIssueCodes must be an array of strings.`, {
679
+ fieldPath: `${itemPath}.expectedIssueCodes`
680
+ });
681
+ }
682
+ if (itemValue.expectedPrimaryIssueCode !== undefined && typeof itemValue.expectedPrimaryIssueCode !== "string") {
683
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.expectedPrimaryIssueCode must be a string.`, {
684
+ fieldPath: `${itemPath}.expectedPrimaryIssueCode`
685
+ });
686
+ }
687
+ if (itemValue.notApplicable !== undefined && typeof itemValue.notApplicable !== "boolean") {
688
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.notApplicable must be a boolean.`, {
689
+ fieldPath: `${itemPath}.notApplicable`
690
+ });
691
+ }
692
+ if (itemValue.notes === undefined || !isStringArray(itemValue.notes)) {
693
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.notes must be an array of strings.`, {
694
+ fieldPath: `${itemPath}.notes`
695
+ });
696
+ }
697
+ return null;
698
+ }
699
+ function validateCriticalityExpectation(itemValue, itemPath, sourcePath) {
700
+ if (!isPlainObject(itemValue)) {
701
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath} must be an object.`, { fieldPath: itemPath });
702
+ }
703
+ const idFailure = requireNonEmptyExpectationId(itemValue, itemPath, sourcePath);
704
+ if (idFailure)
705
+ return idFailure;
706
+ const responsibilityIdFailure = requireNonEmptyString(itemValue, "responsibilityId", `${itemPath}.responsibilityId`, sourcePath);
707
+ if (responsibilityIdFailure)
708
+ return responsibilityIdFailure;
709
+ if (!CRITICALITY_VALUES.includes(itemValue.expectedCriticality)) {
710
+ return failure(sourcePath, "INVALID_LITERAL_VALUE", `${itemPath}.expectedCriticality is not valid.`, {
711
+ fieldPath: `${itemPath}.expectedCriticality`,
712
+ actual: itemValue.expectedCriticality
713
+ });
714
+ }
715
+ if (typeof itemValue.applicable !== "boolean") {
716
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.applicable must be a boolean.`, {
717
+ fieldPath: `${itemPath}.applicable`
718
+ });
719
+ }
720
+ if (typeof itemValue.requiresFullMapping !== "boolean") {
721
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.requiresFullMapping must be a boolean.`, {
722
+ fieldPath: `${itemPath}.requiresFullMapping`
723
+ });
724
+ }
725
+ if (itemValue.notes === undefined || !isStringArray(itemValue.notes)) {
726
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${itemPath}.notes must be an array of strings.`, {
727
+ fieldPath: `${itemPath}.notes`
728
+ });
729
+ }
730
+ return null;
731
+ }
732
+ function validateProducerReadinessExpectations(value, sourcePath) {
733
+ const fieldPath = "producerReadinessExpectations";
734
+ if (!isPlainObject(value)) {
735
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath} must be an object.`, { fieldPath });
736
+ }
737
+ const lists = [
738
+ ["ownerExpectations", value.ownerExpectations, validateOwnerExpectation],
739
+ ["allocationExpectations", value.allocationExpectations, validateAllocationExpectation],
740
+ ["readinessExpectations", value.readinessExpectations, validateReadinessExpectation],
741
+ ["criticalityExpectations", value.criticalityExpectations, validateCriticalityExpectation]
742
+ ];
743
+ const seenIds = new Set();
744
+ for (const [key, listValue, validateItem] of lists) {
745
+ if (listValue === undefined)
746
+ continue;
747
+ if (!Array.isArray(listValue)) {
748
+ return failure(sourcePath, "INVALID_FIELD_TYPE", `${fieldPath}.${key} must be an array.`, {
749
+ fieldPath: `${fieldPath}.${key}`
750
+ });
751
+ }
752
+ for (let index = 0; index < listValue.length; index += 1) {
753
+ const itemPath = `${fieldPath}.${key}[${index}]`;
754
+ const itemFailure = validateItem(listValue[index], itemPath, sourcePath);
755
+ if (itemFailure)
756
+ return itemFailure;
757
+ const id = listValue[index].expectationId;
758
+ if (seenIds.has(id)) {
759
+ return failure(sourcePath, "DUPLICATE_PRODUCER_READINESS_EXPECTATION_ID", `${itemPath}.expectationId "${id}" is duplicated.`, {
760
+ fieldPath: `${itemPath}.expectationId`,
761
+ actual: id
762
+ });
763
+ }
764
+ seenIds.add(id);
765
+ }
766
+ }
767
+ return null;
768
+ }