@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,112 @@
1
+ import { parseSupportedMajorOneSchemaVersion } from "./schemaVersion.js";
2
+ import { ArtifactValidationError, arrayFieldPath, joinFieldPath, optionalField, optionalString, requiredArray, requiredField, requiredLiteral, requiredObject, requiredRecord, requiredScalarLike, requiredString, requiredStringArray } from "./runtimeValidation.js";
3
+ import { validateBudgetSummary, validateContextAdequacyStatement, validateContextCapsuleRequest, validateFreshnessSummary, validateFullFileFallbackSummary, validateProvenanceRecord, validateResponsibilityMappingSummary, validateRoleAdequacyStatement, validateRoleContextSummary, validateTruncationSummary } from "./validateMyDevKitContextCapsuleV1.js";
4
+ const ARTIFACT_KIND = "my-dev-kit-retrieval-audit-record-v1";
5
+ const AUDIT_STEP_STATUSES = ["ok", "skipped", "failed"];
6
+ function validateContextCapsuleTool(ctx, value, fieldPath) {
7
+ const obj = requiredObject(ctx, value, fieldPath);
8
+ return {
9
+ name: requiredString(ctx, requiredField(ctx, obj, "name", joinFieldPath(fieldPath, "name")), joinFieldPath(fieldPath, "name")),
10
+ version: requiredString(ctx, requiredField(ctx, obj, "version", joinFieldPath(fieldPath, "version")), joinFieldPath(fieldPath, "version"))
11
+ };
12
+ }
13
+ function validateRetrievalAuditRecordIndex(ctx, value, fieldPath) {
14
+ const obj = requiredObject(ctx, value, fieldPath);
15
+ const result = {
16
+ indexPath: requiredString(ctx, requiredField(ctx, obj, "indexPath", joinFieldPath(fieldPath, "indexPath")), joinFieldPath(fieldPath, "indexPath")),
17
+ manifestPath: requiredString(ctx, requiredField(ctx, obj, "manifestPath", joinFieldPath(fieldPath, "manifestPath")), joinFieldPath(fieldPath, "manifestPath"))
18
+ };
19
+ if (optionalField(obj, "manifestSchemaVersion") !== undefined) {
20
+ result.manifestSchemaVersion = optionalString(ctx, obj.manifestSchemaVersion, joinFieldPath(fieldPath, "manifestSchemaVersion"));
21
+ }
22
+ if (optionalField(obj, "projectRoot") !== undefined) {
23
+ result.projectRoot = optionalString(ctx, obj.projectRoot, joinFieldPath(fieldPath, "projectRoot"));
24
+ }
25
+ return result;
26
+ }
27
+ function validateAuditStepRecord(ctx, value, fieldPath) {
28
+ const obj = requiredRecord(ctx, value, fieldPath);
29
+ const result = {};
30
+ for (const [key, val] of Object.entries(obj)) {
31
+ result[key] = requiredScalarLike(ctx, val, joinFieldPath(fieldPath, key));
32
+ }
33
+ return result;
34
+ }
35
+ function validateAuditStep(ctx, value, fieldPath) {
36
+ const obj = requiredObject(ctx, value, fieldPath);
37
+ return {
38
+ id: requiredString(ctx, requiredField(ctx, obj, "id", joinFieldPath(fieldPath, "id")), joinFieldPath(fieldPath, "id")),
39
+ kind: requiredString(ctx, requiredField(ctx, obj, "kind", joinFieldPath(fieldPath, "kind")), joinFieldPath(fieldPath, "kind")),
40
+ description: requiredString(ctx, requiredField(ctx, obj, "description", joinFieldPath(fieldPath, "description")), joinFieldPath(fieldPath, "description")),
41
+ inputs: validateAuditStepRecord(ctx, requiredField(ctx, obj, "inputs", joinFieldPath(fieldPath, "inputs")), joinFieldPath(fieldPath, "inputs")),
42
+ outputs: validateAuditStepRecord(ctx, requiredField(ctx, obj, "outputs", joinFieldPath(fieldPath, "outputs")), joinFieldPath(fieldPath, "outputs")),
43
+ status: requiredLiteral(ctx, requiredField(ctx, obj, "status", joinFieldPath(fieldPath, "status")), joinFieldPath(fieldPath, "status"), AUDIT_STEP_STATUSES),
44
+ warnings: requiredStringArray(ctx, requiredField(ctx, obj, "warnings", joinFieldPath(fieldPath, "warnings")), joinFieldPath(fieldPath, "warnings"))
45
+ };
46
+ }
47
+ function validateFullFileReadRecommendation(ctx, value, fieldPath) {
48
+ const obj = requiredObject(ctx, value, fieldPath);
49
+ const continuationValue = requiredField(ctx, obj, "continuationOrExpansionAttempted", joinFieldPath(fieldPath, "continuationOrExpansionAttempted"));
50
+ let continuationOrExpansionAttempted;
51
+ if (continuationValue === "unavailable") {
52
+ continuationOrExpansionAttempted = "unavailable";
53
+ }
54
+ else if (typeof continuationValue === "boolean") {
55
+ continuationOrExpansionAttempted = continuationValue;
56
+ }
57
+ else {
58
+ return requiredLiteral(ctx, continuationValue, joinFieldPath(fieldPath, "continuationOrExpansionAttempted"), ["unavailable"]);
59
+ }
60
+ return {
61
+ filePath: requiredString(ctx, requiredField(ctx, obj, "filePath", joinFieldPath(fieldPath, "filePath")), joinFieldPath(fieldPath, "filePath")),
62
+ reason: requiredString(ctx, requiredField(ctx, obj, "reason", joinFieldPath(fieldPath, "reason")), joinFieldPath(fieldPath, "reason")),
63
+ missingContext: requiredString(ctx, requiredField(ctx, obj, "missingContext", joinFieldPath(fieldPath, "missingContext")), joinFieldPath(fieldPath, "missingContext")),
64
+ continuationOrExpansionAttempted
65
+ };
66
+ }
67
+ export function validateMyDevKitRetrievalAuditRecordV1(value, sourcePath) {
68
+ const ctx = { artifactKind: ARTIFACT_KIND, sourcePath };
69
+ try {
70
+ const schemaVersionResult = parseSupportedMajorOneSchemaVersion(requiredField(ctx, value, "schemaVersion", "schemaVersion"), ARTIFACT_KIND, sourcePath);
71
+ if ("ok" in schemaVersionResult)
72
+ return schemaVersionResult;
73
+ const record = {
74
+ schemaVersion: requiredString(ctx, value.schemaVersion, "schemaVersion"),
75
+ generatedAt: requiredString(ctx, requiredField(ctx, value, "generatedAt", "generatedAt"), "generatedAt"),
76
+ tool: validateContextCapsuleTool(ctx, requiredField(ctx, value, "tool", "tool"), "tool"),
77
+ request: validateContextCapsuleRequest(ctx, requiredField(ctx, value, "request", "request"), "request"),
78
+ index: validateRetrievalAuditRecordIndex(ctx, requiredField(ctx, value, "index", "index"), "index"),
79
+ steps: requiredArray(ctx, requiredField(ctx, value, "steps", "steps"), "steps").map((item, i) => validateAuditStep(ctx, item, arrayFieldPath("steps", i))),
80
+ fallbacks: requiredStringArray(ctx, requiredField(ctx, value, "fallbacks", "fallbacks"), "fallbacks"),
81
+ fullFileReadRecommendations: requiredArray(ctx, requiredField(ctx, value, "fullFileReadRecommendations", "fullFileReadRecommendations"), "fullFileReadRecommendations").map((item, i) => validateFullFileReadRecommendation(ctx, item, arrayFieldPath("fullFileReadRecommendations", i))),
82
+ warnings: requiredStringArray(ctx, requiredField(ctx, value, "warnings", "warnings"), "warnings"),
83
+ contextAdequacy: validateContextAdequacyStatement(ctx, requiredField(ctx, value, "contextAdequacy", "contextAdequacy"), "contextAdequacy"),
84
+ roleContext: validateRoleContextSummary(ctx, requiredField(ctx, value, "roleContext", "roleContext"), "roleContext"),
85
+ responsibilityMappings: validateResponsibilityMappingSummary(ctx, requiredField(ctx, value, "responsibilityMappings", "responsibilityMappings"), "responsibilityMappings"),
86
+ roleAdequacy: validateRoleAdequacyStatement(ctx, requiredField(ctx, value, "roleAdequacy", "roleAdequacy"), "roleAdequacy"),
87
+ freshness: validateFreshnessSummary(ctx, requiredField(ctx, value, "freshness", "freshness"), "freshness"),
88
+ budget: validateBudgetSummary(ctx, requiredField(ctx, value, "budget", "budget"), "budget"),
89
+ truncation: validateTruncationSummary(ctx, requiredField(ctx, value, "truncation", "truncation"), "truncation"),
90
+ fullFileFallback: validateFullFileFallbackSummary(ctx, requiredField(ctx, value, "fullFileFallback", "fullFileFallback"), "fullFileFallback"),
91
+ provenance: requiredArray(ctx, requiredField(ctx, value, "provenance", "provenance"), "provenance").map((item, i) => validateProvenanceRecord(ctx, item, arrayFieldPath("provenance", i)))
92
+ };
93
+ // The record above exists only to walk and type-check every field. Per the exact
94
+ // upstream-mirror contract, the returned artifact is always the original parsed
95
+ // reference, not a rebuilt object.
96
+ void record;
97
+ return {
98
+ ok: true,
99
+ artifactKind: ARTIFACT_KIND,
100
+ sourcePath,
101
+ schemaVersion: value.schemaVersion,
102
+ schemaMajor: 1,
103
+ artifact: value,
104
+ rawArtifact: value
105
+ };
106
+ }
107
+ catch (error) {
108
+ if (error instanceof ArtifactValidationError)
109
+ return error.failure;
110
+ throw error;
111
+ }
112
+ }
@@ -0,0 +1,235 @@
1
+ import { parseSupportedMajorOneSchemaVersion } from "./schemaVersion.js";
2
+ import { ArtifactValidationError, arrayFieldPath, joinFieldPath, requiredArray, requiredBoolean, requiredField, requiredLiteral, requiredNullableNumber, requiredNumber, requiredObject, requiredRecord, requiredString, requiredStringArray } from "./runtimeValidation.js";
3
+ const ARTIFACT_KIND = "orchestrator-workflow-instruction-packet-v1";
4
+ const COMMAND_SIDE_EFFECTS = ["read-only", "writes-workspace", "modifies-project", "external-state"];
5
+ const PACKET_INCLUSIONS = ["required", "optional"];
6
+ const PACKET_ADEQUACY_STATUSES = ["adequate", "inadequate"];
7
+ const BUDGET_LIMIT_NAMES = ["maxCommands", "maxRules", "maxRuleDepth", "maxEntryCharacters", "maxTotalCharacters"];
8
+ function validatePrimaryEntry(ctx, value, fieldPath) {
9
+ const obj = requiredObject(ctx, value, fieldPath);
10
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
11
+ const reqStr = (key) => requiredString(ctx, req(key), joinFieldPath(fieldPath, key));
12
+ const reqStrArr = (key) => requiredStringArray(ctx, req(key), joinFieldPath(fieldPath, key));
13
+ return {
14
+ id: reqStr("id"),
15
+ kind: requiredLiteral(ctx, req("kind"), joinFieldPath(fieldPath, "kind"), ["stage"]),
16
+ title: reqStr("title"),
17
+ description: reqStr("description"),
18
+ workflowRef: reqStr("workflowRef"),
19
+ stageName: reqStr("stageName"),
20
+ commandRefs: reqStrArr("commandRefs"),
21
+ ruleRefs: reqStrArr("ruleRefs"),
22
+ optionalCommandRefs: reqStrArr("optionalCommandRefs"),
23
+ optionalRuleRefs: reqStrArr("optionalRuleRefs"),
24
+ reportContractRef: reqStr("reportContractRef"),
25
+ taskInstructions: reqStr("taskInstructions"),
26
+ validationRequirements: reqStrArr("validationRequirements"),
27
+ stopConditions: reqStrArr("stopConditions")
28
+ };
29
+ }
30
+ function validateResolvedCommandEntry(ctx, value, fieldPath) {
31
+ const obj = requiredObject(ctx, value, fieldPath);
32
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
33
+ const reqStr = (key) => requiredString(ctx, req(key), joinFieldPath(fieldPath, key));
34
+ return {
35
+ id: reqStr("id"),
36
+ kind: requiredLiteral(ctx, req("kind"), joinFieldPath(fieldPath, "kind"), ["command"]),
37
+ title: reqStr("title"),
38
+ description: reqStr("description"),
39
+ owner: reqStr("owner"),
40
+ command: reqStr("command"),
41
+ purpose: reqStr("purpose"),
42
+ sideEffect: requiredLiteral(ctx, req("sideEffect"), joinFieldPath(fieldPath, "sideEffect"), COMMAND_SIDE_EFFECTS),
43
+ included: requiredLiteral(ctx, req("included"), joinFieldPath(fieldPath, "included"), PACKET_INCLUSIONS)
44
+ };
45
+ }
46
+ function validateResolvedRuleEntry(ctx, value, fieldPath) {
47
+ const obj = requiredObject(ctx, value, fieldPath);
48
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
49
+ const reqStr = (key) => requiredString(ctx, req(key), joinFieldPath(fieldPath, key));
50
+ return {
51
+ id: reqStr("id"),
52
+ kind: requiredLiteral(ctx, req("kind"), joinFieldPath(fieldPath, "kind"), ["rule"]),
53
+ title: reqStr("title"),
54
+ description: reqStr("description"),
55
+ category: reqStr("category"),
56
+ instruction: reqStr("instruction"),
57
+ ruleRefs: requiredStringArray(ctx, req("ruleRefs"), joinFieldPath(fieldPath, "ruleRefs")),
58
+ included: requiredLiteral(ctx, req("included"), joinFieldPath(fieldPath, "included"), PACKET_INCLUSIONS),
59
+ depth: requiredNumber(ctx, req("depth"), joinFieldPath(fieldPath, "depth"))
60
+ };
61
+ }
62
+ function validateReportContract(ctx, value, fieldPath) {
63
+ const obj = requiredObject(ctx, value, fieldPath);
64
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
65
+ const reqStr = (key) => requiredString(ctx, req(key), joinFieldPath(fieldPath, key));
66
+ return {
67
+ id: reqStr("id"),
68
+ kind: requiredLiteral(ctx, req("kind"), joinFieldPath(fieldPath, "kind"), ["report-contract"]),
69
+ title: reqStr("title"),
70
+ description: reqStr("description"),
71
+ artifactKind: reqStr("artifactKind"),
72
+ purpose: reqStr("purpose"),
73
+ requiredOutputCategory: reqStr("requiredOutputCategory")
74
+ };
75
+ }
76
+ function validateResolutionProvenanceEntry(ctx, value, fieldPath) {
77
+ const obj = requiredObject(ctx, value, fieldPath);
78
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
79
+ const reqStr = (key) => requiredString(ctx, req(key), joinFieldPath(fieldPath, key));
80
+ return {
81
+ rootWorkflowId: reqStr("rootWorkflowId"),
82
+ rootStageId: reqStr("rootStageId"),
83
+ sourceEntryId: reqStr("sourceEntryId"),
84
+ referenceField: reqStr("referenceField"),
85
+ referencedEntryId: reqStr("referencedEntryId"),
86
+ inclusionReason: reqStr("inclusionReason"),
87
+ depth: requiredNumber(ctx, req("depth"), joinFieldPath(fieldPath, "depth"))
88
+ };
89
+ }
90
+ function validateBudgetFinding(ctx, value, fieldPath) {
91
+ const obj = requiredObject(ctx, value, fieldPath);
92
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
93
+ return {
94
+ limitName: requiredLiteral(ctx, req("limitName"), joinFieldPath(fieldPath, "limitName"), BUDGET_LIMIT_NAMES),
95
+ declaredLimit: requiredNullableNumber(ctx, req("declaredLimit"), joinFieldPath(fieldPath, "declaredLimit")),
96
+ used: requiredNumber(ctx, req("used"), joinFieldPath(fieldPath, "used")),
97
+ available: requiredNullableNumber(ctx, req("available"), joinFieldPath(fieldPath, "available")),
98
+ overLimit: requiredBoolean(ctx, req("overLimit"), joinFieldPath(fieldPath, "overLimit")),
99
+ amountExceeded: requiredNumber(ctx, req("amountExceeded"), joinFieldPath(fieldPath, "amountExceeded")),
100
+ affectedEntryIds: requiredStringArray(ctx, req("affectedEntryIds"), joinFieldPath(fieldPath, "affectedEntryIds"))
101
+ };
102
+ }
103
+ function validateInstructionBudgetAccounting(ctx, value, fieldPath) {
104
+ const obj = requiredObject(ctx, value, fieldPath);
105
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
106
+ const perEntryObj = requiredRecord(ctx, req("perEntryCharacters"), joinFieldPath(fieldPath, "perEntryCharacters"));
107
+ const perEntryCharacters = {};
108
+ for (const [key, val] of Object.entries(perEntryObj)) {
109
+ perEntryCharacters[key] = requiredNumber(ctx, val, joinFieldPath(joinFieldPath(fieldPath, "perEntryCharacters"), key));
110
+ }
111
+ return {
112
+ findings: requiredArray(ctx, req("findings"), joinFieldPath(fieldPath, "findings")).map((item, i) => validateBudgetFinding(ctx, item, arrayFieldPath(joinFieldPath(fieldPath, "findings"), i))),
113
+ overLimit: requiredBoolean(ctx, req("overLimit"), joinFieldPath(fieldPath, "overLimit")),
114
+ adequate: requiredBoolean(ctx, req("adequate"), joinFieldPath(fieldPath, "adequate")),
115
+ totalCharacters: requiredNumber(ctx, req("totalCharacters"), joinFieldPath(fieldPath, "totalCharacters")),
116
+ perEntryCharacters
117
+ };
118
+ }
119
+ function validateTruncationRecord(ctx, value, fieldPath) {
120
+ const obj = requiredObject(ctx, value, fieldPath);
121
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
122
+ return {
123
+ rootOptionalEntryId: requiredString(ctx, req("rootOptionalEntryId"), joinFieldPath(fieldPath, "rootOptionalEntryId")),
124
+ affectedEntryIds: requiredStringArray(ctx, req("affectedEntryIds"), joinFieldPath(fieldPath, "affectedEntryIds")),
125
+ limitingField: requiredLiteral(ctx, req("limitingField"), joinFieldPath(fieldPath, "limitingField"), BUDGET_LIMIT_NAMES),
126
+ declaredLimit: requiredNullableNumber(ctx, req("declaredLimit"), joinFieldPath(fieldPath, "declaredLimit")),
127
+ usedBefore: requiredNumber(ctx, req("usedBefore"), joinFieldPath(fieldPath, "usedBefore")),
128
+ attemptedAfter: requiredNumber(ctx, req("attemptedAfter"), joinFieldPath(fieldPath, "attemptedAfter")),
129
+ reason: requiredString(ctx, req("reason"), joinFieldPath(fieldPath, "reason"))
130
+ };
131
+ }
132
+ function validatePacketTruncation(ctx, value, fieldPath) {
133
+ const obj = requiredObject(ctx, value, fieldPath);
134
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
135
+ return {
136
+ truncated: requiredBoolean(ctx, req("truncated"), joinFieldPath(fieldPath, "truncated")),
137
+ records: requiredArray(ctx, req("records"), joinFieldPath(fieldPath, "records")).map((item, i) => validateTruncationRecord(ctx, item, arrayFieldPath(joinFieldPath(fieldPath, "records"), i))),
138
+ droppedOptionalCommandIds: requiredStringArray(ctx, req("droppedOptionalCommandIds"), joinFieldPath(fieldPath, "droppedOptionalCommandIds")),
139
+ droppedOptionalRuleIds: requiredStringArray(ctx, req("droppedOptionalRuleIds"), joinFieldPath(fieldPath, "droppedOptionalRuleIds")),
140
+ droppedOptionalDependencyIds: requiredStringArray(ctx, req("droppedOptionalDependencyIds"), joinFieldPath(fieldPath, "droppedOptionalDependencyIds")),
141
+ warnings: requiredStringArray(ctx, req("warnings"), joinFieldPath(fieldPath, "warnings"))
142
+ };
143
+ }
144
+ function validatePacketAdequacy(ctx, value, fieldPath) {
145
+ const obj = requiredObject(ctx, value, fieldPath);
146
+ const req = (key) => requiredField(ctx, obj, key, joinFieldPath(fieldPath, key));
147
+ return {
148
+ status: requiredLiteral(ctx, req("status"), joinFieldPath(fieldPath, "status"), PACKET_ADEQUACY_STATUSES),
149
+ reasons: requiredStringArray(ctx, req("reasons"), joinFieldPath(fieldPath, "reasons")),
150
+ requiredContentComplete: requiredBoolean(ctx, req("requiredContentComplete"), joinFieldPath(fieldPath, "requiredContentComplete")),
151
+ requiredBudgetSatisfied: requiredBoolean(ctx, req("requiredBudgetSatisfied"), joinFieldPath(fieldPath, "requiredBudgetSatisfied")),
152
+ optionalContentDropped: requiredBoolean(ctx, req("optionalContentDropped"), joinFieldPath(fieldPath, "optionalContentDropped")),
153
+ affectedEntryIds: requiredStringArray(ctx, req("affectedEntryIds"), joinFieldPath(fieldPath, "affectedEntryIds"))
154
+ };
155
+ }
156
+ function findDuplicates(ids) {
157
+ const seen = new Set();
158
+ const dupes = new Set();
159
+ for (const id of ids) {
160
+ if (seen.has(id))
161
+ dupes.add(id);
162
+ seen.add(id);
163
+ }
164
+ return [...dupes];
165
+ }
166
+ export function validateOrchestratorWorkflowInstructionPacketV1(value, sourcePath) {
167
+ const ctx = { artifactKind: ARTIFACT_KIND, sourcePath };
168
+ try {
169
+ const schemaVersionResult = parseSupportedMajorOneSchemaVersion(requiredField(ctx, value, "schemaVersion", "schemaVersion"), ARTIFACT_KIND, sourcePath);
170
+ if ("ok" in schemaVersionResult)
171
+ return schemaVersionResult;
172
+ const resolvedCommands = requiredArray(ctx, requiredField(ctx, value, "resolvedCommands", "resolvedCommands"), "resolvedCommands").map((item, i) => validateResolvedCommandEntry(ctx, item, arrayFieldPath("resolvedCommands", i)));
173
+ const dupCommandIds = findDuplicates(resolvedCommands.map((c) => c.id));
174
+ if (dupCommandIds.length > 0) {
175
+ return {
176
+ ok: false,
177
+ artifactKind: ARTIFACT_KIND,
178
+ sourcePath,
179
+ code: "DUPLICATE_RESOLVED_COMMAND_ID",
180
+ message: `Artifact "${ARTIFACT_KIND}" at "${sourcePath}" has duplicate resolvedCommands[].id value(s): ${dupCommandIds.join(", ")}.`,
181
+ fieldPath: "resolvedCommands",
182
+ actual: dupCommandIds
183
+ };
184
+ }
185
+ const resolvedRules = requiredArray(ctx, requiredField(ctx, value, "resolvedRules", "resolvedRules"), "resolvedRules").map((item, i) => validateResolvedRuleEntry(ctx, item, arrayFieldPath("resolvedRules", i)));
186
+ const dupRuleIds = findDuplicates(resolvedRules.map((r) => r.id));
187
+ if (dupRuleIds.length > 0) {
188
+ return {
189
+ ok: false,
190
+ artifactKind: ARTIFACT_KIND,
191
+ sourcePath,
192
+ code: "DUPLICATE_RESOLVED_RULE_ID",
193
+ message: `Artifact "${ARTIFACT_KIND}" at "${sourcePath}" has duplicate resolvedRules[].id value(s): ${dupRuleIds.join(", ")}.`,
194
+ fieldPath: "resolvedRules",
195
+ actual: dupRuleIds
196
+ };
197
+ }
198
+ const packet = {
199
+ schemaVersion: requiredString(ctx, value.schemaVersion, "schemaVersion"),
200
+ catalogSchemaVersion: requiredString(ctx, requiredField(ctx, value, "catalogSchemaVersion", "catalogSchemaVersion"), "catalogSchemaVersion"),
201
+ catalogVersion: requiredString(ctx, requiredField(ctx, value, "catalogVersion", "catalogVersion"), "catalogVersion"),
202
+ workflowId: requiredString(ctx, requiredField(ctx, value, "workflowId", "workflowId"), "workflowId"),
203
+ stageId: requiredString(ctx, requiredField(ctx, value, "stageId", "stageId"), "stageId"),
204
+ primaryEntry: validatePrimaryEntry(ctx, requiredField(ctx, value, "primaryEntry", "primaryEntry"), "primaryEntry"),
205
+ resolvedCommands,
206
+ resolvedRules,
207
+ reportContract: validateReportContract(ctx, requiredField(ctx, value, "reportContract", "reportContract"), "reportContract"),
208
+ validationRequirements: requiredStringArray(ctx, requiredField(ctx, value, "validationRequirements", "validationRequirements"), "validationRequirements"),
209
+ stopConditions: requiredStringArray(ctx, requiredField(ctx, value, "stopConditions", "stopConditions"), "stopConditions"),
210
+ resolutionProvenance: requiredArray(ctx, requiredField(ctx, value, "resolutionProvenance", "resolutionProvenance"), "resolutionProvenance").map((item, i) => validateResolutionProvenanceEntry(ctx, item, arrayFieldPath("resolutionProvenance", i))),
211
+ budget: validateInstructionBudgetAccounting(ctx, requiredField(ctx, value, "budget", "budget"), "budget"),
212
+ truncation: validatePacketTruncation(ctx, requiredField(ctx, value, "truncation", "truncation"), "truncation"),
213
+ adequacy: validatePacketAdequacy(ctx, requiredField(ctx, value, "adequacy", "adequacy"), "adequacy"),
214
+ unresolvedReferences: requiredStringArray(ctx, requiredField(ctx, value, "unresolvedReferences", "unresolvedReferences"), "unresolvedReferences"),
215
+ warnings: requiredStringArray(ctx, requiredField(ctx, value, "warnings", "warnings"), "warnings")
216
+ };
217
+ // The record above exists only to walk and type-check every field. The returned
218
+ // artifact is always the original parsed reference, never a rebuilt object.
219
+ void packet;
220
+ return {
221
+ ok: true,
222
+ artifactKind: ARTIFACT_KIND,
223
+ sourcePath,
224
+ schemaVersion: value.schemaVersion,
225
+ schemaMajor: 1,
226
+ artifact: value,
227
+ rawArtifact: value
228
+ };
229
+ }
230
+ catch (error) {
231
+ if (error instanceof ArtifactValidationError)
232
+ return error.failure;
233
+ throw error;
234
+ }
235
+ }
@@ -0,0 +1,148 @@
1
+ import { makeFailure } from "./runtimeValidation.js";
2
+ import { parseSupplementalContextText } from "./supplementalContextTextParser.js";
3
+ import { REQUIRED_METADATA_BY_DOCUMENT_KIND, REQUIRED_SECTIONS_BY_DOCUMENT_KIND, ROLE_BY_DOCUMENT_KIND, SUPPLEMENTAL_CONTEXT_PACKET_SCHEMA_SUPPORTED_MAJOR, SUPPLEMENTAL_CONTEXT_RETRIEVAL_REPORT_SCHEMA_SUPPORTED_MAJOR, VALID_ADEQUACY_VALUES, VALID_DECLARED_STATUSES, VALID_FRESHNESS_VALUES, VALID_REPOSITORY_SCOPES, VALID_TRUNCATION_VALUES, isRetrievalReportKind, isTestKind } from "./supplementalContextTypes.js";
4
+ const SCHEMA_VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+$/;
5
+ function supportedMajorForKind(kind) {
6
+ return isRetrievalReportKind(kind)
7
+ ? SUPPLEMENTAL_CONTEXT_RETRIEVAL_REPORT_SCHEMA_SUPPORTED_MAJOR
8
+ : SUPPLEMENTAL_CONTEXT_PACKET_SCHEMA_SUPPORTED_MAJOR;
9
+ }
10
+ function literalOrFail(artifactKind, sourcePath, fieldPath, value, allowed, errorCode = "INVALID_LITERAL_VALUE") {
11
+ if (allowed.includes(value))
12
+ return value;
13
+ return {
14
+ ok: false,
15
+ artifactKind,
16
+ sourcePath,
17
+ code: errorCode,
18
+ message: `Field "${fieldPath}" in artifact "${artifactKind}" at "${sourcePath}" has invalid value "${value}". Expected one of: ${allowed.join(", ")}.`,
19
+ fieldPath,
20
+ expected: allowed.join(" | "),
21
+ actual: value
22
+ };
23
+ }
24
+ function isFailure(value) {
25
+ return typeof value === "object" && value !== null && value.ok === false;
26
+ }
27
+ export function validateSupplementalContextDocumentV1(artifactKind, expectedKind, text, sourcePath) {
28
+ const parsed = parseSupplementalContextText(text);
29
+ if (parsed.metadataOrder.length === 0 && parsed.sectionOrder.length === 0) {
30
+ return makeFailure(artifactKind, sourcePath, "MALFORMED_TEXT_ARTIFACT", `Artifact "${artifactKind}" at "${sourcePath}" contains no recognizable "Key: value" metadata or "## Heading" sections.`);
31
+ }
32
+ // Kind/role identity is checked before general required-metadata/section completeness so
33
+ // that feeding one document kind's file to another kind's reader is reported as a
34
+ // structural identity mismatch (DOCUMENT_KIND_MISMATCH / DOCUMENT_ROLE_MISMATCH) rather
35
+ // than as an incidental "missing metadata key" from the wrong kind's required-field list.
36
+ const declaredKind = parsed.metadata["Document kind"];
37
+ if (declaredKind !== expectedKind) {
38
+ return makeFailure(artifactKind, sourcePath, "DOCUMENT_KIND_MISMATCH", `Artifact "${artifactKind}" at "${sourcePath}" declares document kind "${declaredKind}" but this reader expects "${expectedKind}".`, "Document kind", expectedKind, declaredKind);
39
+ }
40
+ const expectedRole = ROLE_BY_DOCUMENT_KIND[expectedKind];
41
+ const declaredRole = parsed.metadata["Role"];
42
+ if (declaredRole !== expectedRole) {
43
+ return makeFailure(artifactKind, sourcePath, "DOCUMENT_ROLE_MISMATCH", `Artifact "${artifactKind}" at "${sourcePath}" declares role "${declaredRole}" but this reader expects "${expectedRole}".`, "Role", expectedRole, declaredRole);
44
+ }
45
+ const requiredMetadata = REQUIRED_METADATA_BY_DOCUMENT_KIND[expectedKind];
46
+ for (const key of requiredMetadata) {
47
+ if (!(key in parsed.metadata)) {
48
+ return makeFailure(artifactKind, sourcePath, "MISSING_REQUIRED_METADATA", `Artifact "${artifactKind}" at "${sourcePath}" is missing required metadata key "${key}".`, key, "present");
49
+ }
50
+ }
51
+ const requiredSections = REQUIRED_SECTIONS_BY_DOCUMENT_KIND[expectedKind];
52
+ for (const heading of requiredSections) {
53
+ if (!(heading in parsed.sections)) {
54
+ return makeFailure(artifactKind, sourcePath, "MISSING_REQUIRED_SECTION", `Artifact "${artifactKind}" at "${sourcePath}" is missing required section heading "## ${heading}".`, heading, "present");
55
+ }
56
+ }
57
+ const schemaVersion = parsed.metadata["Schema version"];
58
+ if (!SCHEMA_VERSION_PATTERN.test(schemaVersion)) {
59
+ return makeFailure(artifactKind, sourcePath, "INVALID_SCHEMA_VERSION", `Artifact "${artifactKind}" at "${sourcePath}" has an invalid "Schema version": expected strict "x.y.z" semantic version.`, "Schema version", "^[0-9]+\\.[0-9]+\\.[0-9]+$", schemaVersion);
60
+ }
61
+ const major = Number(schemaVersion.split(".")[0]);
62
+ const supportedMajor = supportedMajorForKind(expectedKind);
63
+ if (major !== supportedMajor) {
64
+ return makeFailure(artifactKind, sourcePath, "UNSUPPORTED_SCHEMA_MAJOR", `Artifact "${artifactKind}" at "${sourcePath}" has unsupported schema major "${major}" in "Schema version": supported major is ${supportedMajor}.`, "Schema version", String(supportedMajor), schemaVersion);
65
+ }
66
+ const status = literalOrFail(artifactKind, sourcePath, "Status", parsed.metadata["Status"], VALID_DECLARED_STATUSES, "UNKNOWN_STATUS_VALUE");
67
+ if (isFailure(status))
68
+ return status;
69
+ const repositoryScope = literalOrFail(artifactKind, sourcePath, "Repository scope", parsed.metadata["Repository scope"], VALID_REPOSITORY_SCOPES);
70
+ if (isFailure(repositoryScope))
71
+ return repositoryScope;
72
+ const freshness = literalOrFail(artifactKind, sourcePath, "Freshness", parsed.metadata["Freshness"], VALID_FRESHNESS_VALUES);
73
+ if (isFailure(freshness))
74
+ return freshness;
75
+ const adequacy = literalOrFail(artifactKind, sourcePath, "Adequacy", parsed.metadata["Adequacy"], VALID_ADEQUACY_VALUES);
76
+ if (isFailure(adequacy))
77
+ return adequacy;
78
+ const requiredEvidenceTruncated = literalOrFail(artifactKind, sourcePath, "Required evidence truncated", parsed.metadata["Required evidence truncated"], VALID_TRUNCATION_VALUES);
79
+ if (isFailure(requiredEvidenceTruncated))
80
+ return requiredEvidenceTruncated;
81
+ const indexIdentity = parsed.metadata["Index identity"];
82
+ if (!indexIdentity || indexIdentity.length === 0) {
83
+ return makeFailure(artifactKind, sourcePath, "MISSING_CANONICAL_IDENTITY", `Artifact "${artifactKind}" at "${sourcePath}" is missing a non-empty canonical "Index identity".`, "Index identity", "present");
84
+ }
85
+ const document = {
86
+ documentKind: expectedKind,
87
+ role: expectedRole,
88
+ schemaVersion,
89
+ schemaMajor: 1,
90
+ status,
91
+ repositoryScope,
92
+ freshness,
93
+ adequacy,
94
+ requiredEvidenceTruncated,
95
+ contextCapsuleSchemaVersion: parsed.metadata["Context capsule schema version"],
96
+ retrievalAuditSchemaVersion: parsed.metadata["Retrieval audit schema version"],
97
+ toolName: parsed.metadata["Tool name"],
98
+ toolVersion: parsed.metadata["Tool version"],
99
+ indexIdentity,
100
+ rawMetadata: parsed.metadata,
101
+ sections: parsed.sections,
102
+ sectionOrder: parsed.sectionOrder,
103
+ metadataOrder: parsed.metadataOrder,
104
+ warnings: []
105
+ };
106
+ if (isRetrievalReportKind(expectedKind)) {
107
+ document.requestSchemaVersion = parsed.metadata["Request schema version"];
108
+ const fullFileFallbackUsed = literalOrFail(artifactKind, sourcePath, "Full-file fallback used", parsed.metadata["Full-file fallback used"], VALID_TRUNCATION_VALUES);
109
+ if (isFailure(fullFileFallbackUsed))
110
+ return fullFileFallbackUsed;
111
+ document.fullFileFallbackUsed = fullFileFallbackUsed;
112
+ const determinismChecked = literalOrFail(artifactKind, sourcePath, "Determinism checked", parsed.metadata["Determinism checked"], VALID_TRUNCATION_VALUES);
113
+ if (isFailure(determinismChecked))
114
+ return determinismChecked;
115
+ document.determinismChecked = determinismChecked;
116
+ }
117
+ if (isTestKind(expectedKind)) {
118
+ const responsibilityMappingsTruncated = literalOrFail(artifactKind, sourcePath, "Responsibility mappings truncated", parsed.metadata["Responsibility mappings truncated"], VALID_TRUNCATION_VALUES);
119
+ if (isFailure(responsibilityMappingsTruncated))
120
+ return responsibilityMappingsTruncated;
121
+ document.responsibilityMappingsTruncated = responsibilityMappingsTruncated;
122
+ // Preserved verbatim, never validated against the orchestrator's internal
123
+ // CriticalResponsibilityMappingState enum -- see supplementalContextTypes.ts.
124
+ const criticalStatus = parsed.metadata["Critical responsibility mapping status"];
125
+ if (!criticalStatus || criticalStatus.length === 0) {
126
+ return makeFailure(artifactKind, sourcePath, "MISSING_REQUIRED_METADATA", `Artifact "${artifactKind}" at "${sourcePath}" is missing a non-empty "Critical responsibility mapping status".`, "Critical responsibility mapping status", "present");
127
+ }
128
+ document.criticalResponsibilityMappingStatus = criticalStatus;
129
+ }
130
+ if (parsed.duplicateMetadataKeys.length > 0) {
131
+ document.warnings.push(`Duplicate metadata keys were ignored (first occurrence kept): ${parsed.duplicateMetadataKeys.join(", ")}.`);
132
+ }
133
+ if (parsed.duplicateSectionHeadings.length > 0) {
134
+ document.warnings.push(`Duplicate section headings were ignored (first occurrence kept): ${parsed.duplicateSectionHeadings.join(", ")}.`);
135
+ }
136
+ if (parsed.emptyMetadataKeys.length > 0) {
137
+ document.warnings.push(`Metadata keys had empty values: ${parsed.emptyMetadataKeys.join(", ")}.`);
138
+ }
139
+ return {
140
+ ok: true,
141
+ artifactKind,
142
+ sourcePath,
143
+ schemaVersion,
144
+ schemaMajor: 1,
145
+ artifact: document,
146
+ rawArtifact: { metadata: parsed.metadata, sections: parsed.sections }
147
+ };
148
+ }
@@ -0,0 +1,46 @@
1
+ import { loadV043StrategyArtifacts } from "./loadV043StrategyArtifacts.js";
2
+ import { V043_STAGE_CONTEXT_STRATEGY_IDS } from "./v043StrategyIds.js";
3
+ import { validateV043StrategyInput } from "./validateV043StrategyInput.js";
4
+ function extractValidStrategyId(value) {
5
+ if (typeof value !== "object" || value === null || Array.isArray(value))
6
+ return null;
7
+ const strategyId = value.strategyId;
8
+ if (typeof strategyId === "string" && V043_STAGE_CONTEXT_STRATEGY_IDS.includes(strategyId)) {
9
+ return strategyId;
10
+ }
11
+ return null;
12
+ }
13
+ export async function executeV043StageContextStrategy(value) {
14
+ const validation = validateV043StrategyInput(value);
15
+ if (!validation.ok) {
16
+ const issues = validation.issues.map((issue) => ({
17
+ code: "INVALID_STRATEGY_INPUT",
18
+ fieldPath: issue.fieldPath,
19
+ message: issue.message,
20
+ details: issue
21
+ }));
22
+ return {
23
+ status: "invalid-input",
24
+ strategyId: extractValidStrategyId(value),
25
+ input: value,
26
+ issues
27
+ };
28
+ }
29
+ try {
30
+ return await loadV043StrategyArtifacts(validation.input);
31
+ }
32
+ catch {
33
+ return {
34
+ status: "failed",
35
+ strategyId: extractValidStrategyId(value),
36
+ input: value,
37
+ issues: [
38
+ {
39
+ code: "UNEXPECTED_EXECUTION_ERROR",
40
+ fieldPath: "execution",
41
+ message: "Unexpected v0.4.3 stage-context strategy execution failure."
42
+ }
43
+ ]
44
+ };
45
+ }
46
+ }
@@ -1,3 +1,12 @@
1
1
  export * from "./config.js";
2
2
  export * from "./plugin.js";
3
3
  export * from "./resultMapping.js";
4
+ export * from "./v043FullWorkflowLibraryFixture.js";
5
+ export { readV043FullWorkflowLibraryFixture } from "./readV043FullWorkflowLibraryFixture.js";
6
+ export * from "./v043StrategyExecutionTypes.js";
7
+ export { executeV043StageContextStrategy } from "./executeV043StageContextStrategy.js";
8
+ export * from "./resolveV043StrategyInputs.js";
9
+ export { evaluateV043StageContextExecution } from "../../../evaluation/stageContextMetrics/index.js";
10
+ export * from "./v043RunAssuranceTypes.js";
11
+ export { validateV043RunAssuranceConfig } from "./validateV043RunAssuranceConfig.js";
12
+ export { runV043StageContextStrategyWithAssurance } from "./runV043StageContextStrategyWithAssurance.js";