@exaudeus/workrail 1.0.0 → 1.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.
Files changed (120) hide show
  1. package/dist/application/services/output-normalizer.d.ts +9 -0
  2. package/dist/application/services/output-normalizer.js +38 -0
  3. package/dist/application/services/validation-engine.d.ts +15 -1
  4. package/dist/application/services/validation-engine.js +81 -51
  5. package/dist/application/services/workflow-compiler.d.ts +3 -0
  6. package/dist/application/services/workflow-compiler.js +26 -0
  7. package/dist/application/services/workflow-interpreter.d.ts +4 -1
  8. package/dist/application/services/workflow-interpreter.js +85 -24
  9. package/dist/application/services/workflow-service.js +19 -2
  10. package/dist/manifest.json +379 -75
  11. package/dist/mcp/handler-factory.d.ts +7 -0
  12. package/dist/mcp/handler-factory.js +70 -0
  13. package/dist/mcp/handlers/shared/with-timeout.d.ts +1 -0
  14. package/dist/mcp/handlers/shared/with-timeout.js +9 -0
  15. package/dist/mcp/handlers/v2-advance-core.d.ts +45 -0
  16. package/dist/mcp/handlers/v2-advance-core.js +433 -0
  17. package/dist/mcp/handlers/v2-context-budget.d.ts +17 -0
  18. package/dist/mcp/handlers/v2-context-budget.js +169 -0
  19. package/dist/mcp/handlers/v2-error-mapping.d.ts +34 -0
  20. package/dist/mcp/handlers/v2-error-mapping.js +125 -0
  21. package/dist/mcp/handlers/v2-execution-helpers.js +4 -1
  22. package/dist/mcp/handlers/v2-execution.d.ts +19 -0
  23. package/dist/mcp/handlers/v2-execution.js +366 -589
  24. package/dist/mcp/handlers/v2-state-conversion.d.ts +40 -0
  25. package/dist/mcp/handlers/v2-state-conversion.js +132 -0
  26. package/dist/mcp/handlers/v2-token-ops.d.ts +33 -0
  27. package/dist/mcp/handlers/v2-token-ops.js +62 -0
  28. package/dist/mcp/handlers/v2-workflow.js +3 -8
  29. package/dist/mcp/handlers/workflow.js +4 -11
  30. package/dist/mcp/output-schemas.d.ts +514 -38
  31. package/dist/mcp/output-schemas.js +102 -7
  32. package/dist/mcp/server.js +23 -127
  33. package/dist/mcp/tool-descriptions.js +142 -18
  34. package/dist/mcp/types/workflow-tool-edition.d.ts +28 -0
  35. package/dist/mcp/types/workflow-tool-edition.js +10 -0
  36. package/dist/mcp/types.d.ts +2 -0
  37. package/dist/mcp/v1/tool-registry.d.ts +8 -0
  38. package/dist/mcp/v1/tool-registry.js +49 -0
  39. package/dist/mcp/v2/tool-registry.d.ts +2 -5
  40. package/dist/mcp/v2/tool-registry.js +33 -32
  41. package/dist/mcp/v2/tools.d.ts +23 -2
  42. package/dist/mcp/v2/tools.js +38 -7
  43. package/dist/mcp/workflow-tool-edition-selector.d.ts +4 -0
  44. package/dist/mcp/workflow-tool-edition-selector.js +13 -0
  45. package/dist/types/workflow-definition.d.ts +19 -0
  46. package/dist/v2/durable-core/constants.d.ts +3 -0
  47. package/dist/v2/durable-core/constants.js +4 -1
  48. package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +15 -7
  49. package/dist/v2/durable-core/domain/ack-advance-append-plan.js +89 -24
  50. package/dist/v2/durable-core/domain/artifact-contract-validator.d.ts +31 -0
  51. package/dist/v2/durable-core/domain/artifact-contract-validator.js +98 -0
  52. package/dist/v2/durable-core/domain/blocked-node-builder.d.ts +20 -0
  53. package/dist/v2/durable-core/domain/blocked-node-builder.js +94 -0
  54. package/dist/v2/durable-core/domain/blocking-decision.d.ts +32 -0
  55. package/dist/v2/durable-core/domain/blocking-decision.js +41 -0
  56. package/dist/v2/durable-core/domain/context-merge.d.ts +8 -0
  57. package/dist/v2/durable-core/domain/context-merge.js +40 -0
  58. package/dist/v2/durable-core/domain/decision-trace-builder.d.ts +33 -0
  59. package/dist/v2/durable-core/domain/decision-trace-builder.js +92 -0
  60. package/dist/v2/durable-core/domain/function-definition-expander.d.ts +14 -0
  61. package/dist/v2/durable-core/domain/function-definition-expander.js +66 -0
  62. package/dist/v2/durable-core/domain/gap-builder.d.ts +19 -0
  63. package/dist/v2/durable-core/domain/gap-builder.js +24 -0
  64. package/dist/v2/durable-core/domain/loop-control-evaluator.d.ts +13 -0
  65. package/dist/v2/durable-core/domain/loop-control-evaluator.js +24 -0
  66. package/dist/v2/durable-core/domain/observation-builder.d.ts +16 -0
  67. package/dist/v2/durable-core/domain/observation-builder.js +42 -0
  68. package/dist/v2/durable-core/domain/outputs.js +2 -2
  69. package/dist/v2/durable-core/domain/prompt-renderer.d.ts +24 -0
  70. package/dist/v2/durable-core/domain/prompt-renderer.js +200 -0
  71. package/dist/v2/durable-core/domain/reason-model.d.ts +96 -0
  72. package/dist/v2/durable-core/domain/reason-model.js +241 -0
  73. package/dist/v2/durable-core/domain/recap-recovery.d.ts +24 -0
  74. package/dist/v2/durable-core/domain/recap-recovery.js +71 -0
  75. package/dist/v2/durable-core/domain/recommendation-warnings.d.ts +20 -0
  76. package/dist/v2/durable-core/domain/recommendation-warnings.js +35 -0
  77. package/dist/v2/durable-core/domain/risk-policy-guardrails.d.ts +15 -0
  78. package/dist/v2/durable-core/domain/risk-policy-guardrails.js +78 -0
  79. package/dist/v2/durable-core/domain/validation-criteria-validator.d.ts +16 -0
  80. package/dist/v2/durable-core/domain/validation-criteria-validator.js +46 -0
  81. package/dist/v2/durable-core/domain/validation-event-builder.d.ts +26 -0
  82. package/dist/v2/durable-core/domain/validation-event-builder.js +100 -0
  83. package/dist/v2/durable-core/domain/validation-loader.d.ts +11 -0
  84. package/dist/v2/durable-core/domain/validation-loader.js +21 -0
  85. package/dist/v2/durable-core/domain/validation-requirements-extractor.d.ts +2 -0
  86. package/dist/v2/durable-core/domain/validation-requirements-extractor.js +58 -0
  87. package/dist/v2/durable-core/projections/snapshot-state.js +1 -1
  88. package/dist/v2/durable-core/schemas/artifacts/index.d.ts +4 -0
  89. package/dist/v2/durable-core/schemas/artifacts/index.js +18 -0
  90. package/dist/v2/durable-core/schemas/artifacts/loop-control.d.ts +66 -0
  91. package/dist/v2/durable-core/schemas/artifacts/loop-control.js +47 -0
  92. package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +598 -0
  93. package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.js +89 -0
  94. package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +3801 -57
  95. package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.js +12 -2
  96. package/dist/v2/durable-core/schemas/execution-snapshot/index.d.ts +2 -0
  97. package/dist/v2/durable-core/schemas/execution-snapshot/index.js +3 -1
  98. package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +6201 -2071
  99. package/dist/v2/durable-core/schemas/session/events.d.ts +216 -45
  100. package/dist/v2/durable-core/schemas/session/events.js +17 -1
  101. package/dist/v2/durable-core/schemas/session/validation-event.d.ts +68 -0
  102. package/dist/v2/durable-core/schemas/session/validation-event.js +52 -0
  103. package/dist/v2/durable-core/tokens/payloads.d.ts +16 -16
  104. package/dist/v2/infra/local/workspace-anchor/index.d.ts +9 -0
  105. package/dist/v2/infra/local/workspace-anchor/index.js +44 -0
  106. package/dist/v2/ports/workspace-anchor.port.d.ts +18 -0
  107. package/dist/v2/ports/workspace-anchor.port.js +2 -0
  108. package/dist/v2/projections/artifacts.d.ts +22 -0
  109. package/dist/v2/projections/artifacts.js +53 -0
  110. package/dist/v2/projections/projection-timing.d.ts +13 -0
  111. package/dist/v2/projections/projection-timing.js +23 -0
  112. package/dist/v2/projections/run-context.d.ts +22 -0
  113. package/dist/v2/projections/run-context.js +33 -0
  114. package/dist/v2/projections/run-dag.d.ts +1 -1
  115. package/dist/v2/projections/run-status-signals.js +3 -8
  116. package/package.json +1 -1
  117. package/spec/workflow.schema.json +60 -0
  118. package/spec/workflow.schema.v0.0.1.json +38 -0
  119. package/workflows/coding-task-workflow-agentic.json +11 -18
  120. package/workflows/test-artifact-loop-control.json +59 -0
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkRecommendationExceedance = checkRecommendationExceedance;
4
+ const AUTONOMY_ORDER = {
5
+ guided: 0,
6
+ full_auto_stop_on_user_deps: 1,
7
+ full_auto_never_stop: 2,
8
+ };
9
+ const RISK_POLICY_ORDER = {
10
+ conservative: 0,
11
+ balanced: 1,
12
+ aggressive: 2,
13
+ };
14
+ function checkRecommendationExceedance(effective, recommended) {
15
+ const warnings = [];
16
+ if (recommended.recommendedAutonomy !== undefined &&
17
+ AUTONOMY_ORDER[effective.autonomy] > AUTONOMY_ORDER[recommended.recommendedAutonomy]) {
18
+ warnings.push({
19
+ kind: 'autonomy_exceeds_recommendation',
20
+ effective: effective.autonomy,
21
+ recommended: recommended.recommendedAutonomy,
22
+ summary: `Effective autonomy '${effective.autonomy}' exceeds workflow recommendation '${recommended.recommendedAutonomy}'.`,
23
+ });
24
+ }
25
+ if (recommended.recommendedRiskPolicy !== undefined &&
26
+ RISK_POLICY_ORDER[effective.riskPolicy] > RISK_POLICY_ORDER[recommended.recommendedRiskPolicy]) {
27
+ warnings.push({
28
+ kind: 'risk_policy_exceeds_recommendation',
29
+ effective: effective.riskPolicy,
30
+ recommended: recommended.recommendedRiskPolicy,
31
+ summary: `Effective riskPolicy '${effective.riskPolicy}' exceeds workflow recommendation '${recommended.recommendedRiskPolicy}'.`,
32
+ });
33
+ }
34
+ return warnings;
35
+ }
@@ -0,0 +1,15 @@
1
+ import type { RiskPolicyV2 } from '../schemas/session/preferences.js';
2
+ import type { ReasonV1 } from './reason-model.js';
3
+ export type GuardrailOutcome = {
4
+ readonly disposition: 'block';
5
+ readonly reason: ReasonV1;
6
+ } | {
7
+ readonly disposition: 'downgrade_to_warning';
8
+ readonly reason: ReasonV1;
9
+ readonly rationale: string;
10
+ };
11
+ export declare function applyGuardrail(policy: RiskPolicyV2, reason: ReasonV1): GuardrailOutcome;
12
+ export declare function applyGuardrails(policy: RiskPolicyV2, reasons: readonly ReasonV1[]): {
13
+ readonly blocking: readonly ReasonV1[];
14
+ readonly downgraded: readonly GuardrailOutcome[];
15
+ };
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyGuardrail = applyGuardrail;
4
+ exports.applyGuardrails = applyGuardrails;
5
+ function isNeverDowngradable(reason) {
6
+ switch (reason.kind) {
7
+ case 'missing_required_output':
8
+ case 'invalid_required_output':
9
+ return true;
10
+ case 'user_only_dependency':
11
+ return true;
12
+ case 'invariant_violation':
13
+ case 'storage_corruption_detected':
14
+ case 'evaluation_error':
15
+ return true;
16
+ case 'missing_context_key':
17
+ case 'context_budget_exceeded':
18
+ return true;
19
+ case 'required_capability_unknown':
20
+ case 'required_capability_unavailable':
21
+ return false;
22
+ default: {
23
+ const _exhaustive = reason;
24
+ return _exhaustive;
25
+ }
26
+ }
27
+ }
28
+ function applyGuardrail(policy, reason) {
29
+ if (isNeverDowngradable(reason)) {
30
+ return { disposition: 'block', reason };
31
+ }
32
+ switch (policy) {
33
+ case 'conservative':
34
+ return { disposition: 'block', reason };
35
+ case 'balanced':
36
+ if (reason.kind === 'required_capability_unknown') {
37
+ return {
38
+ disposition: 'downgrade_to_warning',
39
+ reason,
40
+ rationale: `riskPolicy=balanced: capability '${reason.capability}' status unknown — proceeding with warning`,
41
+ };
42
+ }
43
+ return { disposition: 'block', reason };
44
+ case 'aggressive':
45
+ if (reason.kind === 'required_capability_unknown' || reason.kind === 'required_capability_unavailable') {
46
+ return {
47
+ disposition: 'downgrade_to_warning',
48
+ reason,
49
+ rationale: `riskPolicy=aggressive: capability '${reason.capability}' issue downgraded to warning`,
50
+ };
51
+ }
52
+ return { disposition: 'block', reason };
53
+ default: {
54
+ const _exhaustive = policy;
55
+ return _exhaustive;
56
+ }
57
+ }
58
+ }
59
+ function applyGuardrails(policy, reasons) {
60
+ const blocking = [];
61
+ const downgraded = [];
62
+ for (const reason of reasons) {
63
+ const outcome = applyGuardrail(policy, reason);
64
+ switch (outcome.disposition) {
65
+ case 'block':
66
+ blocking.push(outcome.reason);
67
+ break;
68
+ case 'downgrade_to_warning':
69
+ downgraded.push(outcome);
70
+ break;
71
+ default: {
72
+ const _exhaustive = outcome;
73
+ return _exhaustive;
74
+ }
75
+ }
76
+ }
77
+ return { blocking, downgraded };
78
+ }
@@ -0,0 +1,16 @@
1
+ import type { ValidationCriteria, ValidationResult } from '../../../types/validation.js';
2
+ import type { OutputContract } from '../../../types/workflow-definition.js';
3
+ import type { OutputRequirementStatus } from './blocking-decision.js';
4
+ export declare const VALIDATION_CRITERIA_CONTRACT_REF: "wr.validationCriteria";
5
+ export declare function getOutputRequirementStatusV1(args: {
6
+ readonly validationCriteria: ValidationCriteria | undefined;
7
+ readonly notesMarkdown: string | undefined;
8
+ readonly validation: ValidationResult | undefined;
9
+ }): OutputRequirementStatus;
10
+ export declare function getOutputRequirementStatusWithArtifactsV1(args: {
11
+ readonly outputContract: OutputContract | undefined;
12
+ readonly artifacts: readonly unknown[];
13
+ readonly validationCriteria: ValidationCriteria | undefined;
14
+ readonly notesMarkdown: string | undefined;
15
+ readonly validation: ValidationResult | undefined;
16
+ }): OutputRequirementStatus;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VALIDATION_CRITERIA_CONTRACT_REF = void 0;
4
+ exports.getOutputRequirementStatusV1 = getOutputRequirementStatusV1;
5
+ exports.getOutputRequirementStatusWithArtifactsV1 = getOutputRequirementStatusWithArtifactsV1;
6
+ const artifact_contract_validator_js_1 = require("./artifact-contract-validator.js");
7
+ exports.VALIDATION_CRITERIA_CONTRACT_REF = 'wr.validationCriteria';
8
+ function getOutputRequirementStatusV1(args) {
9
+ if (!args.validationCriteria)
10
+ return { kind: 'not_required' };
11
+ if (!args.notesMarkdown) {
12
+ return { kind: 'missing', contractRef: exports.VALIDATION_CRITERIA_CONTRACT_REF };
13
+ }
14
+ if (args.validation && !args.validation.valid) {
15
+ return { kind: 'invalid', contractRef: exports.VALIDATION_CRITERIA_CONTRACT_REF, validation: args.validation };
16
+ }
17
+ return { kind: 'not_required' };
18
+ }
19
+ function getOutputRequirementStatusWithArtifactsV1(args) {
20
+ if (args.outputContract) {
21
+ const result = (0, artifact_contract_validator_js_1.validateArtifactContract)(args.artifacts, args.outputContract);
22
+ if (!result.valid) {
23
+ const error = result.error;
24
+ if (error.code === 'MISSING_REQUIRED_ARTIFACT') {
25
+ return { kind: 'missing', contractRef: error.contractRef };
26
+ }
27
+ if (error.code === 'INVALID_ARTIFACT_SCHEMA') {
28
+ const validationResult = {
29
+ valid: false,
30
+ issues: error.issues.map(issue => issue),
31
+ suggestions: ['Provide a valid artifact matching the contract schema'],
32
+ };
33
+ return { kind: 'invalid', contractRef: error.contractRef, validation: validationResult };
34
+ }
35
+ if (error.code === 'UNKNOWN_CONTRACT_REF') {
36
+ return { kind: 'missing', contractRef: error.contractRef };
37
+ }
38
+ }
39
+ return { kind: 'not_required' };
40
+ }
41
+ return getOutputRequirementStatusV1({
42
+ validationCriteria: args.validationCriteria,
43
+ notesMarkdown: args.notesMarkdown,
44
+ validation: args.validation,
45
+ });
46
+ }
@@ -0,0 +1,26 @@
1
+ import { type Result } from 'neverthrow';
2
+ import type { ValidationResult } from '../../../types/validation.js';
3
+ import type { DomainEventV1 } from '../schemas/session/index.js';
4
+ type EventToAppendV1 = Omit<DomainEventV1, 'eventIndex' | 'sessionId'>;
5
+ export type ValidationEventError = {
6
+ readonly code: 'VALIDATION_EVENT_INVARIANT_VIOLATION';
7
+ readonly message: string;
8
+ } | {
9
+ readonly code: 'VALIDATION_EVENT_TEXT_TOO_LARGE';
10
+ readonly message: string;
11
+ };
12
+ export declare function buildValidationPerformedEvent(args: {
13
+ readonly sessionId: string;
14
+ readonly validationId: string;
15
+ readonly attemptId: string;
16
+ readonly contractRef: string;
17
+ readonly result: ValidationResult;
18
+ readonly scope: {
19
+ readonly runId: string;
20
+ readonly nodeId: string;
21
+ };
22
+ readonly minted: {
23
+ readonly eventId: string;
24
+ };
25
+ }): Result<EventToAppendV1, ValidationEventError>;
26
+ export {};
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildValidationPerformedEvent = buildValidationPerformedEvent;
4
+ const neverthrow_1 = require("neverthrow");
5
+ const constants_js_1 = require("../constants.js");
6
+ function utf8ByteLength(s) {
7
+ return new TextEncoder().encode(s).length;
8
+ }
9
+ function uniqueSorted(values) {
10
+ const sorted = [...values].filter((v) => v.length > 0).sort((a, b) => a.localeCompare(b, 'en-US'));
11
+ const out = [];
12
+ for (const v of sorted) {
13
+ if (out.length === 0 || out[out.length - 1] !== v)
14
+ out.push(v);
15
+ }
16
+ return out;
17
+ }
18
+ const VALIDATION_TRUNCATION_ITEM = '[TRUNCATED]';
19
+ function truncateListToUtf8ByteBudget(args) {
20
+ if (args.maxBytes <= 0) {
21
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'maxBytes must be positive' });
22
+ }
23
+ const markerBytes = args.includeTruncationMarker ? utf8ByteLength(VALIDATION_TRUNCATION_ITEM) : 0;
24
+ if (args.includeTruncationMarker && markerBytes > args.maxBytes) {
25
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_TEXT_TOO_LARGE', message: 'validation truncation marker does not fit budget' });
26
+ }
27
+ const values = uniqueSorted(args.values);
28
+ const out = [];
29
+ let used = 0;
30
+ for (const v of values) {
31
+ const bytes = utf8ByteLength(v);
32
+ if (bytes > args.maxBytes) {
33
+ return (0, neverthrow_1.err)({
34
+ code: 'VALIDATION_EVENT_TEXT_TOO_LARGE',
35
+ message: 'validation item exceeds max bytes budget',
36
+ });
37
+ }
38
+ const remainingBudget = args.maxBytes - used;
39
+ const reserve = args.includeTruncationMarker ? markerBytes : 0;
40
+ const canFitWithReserve = bytes <= remainingBudget - reserve;
41
+ if (!canFitWithReserve) {
42
+ if (args.includeTruncationMarker) {
43
+ if (used + markerBytes <= args.maxBytes)
44
+ out.push(VALIDATION_TRUNCATION_ITEM);
45
+ }
46
+ return (0, neverthrow_1.ok)(out);
47
+ }
48
+ out.push(v);
49
+ used += bytes;
50
+ }
51
+ return (0, neverthrow_1.ok)(out);
52
+ }
53
+ function buildValidationPerformedEvent(args) {
54
+ if (!args.sessionId)
55
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'sessionId is required' });
56
+ if (!args.validationId)
57
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'validationId is required' });
58
+ if (!args.attemptId)
59
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'attemptId is required' });
60
+ if (!args.contractRef)
61
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'contractRef is required' });
62
+ if (!args.scope.runId || !args.scope.nodeId) {
63
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'scope.runId and scope.nodeId are required' });
64
+ }
65
+ if (!args.minted.eventId)
66
+ return (0, neverthrow_1.err)({ code: 'VALIDATION_EVENT_INVARIANT_VIOLATION', message: 'minted.eventId is required' });
67
+ const issuesRes = truncateListToUtf8ByteBudget({
68
+ values: args.result.issues ?? [],
69
+ maxBytes: constants_js_1.MAX_VALIDATION_ISSUES_BYTES,
70
+ includeTruncationMarker: true,
71
+ });
72
+ if (issuesRes.isErr())
73
+ return (0, neverthrow_1.err)(issuesRes.error);
74
+ const suggestionsRes = truncateListToUtf8ByteBudget({
75
+ values: args.result.suggestions ?? [],
76
+ maxBytes: constants_js_1.MAX_VALIDATION_SUGGESTIONS_BYTES,
77
+ includeTruncationMarker: true,
78
+ });
79
+ if (suggestionsRes.isErr())
80
+ return (0, neverthrow_1.err)(suggestionsRes.error);
81
+ const dedupeKey = `validation_performed:${args.sessionId}:${args.attemptId}`;
82
+ const event = {
83
+ v: 1,
84
+ eventId: args.minted.eventId,
85
+ kind: 'validation_performed',
86
+ dedupeKey: dedupeKey,
87
+ scope: { runId: args.scope.runId, nodeId: args.scope.nodeId },
88
+ data: {
89
+ validationId: args.validationId,
90
+ attemptId: args.attemptId,
91
+ contractRef: args.contractRef,
92
+ result: {
93
+ valid: args.result.valid,
94
+ issues: issuesRes.value,
95
+ suggestions: suggestionsRes.value,
96
+ },
97
+ },
98
+ };
99
+ return (0, neverthrow_1.ok)(event);
100
+ }
@@ -0,0 +1,11 @@
1
+ import { type Result } from 'neverthrow';
2
+ import type { DomainEventV1 } from '../schemas/session/index.js';
3
+ export type ValidationLoadError = {
4
+ readonly code: 'VALIDATION_LOAD_INVARIANT_VIOLATION';
5
+ readonly message: string;
6
+ };
7
+ export type LoadedValidationV1 = {
8
+ readonly issues: readonly string[];
9
+ readonly suggestions: readonly string[];
10
+ };
11
+ export declare function loadValidationResultV1(events: readonly DomainEventV1[], validationId: string): Result<LoadedValidationV1 | null, ValidationLoadError>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadValidationResultV1 = loadValidationResultV1;
4
+ const neverthrow_1 = require("neverthrow");
5
+ function loadValidationResultV1(events, validationId) {
6
+ if (!validationId) {
7
+ return (0, neverthrow_1.ok)(null);
8
+ }
9
+ let latest = null;
10
+ for (const e of events) {
11
+ if (e.kind !== 'validation_performed')
12
+ continue;
13
+ if (e.data.validationId !== validationId)
14
+ continue;
15
+ if (!latest || e.eventIndex > latest.eventIndex)
16
+ latest = e;
17
+ }
18
+ if (!latest)
19
+ return (0, neverthrow_1.ok)(null);
20
+ return (0, neverthrow_1.ok)({ issues: latest.data.result.issues, suggestions: latest.data.result.suggestions });
21
+ }
@@ -0,0 +1,2 @@
1
+ import type { ValidationCriteria } from '../../../types/validation.js';
2
+ export declare function extractValidationRequirements(criteria: ValidationCriteria | undefined): readonly string[];
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractValidationRequirements = extractValidationRequirements;
4
+ const validation_js_1 = require("../../../types/validation.js");
5
+ function extractValidationRequirements(criteria) {
6
+ if (!criteria)
7
+ return [];
8
+ try {
9
+ const requirements = extractRequirementsRecursive(criteria);
10
+ return requirements.slice(0, 5);
11
+ }
12
+ catch {
13
+ return [];
14
+ }
15
+ }
16
+ function extractRequirementsRecursive(criteria) {
17
+ const requirements = [];
18
+ if ((0, validation_js_1.isValidationRule)(criteria)) {
19
+ const formatted = formatRule(criteria);
20
+ if (formatted)
21
+ requirements.push(formatted);
22
+ return requirements;
23
+ }
24
+ if ((0, validation_js_1.isValidationComposition)(criteria)) {
25
+ if (criteria.and) {
26
+ for (const sub of criteria.and) {
27
+ requirements.push(...extractRequirementsRecursive(sub));
28
+ }
29
+ }
30
+ }
31
+ return requirements;
32
+ }
33
+ function formatRule(rule) {
34
+ switch (rule.type) {
35
+ case 'contains':
36
+ if (!rule.value)
37
+ return null;
38
+ return `Must contain: "${rule.value}"`;
39
+ case 'regex':
40
+ if (!rule.pattern)
41
+ return null;
42
+ const flags = rule.flags ? ` (flags: ${rule.flags})` : '';
43
+ return `Must match pattern: ${rule.pattern}${flags}`;
44
+ case 'length':
45
+ const parts = [];
46
+ if (rule.min !== undefined)
47
+ parts.push(`≥${rule.min} chars`);
48
+ if (rule.max !== undefined)
49
+ parts.push(`≤${rule.max} chars`);
50
+ if (parts.length === 0)
51
+ return null;
52
+ return `Length: ${parts.join(', ')}`;
53
+ case 'schema':
54
+ return null;
55
+ default:
56
+ return null;
57
+ }
58
+ }
@@ -6,7 +6,7 @@ function deriveIsComplete(state) {
6
6
  return state.kind === 'complete';
7
7
  }
