@exaudeus/workrail 3.75.0 → 3.77.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 (95) hide show
  1. package/dist/console-ui/assets/index-D9pYbwS0.js +28 -0
  2. package/dist/console-ui/index.html +1 -1
  3. package/dist/coordinators/adaptive-pipeline.d.ts +8 -0
  4. package/dist/coordinators/context-assembly.d.ts +4 -0
  5. package/dist/coordinators/context-assembly.js +156 -0
  6. package/dist/coordinators/modes/full-pipeline.d.ts +1 -1
  7. package/dist/coordinators/modes/full-pipeline.js +140 -27
  8. package/dist/coordinators/modes/implement-shared.d.ts +3 -2
  9. package/dist/coordinators/modes/implement-shared.js +16 -6
  10. package/dist/coordinators/modes/implement.js +49 -3
  11. package/dist/coordinators/pipeline-run-context.d.ts +1811 -0
  12. package/dist/coordinators/pipeline-run-context.js +114 -0
  13. package/dist/daemon/context-loader.d.ts +1 -1
  14. package/dist/daemon/core/agent-client.d.ts +7 -0
  15. package/dist/daemon/core/agent-client.js +31 -0
  16. package/dist/daemon/core/index.d.ts +6 -0
  17. package/dist/daemon/core/index.js +19 -0
  18. package/dist/daemon/core/session-context.d.ts +14 -0
  19. package/dist/daemon/core/session-context.js +24 -0
  20. package/dist/daemon/core/session-result.d.ts +10 -0
  21. package/dist/daemon/core/session-result.js +92 -0
  22. package/dist/daemon/core/system-prompt.d.ts +6 -0
  23. package/dist/daemon/core/system-prompt.js +151 -0
  24. package/dist/daemon/io/conversation-log.d.ts +2 -0
  25. package/dist/daemon/io/conversation-log.js +45 -0
  26. package/dist/daemon/io/execution-stats.d.ts +7 -0
  27. package/dist/daemon/io/execution-stats.js +86 -0
  28. package/dist/daemon/io/index.d.ts +5 -0
  29. package/dist/daemon/io/index.js +24 -0
  30. package/dist/daemon/io/session-notes-loader.d.ts +4 -0
  31. package/dist/daemon/io/session-notes-loader.js +45 -0
  32. package/dist/daemon/io/soul-loader.d.ts +3 -0
  33. package/dist/daemon/io/soul-loader.js +68 -0
  34. package/dist/daemon/io/workspace-context-loader.d.ts +17 -0
  35. package/dist/daemon/io/workspace-context-loader.js +137 -0
  36. package/dist/daemon/runner/agent-loop-runner.d.ts +28 -0
  37. package/dist/daemon/runner/agent-loop-runner.js +250 -0
  38. package/dist/daemon/runner/construct-tools.d.ts +5 -0
  39. package/dist/daemon/runner/construct-tools.js +30 -0
  40. package/dist/daemon/runner/finalize-session.d.ts +3 -0
  41. package/dist/daemon/runner/finalize-session.js +75 -0
  42. package/dist/daemon/runner/index.d.ts +8 -0
  43. package/dist/daemon/runner/index.js +18 -0
  44. package/dist/daemon/runner/pre-agent-session.d.ts +7 -0
  45. package/dist/daemon/runner/pre-agent-session.js +227 -0
  46. package/dist/daemon/runner/runner-types.d.ts +73 -0
  47. package/dist/daemon/runner/runner-types.js +39 -0
  48. package/dist/daemon/runner/tool-schemas.d.ts +1 -0
  49. package/dist/daemon/runner/tool-schemas.js +151 -0
  50. package/dist/daemon/session-scope.d.ts +1 -1
  51. package/dist/daemon/startup-recovery.d.ts +20 -0
  52. package/dist/daemon/startup-recovery.js +323 -0
  53. package/dist/daemon/state/index.d.ts +6 -0
  54. package/dist/daemon/state/index.js +14 -0
  55. package/dist/daemon/state/session-state.d.ts +23 -0
  56. package/dist/daemon/state/session-state.js +44 -0
  57. package/dist/daemon/state/stuck-detection.d.ts +22 -0
  58. package/dist/daemon/state/stuck-detection.js +25 -0
  59. package/dist/daemon/state/terminal-signal.d.ts +9 -0
  60. package/dist/daemon/state/terminal-signal.js +10 -0
  61. package/dist/daemon/tools/file-tools.d.ts +1 -1
  62. package/dist/daemon/turn-end/detect-stuck.d.ts +2 -2
  63. package/dist/daemon/turn-end/detect-stuck.js +2 -2
  64. package/dist/daemon/turn-end/step-injector.d.ts +1 -1
  65. package/dist/daemon/types.d.ts +105 -0
  66. package/dist/daemon/types.js +11 -0
  67. package/dist/daemon/workflow-enricher.d.ts +16 -0
  68. package/dist/daemon/workflow-enricher.js +58 -0
  69. package/dist/daemon/workflow-runner.d.ts +13 -277
  70. package/dist/daemon/workflow-runner.js +63 -1421
  71. package/dist/manifest.json +280 -56
  72. package/dist/trigger/coordinator-deps.d.ts +1 -1
  73. package/dist/trigger/coordinator-deps.js +131 -0
  74. package/dist/trigger/delivery-client.d.ts +1 -1
  75. package/dist/trigger/delivery-pipeline.d.ts +1 -1
  76. package/dist/trigger/notification-service.d.ts +1 -1
  77. package/dist/trigger/trigger-listener.js +6 -2
  78. package/dist/trigger/trigger-router.d.ts +2 -2
  79. package/dist/v2/durable-core/domain/artifact-contract-validator.js +99 -0
  80. package/dist/v2/durable-core/schemas/artifacts/discovery-handoff.d.ts +39 -0
  81. package/dist/v2/durable-core/schemas/artifacts/discovery-handoff.js +10 -1
  82. package/dist/v2/durable-core/schemas/artifacts/index.d.ts +2 -1
  83. package/dist/v2/durable-core/schemas/artifacts/index.js +12 -1
  84. package/dist/v2/durable-core/schemas/artifacts/phase-handoff.d.ts +89 -0
  85. package/dist/v2/durable-core/schemas/artifacts/phase-handoff.js +56 -0
  86. package/docs/authoring-v2.md +12 -0
  87. package/docs/ideas/backlog.md +639 -25
  88. package/docs/reference/worktrain-daemon-invariants.md +33 -49
  89. package/docs/vision.md +5 -15
  90. package/package.json +2 -2
  91. package/workflows/coding-task-workflow-agentic.json +9 -6
  92. package/workflows/mr-review-workflow.agentic.v2.json +2 -2
  93. package/workflows/wr.discovery.json +2 -1
  94. package/workflows/wr.shaping.json +7 -4
  95. package/dist/console-ui/assets/index-BvBihscd.js +0 -28