8
8
  function derivePendingStep(state) {
9
- if (state.kind !== 'running')
9
+ if (state.kind !== 'running' && state.kind !== 'blocked')
10
10
  return null;
11
11
  if (state.pending.kind !== 'some')
12
12
  return null;
@@ -0,0 +1,4 @@
1
+ export { LOOP_CONTROL_CONTRACT_REF, LoopControlDecisionSchema, LoopControlMetadataV1Schema, LoopControlArtifactV1Schema, isLoopControlArtifact, parseLoopControlArtifact, findLoopControlArtifact, type LoopControlDecision, type LoopControlMetadataV1, type LoopControlArtifactV1, } from './loop-control.js';
2
+ export declare const ARTIFACT_CONTRACT_REFS: readonly ["wr.contracts.loop_control"];
3
+ export type ArtifactContractRef = (typeof ARTIFACT_CONTRACT_REFS)[number];
4
+ export declare function isValidContractRef(ref: string): ref is ArtifactContractRef;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ARTIFACT_CONTRACT_REFS = exports.findLoopControlArtifact = exports.parseLoopControlArtifact = exports.isLoopControlArtifact = exports.LoopControlArtifactV1Schema = exports.LoopControlMetadataV1Schema = exports.LoopControlDecisionSchema = exports.LOOP_CONTROL_CONTRACT_REF = void 0;
4
+ exports.isValidContractRef = isValidContractRef;
5
+ var loop_control_js_1 = require("./loop-control.js");
6
+ Object.defineProperty(exports, "LOOP_CONTROL_CONTRACT_REF", { enumerable: true, get: function () { return loop_control_js_1.LOOP_CONTROL_CONTRACT_REF; } });
7
+ Object.defineProperty(exports, "LoopControlDecisionSchema", { enumerable: true, get: function () { return loop_control_js_1.LoopControlDecisionSchema; } });
8
+ Object.defineProperty(exports, "LoopControlMetadataV1Schema", { enumerable: true, get: function () { return loop_control_js_1.LoopControlMetadataV1Schema; } });
9
+ Object.defineProperty(exports, "LoopControlArtifactV1Schema", { enumerable: true, get: function () { return loop_control_js_1.LoopControlArtifactV1Schema; } });
10
+ Object.defineProperty(exports, "isLoopControlArtifact", { enumerable: true, get: function () { return loop_control_js_1.isLoopControlArtifact; } });
11
+ Object.defineProperty(exports, "parseLoopControlArtifact", { enumerable: true, get: function () { return loop_control_js_1.parseLoopControlArtifact; } });
12
+ Object.defineProperty(exports, "findLoopControlArtifact", { enumerable: true, get: function () { return loop_control_js_1.findLoopControlArtifact; } });
13
+ exports.ARTIFACT_CONTRACT_REFS = [
14
+ 'wr.contracts.loop_control',
15
+ ];
16
+ function isValidContractRef(ref) {
17
+ return exports.ARTIFACT_CONTRACT_REFS.includes(ref);
18
+ }
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ export declare const LOOP_CONTROL_CONTRACT_REF: "wr.contracts.loop_control";
3
+ export declare const LoopControlDecisionSchema: z.ZodEnum<["continue", "stop"]>;
4
+ export type LoopControlDecision = z.infer<typeof LoopControlDecisionSchema>;
5
+ export declare const LoopControlMetadataV1Schema: z.ZodOptional<z.ZodObject<{
6
+ reason: z.ZodOptional<z.ZodString>;
7
+ issuesFound: z.ZodOptional<z.ZodNumber>;
8
+ iterationIndex: z.ZodOptional<z.ZodNumber>;
9
+ confidence: z.ZodOptional<z.ZodNumber>;
10
+ }, "strict", z.ZodTypeAny, {
11
+ confidence?: number | undefined;
12
+ reason?: string | undefined;
13
+ issuesFound?: number | undefined;
14
+ iterationIndex?: number | undefined;
15
+ }, {
16
+ confidence?: number | undefined;
17
+ reason?: string | undefined;
18
+ issuesFound?: number | undefined;
19
+ iterationIndex?: number | undefined;
20
+ }>>;
21
+ export type LoopControlMetadataV1 = z.infer<typeof LoopControlMetadataV1Schema>;
22
+ export declare const LoopControlArtifactV1Schema: z.ZodObject<{
23
+ kind: z.ZodLiteral<"wr.loop_control">;
24
+ loopId: z.ZodString;
25
+ decision: z.ZodEnum<["continue", "stop"]>;
26
+ metadata: z.ZodOptional<z.ZodObject<{
27
+ reason: z.ZodOptional<z.ZodString>;
28
+ issuesFound: z.ZodOptional<z.ZodNumber>;
29
+ iterationIndex: z.ZodOptional<z.ZodNumber>;
30
+ confidence: z.ZodOptional<z.ZodNumber>;
31
+ }, "strict", z.ZodTypeAny, {
32
+ confidence?: number | undefined;
33
+ reason?: string | undefined;
34
+ issuesFound?: number | undefined;
35
+ iterationIndex?: number | undefined;
36
+ }, {
37
+ confidence?: number | undefined;
38
+ reason?: string | undefined;
39
+ issuesFound?: number | undefined;
40
+ iterationIndex?: number | undefined;
41
+ }>>;
42
+ }, "strict", z.ZodTypeAny, {
43
+ kind: "wr.loop_control";
44
+ loopId: string;
45
+ decision: "continue" | "stop";
46
+ metadata?: {
47
+ confidence?: number | undefined;
48
+ reason?: string | undefined;
49
+ issuesFound?: number | undefined;
50
+ iterationIndex?: number | undefined;
51
+ } | undefined;
52
+ }, {
53
+ kind: "wr.loop_control";
54
+ loopId: string;
55
+ decision: "continue" | "stop";
56
+ metadata?: {
57
+ confidence?: number | undefined;
58
+ reason?: string | undefined;
59
+ issuesFound?: number | undefined;
60
+ iterationIndex?: number | undefined;
61
+ } | undefined;
62
+ }>;
63
+ export type LoopControlArtifactV1 = z.infer<typeof LoopControlArtifactV1Schema>;
64
+ export declare function isLoopControlArtifact(artifact: unknown): artifact is LoopControlArtifactV1;
65
+ export declare function parseLoopControlArtifact(artifact: unknown): LoopControlArtifactV1 | null;
66
+ export declare function findLoopControlArtifact(artifacts: readonly unknown[], loopId: string): LoopControlArtifactV1 | null;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LoopControlArtifactV1Schema = exports.LoopControlMetadataV1Schema = exports.LoopControlDecisionSchema = exports.LOOP_CONTROL_CONTRACT_REF = void 0;
4
+ exports.isLoopControlArtifact = isLoopControlArtifact;
5
+ exports.parseLoopControlArtifact = parseLoopControlArtifact;
6
+ exports.findLoopControlArtifact = findLoopControlArtifact;
7
+ const zod_1 = require("zod");
8
+ const constants_js_1 = require("../../constants.js");
9
+ exports.LOOP_CONTROL_CONTRACT_REF = 'wr.contracts.loop_control';
10
+ exports.LoopControlDecisionSchema = zod_1.z.enum(['continue', 'stop']);
11
+ exports.LoopControlMetadataV1Schema = zod_1.z
12
+ .object({
13
+ reason: zod_1.z.string().max(1024).optional(),
14
+ issuesFound: zod_1.z.number().int().nonnegative().optional(),
15
+ iterationIndex: zod_1.z.number().int().nonnegative().optional(),
16
+ confidence: zod_1.z.number().int().min(0).max(100).optional(),
17
+ })
18
+ .strict()
19
+ .optional();
20
+ exports.LoopControlArtifactV1Schema = zod_1.z
21
+ .object({
22
+ kind: zod_1.z.literal('wr.loop_control'),
23
+ loopId: zod_1.z.string().min(1).max(64).regex(constants_js_1.DELIMITER_SAFE_ID_PATTERN, 'loopId must be delimiter-safe: [a-z0-9_-]+'),
24
+ decision: exports.LoopControlDecisionSchema,
25
+ metadata: exports.LoopControlMetadataV1Schema,
26
+ })
27
+ .strict();
28
+ function isLoopControlArtifact(artifact) {
29
+ if (typeof artifact !== 'object' || artifact === null)
30
+ return false;
31
+ return artifact.kind === 'wr.loop_control';
32
+ }
33
+ function parseLoopControlArtifact(artifact) {
34
+ const result = exports.LoopControlArtifactV1Schema.safeParse(artifact);
35
+ return result.success ? result.data : null;
36
+ }
37
+ function findLoopControlArtifact(artifacts, loopId) {
38
+ for (const artifact of artifacts) {
39
+ if (!isLoopControlArtifact(artifact))
40
+ continue;
41
+ const parsed = parseLoopControlArtifact(artifact);
42
+ if (parsed && parsed.loopId === loopId) {
43
+ return parsed;
44
+ }
45
+ }
46
+ return null;
47
+ }