@@ -1,4 +1,4 @@
1
- import type { WorkflowRunSuccess } from '../daemon/workflow-runner.js';
1
+ import type { WorkflowRunSuccess } from '../daemon/types.js';
2
2
  import type { TriggerDefinition } from './types.js';
3
3
  import type { ExecFn, HandoffArtifact } from './delivery-action.js';
4
4
  import type { ExecutionSessionGateV2 } from '../v2/usecases/execution-session-gate.js';
@@ -1,4 +1,4 @@
1
- import type { WorkflowRunResult } from '../daemon/workflow-runner.js';
1
+ import type { WorkflowRunResult } from '../daemon/types.js';
2
2
  export type ExecFileNotifyFn = (file: string, args: readonly string[], options: {
3
3
  timeout: number;
4
4
  }, callback: (error: Error | null) => void) => void;
@@ -49,6 +49,8 @@ const active_sessions_js_1 = require("../daemon/active-sessions.js");
49
49
  const config_file_js_1 = require("../config/config-file.js");
50
50
  const notification_service_js_1 = require("./notification-service.js");
51
51
  const workflow_runner_js_1 = require("../daemon/workflow-runner.js");
52
+ const workflow_enricher_js_1 = require("../daemon/workflow-enricher.js");
53
+ const startup_recovery_js_1 = require("../daemon/startup-recovery.js");
52
54
  const types_js_1 = require("./types.js");
53
55
  const polling_scheduler_js_1 = require("./polling-scheduler.js");
54
56
  const polled_event_store_js_1 = require("./polled-event-store.js");
@@ -226,7 +228,9 @@ async function startTriggerListener(ctx, options) {
226
228
  runImplement: implement_js_1.runImplementPipeline,
227
229
  runFull: full_pipeline_js_1.runFullPipeline,
228
230
  };
229
- const runWorkflowFn = options.runWorkflowFn ?? workflow_runner_js_1.runWorkflow;
231
+ const enricherDeps = (0, workflow_enricher_js_1.createWorkflowEnricherDeps)();
232
+ const baseRunWorkflow = options.runWorkflowFn ?? workflow_runner_js_1.runWorkflow;
233
+ const runWorkflowFn = (trigger, ctx, apiKey, daemonRegistry, emitter, activeSessionSet, _statsDir, _sessionsDir, source) => baseRunWorkflow(trigger, ctx, apiKey, daemonRegistry, emitter, activeSessionSet, _statsDir, _sessionsDir, source, enricherDeps);
230
234
  const router = new trigger_router_js_1.TriggerRouter(triggerIndex, ctx, apiKey, runWorkflowFn, undefined, maxConcurrentSessions, options.emitter, notificationService, activeSessionSet, coordinatorDeps, modeExecutors);
231
235
  coordinatorDeps.setDispatch(router.dispatch.bind(router));
232
236
  const app = createTriggerApp(router);
@@ -234,7 +238,7 @@ async function startTriggerListener(ctx, options) {
234
238
  const polledEventStore = new polled_event_store_js_1.PolledEventStore(env);
235
239
  const pollingScheduler = new polling_scheduler_js_1.PollingScheduler(allTriggers, router, polledEventStore, options.fetchFn);
236
240
  pollingScheduler.start();
237
- await (0, workflow_runner_js_1.runStartupRecovery)(undefined, undefined, ctx, undefined, undefined, undefined, apiKey).catch((err) => {
241
+ await (0, startup_recovery_js_1.runStartupRecovery)(undefined, undefined, ctx, undefined, undefined, runWorkflowFn, apiKey).catch((err) => {
238
242
  console.warn('[TriggerListener] Startup recovery encountered an unexpected error:', err instanceof Error ? err.message : String(err));
239
243
  });
240
244
  const portEnv = env['WORKRAIL_TRIGGER_PORT'];
@@ -1,4 +1,4 @@
1
- import type { WorkflowTrigger, WorkflowRunResult, SessionSource } from '../daemon/workflow-runner.js';
1
+ import type { WorkflowTrigger, WorkflowRunResult, SessionSource } from '../daemon/types.js';
2
2
  import type { ActiveSessionSet } from '../daemon/active-sessions.js';
3
3
  import type { V2ToolContext } from '../mcp/types.js';
4
4
  import type { TriggerDefinition, WebhookEvent } from './types.js';
@@ -30,7 +30,7 @@ export type RouteResult = {
30
30
  readonly _tag: 'error';
31
31
  readonly error: RouteError;
32
32
  };
33
- export type RunWorkflowFn = (trigger: WorkflowTrigger, ctx: V2ToolContext, apiKey: string, daemonRegistry?: import('../v2/infra/in-memory/daemon-registry/index.js').DaemonRegistry, emitter?: DaemonEventEmitter, activeSessionSet?: ActiveSessionSet, _statsDir?: string, _sessionsDir?: string, source?: SessionSource) => Promise<WorkflowRunResult>;
33
+ export type RunWorkflowFn = (trigger: WorkflowTrigger, ctx: V2ToolContext, apiKey: string, daemonRegistry?: import('../v2/infra/in-memory/daemon-registry/index.js').DaemonRegistry, emitter?: DaemonEventEmitter, activeSessionSet?: ActiveSessionSet, _statsDir?: string, _sessionsDir?: string, source?: SessionSource, enricherDeps?: import('../daemon/workflow-enricher.js').WorkflowEnricherDeps) => Promise<WorkflowRunResult>;
34
34
  export declare function interpolateGoalTemplate(template: string, staticGoal: string, payload: Readonly<Record<string, unknown>>, triggerId: string): string;
35
35
  export declare class TriggerRouter {
36
36
  private readonly index;
@@ -25,6 +25,12 @@ function validateArtifactContract(artifacts, contract) {
25
25
  return validateCoordinatorSignalContract(artifacts, contractRef, required);
26
26
  case index_js_1.REVIEW_VERDICT_CONTRACT_REF:
27
27
  return validateReviewVerdictContract(artifacts, contractRef, required);
28
+ case index_js_1.DISCOVERY_HANDOFF_CONTRACT_REF:
29
+ return validateDiscoveryHandoffContract(artifacts, contractRef, required);
30
+ case index_js_1.SHAPING_HANDOFF_CONTRACT_REF:
31
+ return validateShapingHandoffContract(artifacts, contractRef, required);
32
+ case index_js_1.CODING_HANDOFF_CONTRACT_REF:
33
+ return validateCodingHandoffContract(artifacts, contractRef, required);
28
34
  default:
29
35
  return {
30
36
  valid: false,
@@ -129,6 +135,99 @@ function validateReviewVerdictContract(artifacts, contractRef, required) {
129
135
  }
130
136
  return { valid: true, artifact: parseResult.data };
131
137
  }
138
+ function validateDiscoveryHandoffContract(artifacts, contractRef, required) {
139
+ const handoffArtifacts = artifacts.filter(index_js_1.isDiscoveryHandoffArtifact);
140
+ if (handoffArtifacts.length === 0) {
141
+ if (required) {
142
+ return {
143
+ valid: false,
144
+ error: {
145
+ code: 'MISSING_REQUIRED_ARTIFACT',
146
+ contractRef,
147
+ message: `Required artifact missing: ${contractRef}. Agent must provide an artifact with kind='wr.discovery_handoff'.`,
148
+ },
149
+ };
150
+ }
151
+ return { valid: true, artifact: null };
152
+ }
153
+ const artifact = handoffArtifacts[0];
154
+ const parseResult = index_js_1.DiscoveryHandoffArtifactV1Schema.safeParse(artifact);
155
+ if (!parseResult.success) {
156
+ const issues = parseResult.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`);
157
+ return {
158
+ valid: false,
159
+ error: {
160
+ code: 'INVALID_ARTIFACT_SCHEMA',
161
+ contractRef,
162
+ message: `Artifact schema validation failed for ${contractRef}`,
163
+ issues,
164
+ },
165
+ };
166
+ }
167
+ return { valid: true, artifact: parseResult.data };
168
+ }
169
+ function validateShapingHandoffContract(artifacts, contractRef, required) {
170
+ const handoffArtifacts = artifacts.filter(index_js_1.isShapingHandoffArtifact);
171
+ if (handoffArtifacts.length === 0) {
172
+ if (required) {
173
+ return {
174
+ valid: false,
175
+ error: {
176
+ code: 'MISSING_REQUIRED_ARTIFACT',
177
+ contractRef,
178
+ message: `Required artifact missing: ${contractRef}. Agent must provide an artifact with kind='wr.shaping_handoff'.`,
179
+ },
180
+ };
181
+ }
182
+ return { valid: true, artifact: null };
183
+ }
184
+ const artifact = handoffArtifacts[0];
185
+ const parseResult = index_js_1.ShapingHandoffArtifactV1Schema.safeParse(artifact);
186
+ if (!parseResult.success) {
187
+ const issues = parseResult.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`);
188
+ return {
189
+ valid: false,
190
+ error: {
191
+ code: 'INVALID_ARTIFACT_SCHEMA',
192
+ contractRef,
193
+ message: `Artifact schema validation failed for ${contractRef}`,
194
+ issues,
195
+ },
196
+ };
197
+ }
198
+ return { valid: true, artifact: parseResult.data };
199
+ }
200
+ function validateCodingHandoffContract(artifacts, contractRef, required) {
201
+ const handoffArtifacts = artifacts.filter(index_js_1.isCodingHandoffArtifact);
202
+ if (handoffArtifacts.length === 0) {
203
+ if (required) {
204
+ return {
205
+ valid: false,
206
+ error: {
207
+ code: 'MISSING_REQUIRED_ARTIFACT',
208
+ contractRef,
209
+ message: `Required artifact missing: ${contractRef}. Agent must provide an artifact with kind='wr.coding_handoff'.`,
210
+ },
211
+ };
212
+ }
213
+ return { valid: true, artifact: null };
214
+ }
215
+ const artifact = handoffArtifacts[0];
216
+ const parseResult = index_js_1.CodingHandoffArtifactV1Schema.safeParse(artifact);
217
+ if (!parseResult.success) {
218
+ const issues = parseResult.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`);
219
+ return {
220
+ valid: false,
221
+ error: {
222
+ code: 'INVALID_ARTIFACT_SCHEMA',
223
+ contractRef,
224
+ message: `Artifact schema validation failed for ${contractRef}`,
225
+ issues,
226
+ },
227
+ };
228
+ }
229
+ return { valid: true, artifact: parseResult.data };
230
+ }
132
231
  function requiresArtifactValidation(outputContract) {
133
232
  if (!outputContract)
134
233
  return false;
@@ -7,6 +7,27 @@ export declare const DiscoveryHandoffArtifactV1Schema: z.ZodObject<{
7
7
  designDocPath: z.ZodString;
8
8
  confidenceBand: z.ZodEnum<["high", "medium", "low"]>;
9
9
  keyInvariants: z.ZodArray<z.ZodString, "many">;
10
+ rejectedDirections: z.ZodOptional<z.ZodArray<z.ZodObject<{
11
+ direction: z.ZodString;
12
+ reason: z.ZodString;
13
+ }, "strip", z.ZodTypeAny, {
14
+ reason: string;
15
+ direction: string;
16
+ }, {
17
+ reason: string;
18
+ direction: string;
19
+ }>, "many">>;
20
+ implementationConstraints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
+ keyCodebaseLocations: z.ZodOptional<z.ZodArray<z.ZodObject<{
22
+ path: z.ZodString;
23
+ relevance: z.ZodString;
24
+ }, "strip", z.ZodTypeAny, {
25
+ path: string;
26
+ relevance: string;
27
+ }, {
28
+ path: string;
29
+ relevance: string;
30
+ }>, "many">>;
10
31
  }, "strict", z.ZodTypeAny, {
11
32
  kind: "wr.discovery_handoff";
12
33
  version: 1;
@@ -14,6 +35,15 @@ export declare const DiscoveryHandoffArtifactV1Schema: z.ZodObject<{
14
35
  designDocPath: string;
15
36
  confidenceBand: "low" | "high" | "medium";
16
37
  keyInvariants: string[];
38
+ rejectedDirections?: {
39
+ reason: string;
40
+ direction: string;
41
+ }[] | undefined;
42
+ implementationConstraints?: string[] | undefined;
43
+ keyCodebaseLocations?: {
44
+ path: string;
45
+ relevance: string;
46
+ }[] | undefined;
17
47
  }, {
18
48
  kind: "wr.discovery_handoff";
19
49
  version: 1;
@@ -21,6 +51,15 @@ export declare const DiscoveryHandoffArtifactV1Schema: z.ZodObject<{
21
51
  designDocPath: string;
22
52
  confidenceBand: "low" | "high" | "medium";
23
53
  keyInvariants: string[];
54
+ rejectedDirections?: {
55
+ reason: string;
56
+ direction: string;
57
+ }[] | undefined;
58
+ implementationConstraints?: string[] | undefined;
59
+ keyCodebaseLocations?: {
60
+ path: string;
61
+ relevance: string;
62
+ }[] | undefined;
24
63
  }>;
25
64
  export type DiscoveryHandoffArtifactV1 = z.infer<typeof DiscoveryHandoffArtifactV1Schema>;
26
65
  export declare function isDiscoveryHandoffArtifact(artifact: unknown): artifact is {
@@ -12,7 +12,16 @@ exports.DiscoveryHandoffArtifactV1Schema = zod_1.z
12
12
  selectedDirection: zod_1.z.string().min(1),
13
13
  designDocPath: zod_1.z.string(),
14
14
  confidenceBand: zod_1.z.enum(['high', 'medium', 'low']),
15
- keyInvariants: zod_1.z.array(zod_1.z.string().min(1)),
15
+ keyInvariants: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(12),
16
+ rejectedDirections: zod_1.z.array(zod_1.z.object({
17
+ direction: zod_1.z.string().min(1).max(200),
18
+ reason: zod_1.z.string().min(1).max(300),
19
+ })).max(5).optional(),
20
+ implementationConstraints: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(8).optional(),
21
+ keyCodebaseLocations: zod_1.z.array(zod_1.z.object({
22
+ path: zod_1.z.string().min(1).max(300),
23
+ relevance: zod_1.z.string().min(1).max(150),
24
+ })).max(10).optional(),
16
25
  })
17
26
  .strict();
18
27
  function isDiscoveryHandoffArtifact(artifact) {
@@ -3,6 +3,7 @@ export { LOOP_CONTROL_CONTRACT_REF, LoopControlDecisionSchema, LoopControlMetada
3
3
  export { COORDINATOR_SIGNAL_CONTRACT_REF, CoordinatorSignalKindSchema, CoordinatorSignalArtifactV1Schema, isCoordinatorSignalArtifact, parseCoordinatorSignalArtifact, type CoordinatorSignalKind, type CoordinatorSignalArtifactV1, } from './coordinator-signal.js';
4
4
  export { REVIEW_VERDICT_CONTRACT_REF, ReviewVerdictArtifactV1Schema, isReviewVerdictArtifact, parseReviewVerdictArtifact, type ReviewVerdictArtifactV1, } from './review-verdict.js';
5
5
  export { DISCOVERY_HANDOFF_CONTRACT_REF, DiscoveryHandoffArtifactV1Schema, isDiscoveryHandoffArtifact, parseDiscoveryHandoffArtifact, type DiscoveryHandoffArtifactV1, } from './discovery-handoff.js';
6
- export declare const ARTIFACT_CONTRACT_REFS: readonly ["wr.contracts.assessment", "wr.contracts.loop_control", "wr.contracts.coordinator_signal", "wr.contracts.review_verdict", "wr.contracts.discovery_handoff"];
6
+ export { SHAPING_HANDOFF_CONTRACT_REF, ShapingHandoffArtifactV1Schema, isShapingHandoffArtifact, parseShapingHandoffArtifact, type ShapingHandoffArtifactV1, CODING_HANDOFF_CONTRACT_REF, CodingHandoffArtifactV1Schema, isCodingHandoffArtifact, parseCodingHandoffArtifact, type CodingHandoffArtifactV1, type PhaseHandoffArtifact, } from './phase-handoff.js';
7
+ export declare const ARTIFACT_CONTRACT_REFS: readonly ["wr.contracts.assessment", "wr.contracts.loop_control", "wr.contracts.coordinator_signal", "wr.contracts.review_verdict", "wr.contracts.discovery_handoff", "wr.contracts.shaping_handoff", "wr.contracts.coding_handoff"];
7
8
  export type ArtifactContractRef = (typeof ARTIFACT_CONTRACT_REFS)[number];
8
9
  export declare function isValidContractRef(ref: string): ref is ArtifactContractRef;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ARTIFACT_CONTRACT_REFS = exports.parseDiscoveryHandoffArtifact = exports.isDiscoveryHandoffArtifact = exports.DiscoveryHandoffArtifactV1Schema = exports.DISCOVERY_HANDOFF_CONTRACT_REF = exports.parseReviewVerdictArtifact = exports.isReviewVerdictArtifact = exports.ReviewVerdictArtifactV1Schema = exports.REVIEW_VERDICT_CONTRACT_REF = exports.parseCoordinatorSignalArtifact = exports.isCoordinatorSignalArtifact = exports.CoordinatorSignalArtifactV1Schema = exports.CoordinatorSignalKindSchema = exports.COORDINATOR_SIGNAL_CONTRACT_REF = exports.findLoopControlArtifact = exports.parseLoopControlArtifact = exports.isLoopControlArtifact = exports.LoopControlArtifactV1Schema = exports.LoopControlMetadataV1Schema = exports.LoopControlDecisionSchema = exports.LOOP_CONTROL_CONTRACT_REF = exports.parseAssessmentArtifact = exports.isAssessmentArtifact = exports.AssessmentDimensionSubmissionSchema = exports.AssessmentArtifactV1Schema = exports.ASSESSMENT_CONTRACT_REF = void 0;
3
+ exports.ARTIFACT_CONTRACT_REFS = exports.parseCodingHandoffArtifact = exports.isCodingHandoffArtifact = exports.CodingHandoffArtifactV1Schema = exports.CODING_HANDOFF_CONTRACT_REF = exports.parseShapingHandoffArtifact = exports.isShapingHandoffArtifact = exports.ShapingHandoffArtifactV1Schema = exports.SHAPING_HANDOFF_CONTRACT_REF = exports.parseDiscoveryHandoffArtifact = exports.isDiscoveryHandoffArtifact = exports.DiscoveryHandoffArtifactV1Schema = exports.DISCOVERY_HANDOFF_CONTRACT_REF = exports.parseReviewVerdictArtifact = exports.isReviewVerdictArtifact = exports.ReviewVerdictArtifactV1Schema = exports.REVIEW_VERDICT_CONTRACT_REF = exports.parseCoordinatorSignalArtifact = exports.isCoordinatorSignalArtifact = exports.CoordinatorSignalArtifactV1Schema = exports.CoordinatorSignalKindSchema = exports.COORDINATOR_SIGNAL_CONTRACT_REF = exports.findLoopControlArtifact = exports.parseLoopControlArtifact = exports.isLoopControlArtifact = exports.LoopControlArtifactV1Schema = exports.LoopControlMetadataV1Schema = exports.LoopControlDecisionSchema = exports.LOOP_CONTROL_CONTRACT_REF = exports.parseAssessmentArtifact = exports.isAssessmentArtifact = exports.AssessmentDimensionSubmissionSchema = exports.AssessmentArtifactV1Schema = exports.ASSESSMENT_CONTRACT_REF = void 0;
4
4
  exports.isValidContractRef = isValidContractRef;
5
5
  var assessment_js_1 = require("./assessment.js");
6
6
  Object.defineProperty(exports, "ASSESSMENT_CONTRACT_REF", { enumerable: true, get: function () { return assessment_js_1.ASSESSMENT_CONTRACT_REF; } });
@@ -32,12 +32,23 @@ Object.defineProperty(exports, "DISCOVERY_HANDOFF_CONTRACT_REF", { enumerable: t
32
32
  Object.defineProperty(exports, "DiscoveryHandoffArtifactV1Schema", { enumerable: true, get: function () { return discovery_handoff_js_1.DiscoveryHandoffArtifactV1Schema; } });
33
33
  Object.defineProperty(exports, "isDiscoveryHandoffArtifact", { enumerable: true, get: function () { return discovery_handoff_js_1.isDiscoveryHandoffArtifact; } });
34
34
  Object.defineProperty(exports, "parseDiscoveryHandoffArtifact", { enumerable: true, get: function () { return discovery_handoff_js_1.parseDiscoveryHandoffArtifact; } });
35
+ var phase_handoff_js_1 = require("./phase-handoff.js");
36
+ Object.defineProperty(exports, "SHAPING_HANDOFF_CONTRACT_REF", { enumerable: true, get: function () { return phase_handoff_js_1.SHAPING_HANDOFF_CONTRACT_REF; } });
37
+ Object.defineProperty(exports, "ShapingHandoffArtifactV1Schema", { enumerable: true, get: function () { return phase_handoff_js_1.ShapingHandoffArtifactV1Schema; } });
38
+ Object.defineProperty(exports, "isShapingHandoffArtifact", { enumerable: true, get: function () { return phase_handoff_js_1.isShapingHandoffArtifact; } });
39
+ Object.defineProperty(exports, "parseShapingHandoffArtifact", { enumerable: true, get: function () { return phase_handoff_js_1.parseShapingHandoffArtifact; } });
40
+ Object.defineProperty(exports, "CODING_HANDOFF_CONTRACT_REF", { enumerable: true, get: function () { return phase_handoff_js_1.CODING_HANDOFF_CONTRACT_REF; } });
41
+ Object.defineProperty(exports, "CodingHandoffArtifactV1Schema", { enumerable: true, get: function () { return phase_handoff_js_1.CodingHandoffArtifactV1Schema; } });
42
+ Object.defineProperty(exports, "isCodingHandoffArtifact", { enumerable: true, get: function () { return phase_handoff_js_1.isCodingHandoffArtifact; } });
43
+ Object.defineProperty(exports, "parseCodingHandoffArtifact", { enumerable: true, get: function () { return phase_handoff_js_1.parseCodingHandoffArtifact; } });
35
44
  exports.ARTIFACT_CONTRACT_REFS = [
36
45
  'wr.contracts.assessment',
37
46
  'wr.contracts.loop_control',
38
47
  'wr.contracts.coordinator_signal',
39
48
  'wr.contracts.review_verdict',
40
49
  'wr.contracts.discovery_handoff',
50
+ 'wr.contracts.shaping_handoff',
51
+ 'wr.contracts.coding_handoff',
41
52
  ];
42
53
  function isValidContractRef(ref) {
43
54
  return exports.ARTIFACT_CONTRACT_REFS.includes(ref);
@@ -0,0 +1,89 @@
1
+ import { z } from 'zod';
2
+ import type { DiscoveryHandoffArtifactV1 } from './discovery-handoff.js';
3
+ export declare const SHAPING_HANDOFF_CONTRACT_REF: "wr.contracts.shaping_handoff";
4
+ export declare const ShapingHandoffArtifactV1Schema: z.ZodObject<{
5
+ kind: z.ZodLiteral<"wr.shaping_handoff">;
6
+ version: z.ZodLiteral<1>;
7
+ pitchPath: z.ZodString;
8
+ selectedShape: z.ZodString;
9
+ appetite: z.ZodString;
10
+ keyConstraints: z.ZodArray<z.ZodString, "many">;
11
+ rabbitHoles: z.ZodArray<z.ZodString, "many">;
12
+ outOfScope: z.ZodArray<z.ZodString, "many">;
13
+ validationChecklist: z.ZodArray<z.ZodString, "many">;
14
+ }, "strict", z.ZodTypeAny, {
15
+ kind: "wr.shaping_handoff";
16
+ version: 1;
17
+ pitchPath: string;
18
+ selectedShape: string;
19
+ appetite: string;
20
+ keyConstraints: string[];
21
+ rabbitHoles: string[];
22
+ outOfScope: string[];
23
+ validationChecklist: string[];
24
+ }, {
25
+ kind: "wr.shaping_handoff";
26
+ version: 1;
27
+ pitchPath: string;
28
+ selectedShape: string;
29
+ appetite: string;
30
+ keyConstraints: string[];
31
+ rabbitHoles: string[];
32
+ outOfScope: string[];
33
+ validationChecklist: string[];
34
+ }>;
35
+ export type ShapingHandoffArtifactV1 = z.infer<typeof ShapingHandoffArtifactV1Schema>;
36
+ export declare function isShapingHandoffArtifact(artifact: unknown): artifact is {
37
+ readonly kind: 'wr.shaping_handoff';
38
+ };
39
+ export declare function parseShapingHandoffArtifact(artifact: unknown): ShapingHandoffArtifactV1 | null;
40
+ export declare const CODING_HANDOFF_CONTRACT_REF: "wr.contracts.coding_handoff";
41
+ export declare const CodingHandoffArtifactV1Schema: z.ZodObject<{
42
+ kind: z.ZodLiteral<"wr.coding_handoff">;
43
+ version: z.ZodLiteral<1>;
44
+ branchName: z.ZodString;
45
+ keyDecisions: z.ZodArray<z.ZodString, "many">;
46
+ knownLimitations: z.ZodArray<z.ZodString, "many">;
47
+ testsAdded: z.ZodArray<z.ZodString, "many">;
48
+ filesChanged: z.ZodArray<z.ZodString, "many">;
49
+ correctedAssumptions: z.ZodOptional<z.ZodArray<z.ZodObject<{
50
+ assumed: z.ZodString;
51
+ actual: z.ZodString;
52
+ }, "strip", z.ZodTypeAny, {
53
+ assumed: string;
54
+ actual: string;
55
+ }, {
56
+ assumed: string;
57
+ actual: string;
58
+ }>, "many">>;
59
+ }, "strict", z.ZodTypeAny, {
60
+ kind: "wr.coding_handoff";
61
+ version: 1;
62
+ branchName: string;
63
+ keyDecisions: string[];
64
+ knownLimitations: string[];
65
+ testsAdded: string[];
66
+ filesChanged: string[];
67
+ correctedAssumptions?: {
68
+ assumed: string;
69
+ actual: string;
70
+ }[] | undefined;
71
+ }, {
72
+ kind: "wr.coding_handoff";
73
+ version: 1;
74
+ branchName: string;
75
+ keyDecisions: string[];
76
+ knownLimitations: string[];
77
+ testsAdded: string[];
78
+ filesChanged: string[];
79
+ correctedAssumptions?: {
80
+ assumed: string;
81
+ actual: string;
82
+ }[] | undefined;
83
+ }>;
84
+ export type CodingHandoffArtifactV1 = z.infer<typeof CodingHandoffArtifactV1Schema>;
85
+ export declare function isCodingHandoffArtifact(artifact: unknown): artifact is {
86
+ readonly kind: 'wr.coding_handoff';
87
+ };
88
+ export declare function parseCodingHandoffArtifact(artifact: unknown): CodingHandoffArtifactV1 | null;
89
+ export type PhaseHandoffArtifact = DiscoveryHandoffArtifactV1 | ShapingHandoffArtifactV1 | CodingHandoffArtifactV1;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CodingHandoffArtifactV1Schema = exports.CODING_HANDOFF_CONTRACT_REF = exports.ShapingHandoffArtifactV1Schema = exports.SHAPING_HANDOFF_CONTRACT_REF = void 0;
4
+ exports.isShapingHandoffArtifact = isShapingHandoffArtifact;
5
+ exports.parseShapingHandoffArtifact = parseShapingHandoffArtifact;
6
+ exports.isCodingHandoffArtifact = isCodingHandoffArtifact;
7
+ exports.parseCodingHandoffArtifact = parseCodingHandoffArtifact;
8
+ const zod_1 = require("zod");
9
+ exports.SHAPING_HANDOFF_CONTRACT_REF = 'wr.contracts.shaping_handoff';
10
+ exports.ShapingHandoffArtifactV1Schema = zod_1.z
11
+ .object({
12
+ kind: zod_1.z.literal('wr.shaping_handoff'),
13
+ version: zod_1.z.literal(1),
14
+ pitchPath: zod_1.z.string().min(1),
15
+ selectedShape: zod_1.z.string().min(1).max(200),
16
+ appetite: zod_1.z.string().min(1).max(100),
17
+ keyConstraints: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(8),
18
+ rabbitHoles: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(6),
19
+ outOfScope: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(6),
20
+ validationChecklist: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(10),
21
+ })
22
+ .strict();
23
+ function isShapingHandoffArtifact(artifact) {
24
+ return (typeof artifact === 'object' &&
25
+ artifact !== null &&
26
+ artifact.kind === 'wr.shaping_handoff');
27
+ }
28
+ function parseShapingHandoffArtifact(artifact) {
29
+ const result = exports.ShapingHandoffArtifactV1Schema.safeParse(artifact);
30
+ return result.success ? result.data : null;
31
+ }
32
+ exports.CODING_HANDOFF_CONTRACT_REF = 'wr.contracts.coding_handoff';
33
+ exports.CodingHandoffArtifactV1Schema = zod_1.z
34
+ .object({
35
+ kind: zod_1.z.literal('wr.coding_handoff'),
36
+ version: zod_1.z.literal(1),
37
+ branchName: zod_1.z.string().min(1),
38
+ keyDecisions: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(8),
39
+ knownLimitations: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(6),
40
+ testsAdded: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(10),
41
+ filesChanged: zod_1.z.array(zod_1.z.string().min(1).max(300)).max(20),
42
+ correctedAssumptions: zod_1.z.array(zod_1.z.object({
43
+ assumed: zod_1.z.string().min(1).max(200),
44
+ actual: zod_1.z.string().min(1).max(200),
45
+ })).max(6).optional(),
46
+ })
47
+ .strict();
48
+ function isCodingHandoffArtifact(artifact) {
49
+ return (typeof artifact === 'object' &&
50
+ artifact !== null &&
51
+ artifact.kind === 'wr.coding_handoff');
52
+ }
53
+ function parseCodingHandoffArtifact(artifact) {
54
+ const result = exports.CodingHandoffArtifactV1Schema.safeParse(artifact);
55
+ return result.success ? result.data : null;
56
+ }
@@ -434,6 +434,18 @@ WorkRail v2 provides **built-in** building blocks that workflows (including exte
434
434
  - **Features**: deterministic, closed-set “middleware” applied by WorkRail (e.g., tier-aware instructions, formatting, durable recap guidance).
435
435
  - **Contract packs**: server-side definitions for allowed artifact kinds and small examples (no schema authoring required by workflow authors).
436
436
 
437
+ **Available contract refs** (use in `outputContract: { contractRef: "..." }`):
438
+
439
+ | contractRef | Artifact kind | Emitted by |
440
+ |---|---|---|
441
+ | `wr.contracts.loop_control` | `wr.loop_control` | Loop body exit steps |
442
+ | `wr.contracts.coordinator_signal` | `wr.coordinator_signal` | Coordinator signal steps |
443
+ | `wr.contracts.review_verdict` | `wr.review_verdict` | Review workflow final step |
444
+ | `wr.contracts.discovery_handoff` | `wr.discovery_handoff` | Discovery workflow handoff step |
445
+ | `wr.contracts.shaping_handoff` | `wr.shaping_handoff` | Shaping workflow finalize step |
446
+ | `wr.contracts.coding_handoff` | `wr.coding_handoff` | Coding workflow retrospective step |
447
+ | `wr.contracts.assessment` | `wr.assessment` | Assessment gate steps |
448
+
437
449
  External workflows can reference these builtins, but cannot define arbitrary new plugin code.
438
450
 
439
451
  ### Where injections happen: templates as anchors