@vercel/factory 0.0.8 → 0.0.10

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.
@@ -1,132 +1,120 @@
1
1
  import { a as repositoryIdsSchema, d as schemaVersionSchema, f as usdSchema, i as repositoryIdSchema, l as isoDateTimeSchema, o as signalIdSchema, p as vocabularySchema, s as taskIdSchema, t as changeIdSchema, u as replyToSchema } from "./id-DwCihQr4.mjs";
2
2
  import { n as RecordNotFoundError } from "./driver-Bbd25rNM.mjs";
3
3
  import { z } from "zod";
4
- import { createHash } from "node:crypto";
5
- //#region src/schema/finding.ts
6
- const findingPrioritySchema = z.enum([
7
- "P0",
8
- "P1",
9
- "P2",
10
- "P3"
11
- ]).describe("Urgency of a finding: P0 is drop-everything, P3 is nice-to-have.");
12
- const findingCategorySchema = z.enum([
13
- "security",
14
- "correctness",
15
- "reliability",
16
- "performance",
17
- "compatibility",
18
- "accessibility",
19
- "documentation",
20
- "maintainability",
21
- "testing",
22
- "usability"
23
- ]);
24
- const findingVerificationLevelSchema = z.enum([
25
- "unverified",
26
- "supported",
27
- "confirmed"
28
- ]).describe("How sure the reporter is: unverified = suspected from reading; supported = evidence points to it; confirmed = demonstrated.");
29
- const findingVerificationMethodSchema = z.enum([
30
- "code_inspection",
31
- "static_analysis",
32
- "manual_reproduction",
33
- "unit_test",
34
- "integration_test",
35
- "e2e_test",
36
- "runtime_observation",
37
- "documentation"
38
- ]);
4
+ //#region src/schema/task.ts
39
5
  /**
40
- * What was done to check the finding. Forces a reporter to distinguish "I
41
- * think this is a problem" from "I demonstrated it", which is the axis a human
42
- * approving fixes cares about most.
6
+ * Kinds the standard loop understands. Any vocabulary value is valid; the
7
+ * kind-scoped rules below apply only to these standard kinds.
43
8
  */
44
- const findingVerificationSchema = z.strictObject({
45
- level: findingVerificationLevelSchema,
46
- method: findingVerificationMethodSchema,
47
- summary: z.string().min(1).max(2e3).describe("What was checked and what it showed."),
48
- limitations: z.string().min(1).max(2e3).optional().describe("What could not be checked.")
9
+ const standardTaskKinds = [
10
+ "coordination",
11
+ "code_change",
12
+ "verification",
13
+ "investigation",
14
+ "question"
15
+ ];
16
+ const taskKindSchema = vocabularySchema.describe("What kind of work this is, e.g. code_change, question, or a registered custom kind.");
17
+ const taskStateSchema = z.enum([
18
+ "queued",
19
+ "running",
20
+ "verifying",
21
+ "succeeded",
22
+ "failed",
23
+ "needs_human",
24
+ "cancelled"
25
+ ]).describe("Lifecycle state. Transitions are fixed; see taskTransitions.");
26
+ const taskApprovalSchema = z.enum([
27
+ "required",
28
+ "granted",
29
+ "denied"
30
+ ]).describe("Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator.");
31
+ const taskExecutionRepositoryIdsSchema = z.tuple([repositoryIdSchema]).describe("The one repository used to execute a task.");
32
+ const coordinationRepositoryIdsSchema = z.tuple([repositoryIdSchema, repositoryIdSchema]).rest(repositoryIdSchema).refine((repositoryIds) => new Set(repositoryIds).size === repositoryIds.length, { message: "Coordination tasks require distinct repositories." }).describe("The distinct repositories coordinated by a non-executable parent task.");
33
+ const harnessSchema = z.string().min(1).describe("Coding harness used in the devbox, e.g. claude-code or codex.");
34
+ const taskOriginSchema = z.strictObject({
35
+ signalId: signalIdSchema.optional().describe("Signal that led to this task."),
36
+ parentTaskId: taskIdSchema.optional().describe("Parent task that planned this child."),
37
+ operator: z.string().min(1).optional().describe("Human operator who requested it.")
38
+ }).refine((origin) => origin.signalId !== void 0 || origin.parentTaskId !== void 0 || origin.operator !== void 0, { message: "origin requires a signalId, parentTaskId, or operator" });
39
+ const taskDevboxSchema = z.strictObject({
40
+ devboxId: z.string().min(1).describe("Devbox running or having run this task."),
41
+ remoteId: z.string().min(1).describe("Provider-side id of the execution."),
42
+ harness: harnessSchema
49
43
  });
50
- /** A single problem found in a repository, as a scanner or agent reports it. */
51
- const findingSchema = z.strictObject({
52
- title: z.string().min(1).max(200),
53
- body: z.string().min(1).max(8e3).describe("The problem, its impact, and how to fix it. Markdown."),
54
- path: z.string().min(1).max(500).optional().describe("Repository-relative file path."),
55
- line: z.number().int().min(1).optional(),
56
- endLine: z.number().int().min(1).optional(),
57
- priority: findingPrioritySchema,
58
- category: findingCategorySchema,
59
- verification: findingVerificationSchema,
60
- tool: z.string().min(1).max(100).optional().describe("Scanner that produced it, e.g. deepsec."),
61
- ruleId: z.string().min(1).max(200).optional().describe("Scanner rule or check id, when there is one.")
44
+ const taskQuestionSchema = z.strictObject({
45
+ text: z.string().min(1).describe("The question a human must answer."),
46
+ options: z.array(z.string().min(1)).describe("Suggested answers; free-text is also allowed."),
47
+ answer: z.string().min(1).optional(),
48
+ answeredBy: z.string().min(1).optional().describe("Authenticated operator who answered.")
62
49
  });
63
- /**
64
- * Stable identity of a finding across scans, used as the signal's delivery id
65
- * so re-reporting is a no-op instead of a second task. A scanner finding is
66
- * the same problem when the same tool reports the same rule on the same file;
67
- * its title is model-written prose and changes between runs, so it is left
68
- * out. Without a rule id the title is all there is, normalised.
69
- */
70
- function findingFingerprint(repositoryId, finding) {
71
- const parts = finding.tool !== void 0 && finding.ruleId !== void 0 && finding.path !== void 0 ? [
72
- repositoryId,
73
- finding.tool,
74
- finding.ruleId,
75
- finding.path
76
- ] : [
77
- repositoryId,
78
- finding.tool ?? "",
79
- finding.ruleId ?? "",
80
- finding.path ?? "",
81
- finding.title.trim().toLowerCase().replaceAll(/\s+/gu, " ")
82
- ];
83
- return createHash("sha256").update(parts.join(" ")).digest("hex").slice(0, 32);
84
- }
85
- //#endregion
86
- //#region src/approval.ts
87
- /**
88
- * One approval rule. Every listed field must match for the rule to apply;
89
- * absent fields match anything. Rules are evaluated first-match.
90
- */
91
- const approvalRuleSchema = z.strictObject({
92
- source: vocabularySchema.optional().describe("Signal source, e.g. security_scan or github_issue."),
93
- kind: vocabularySchema.optional().describe("Task kind, e.g. code_change."),
94
- priority: z.array(findingPrioritySchema).min(1).optional().describe("Finding priorities the rule applies to."),
95
- require: z.boolean().describe("Whether matching tasks wait for a human before dispatch.")
50
+ const taskSchema = z.strictObject({
51
+ schemaVersion: schemaVersionSchema,
52
+ id: taskIdSchema,
53
+ repositoryIds: repositoryIdsSchema.describe("Repositories the task concerns."),
54
+ kind: taskKindSchema,
55
+ area: z.string().min(1).optional().describe("Investigation area, e.g. onboarding or security. Investigation tasks only."),
56
+ state: taskStateSchema,
57
+ approval: taskApprovalSchema.optional(),
58
+ origin: taskOriginSchema,
59
+ dependsOn: z.array(taskIdSchema).min(1).optional().describe("Sibling tasks that must produce a change before this one may run."),
60
+ replyTo: replyToSchema,
61
+ devbox: taskDevboxSchema.optional(),
62
+ attempt: z.number().int().min(1).describe("Execution attempt, starting at 1; bumps on retry."),
63
+ reservedUsd: usdSchema.optional().describe("Budget reserved before dispatch."),
64
+ settledUsd: usdSchema.optional().describe("Measured cost settled after execution."),
65
+ question: taskQuestionSchema.optional(),
66
+ changeId: changeIdSchema.optional().describe("Change this code_change task produced."),
67
+ reportRef: z.string().min(1).optional().describe("Reference to the report artifact an investigation produced."),
68
+ createdAt: isoDateTimeSchema,
69
+ updatedAt: isoDateTimeSchema
70
+ }).superRefine((task, ctx) => {
71
+ if (task.kind === "coordination" && !coordinationRepositoryIdsSchema.safeParse(task.repositoryIds).success) ctx.addIssue({
72
+ code: "custom",
73
+ path: ["repositoryIds"],
74
+ message: "coordination tasks require at least two distinct repositories"
75
+ });
76
+ if ((task.kind === "code_change" || task.kind === "verification") && task.repositoryIds.length !== 1) ctx.addIssue({
77
+ code: "custom",
78
+ path: ["repositoryIds"],
79
+ message: `${task.kind} tasks require exactly one repository`
80
+ });
81
+ if (task.area !== void 0 && task.kind !== "investigation") ctx.addIssue({
82
+ code: "custom",
83
+ path: ["area"],
84
+ message: "area is only valid on investigation tasks"
85
+ });
86
+ if (task.kind === "question") {
87
+ if (task.question === void 0) ctx.addIssue({
88
+ code: "custom",
89
+ path: ["question"],
90
+ message: "question tasks require a question"
91
+ });
92
+ if (task.devbox !== void 0) ctx.addIssue({
93
+ code: "custom",
94
+ path: ["devbox"],
95
+ message: "question tasks never run in a devbox"
96
+ });
97
+ } else if (task.question !== void 0) ctx.addIssue({
98
+ code: "custom",
99
+ path: ["question"],
100
+ message: "question is only valid on question tasks"
101
+ });
102
+ if (task.kind === "coordination" && task.devbox !== void 0) ctx.addIssue({
103
+ code: "custom",
104
+ path: ["devbox"],
105
+ message: "coordination tasks never run in a devbox"
106
+ });
107
+ if (task.changeId !== void 0 && task.kind !== "code_change") ctx.addIssue({
108
+ code: "custom",
109
+ path: ["changeId"],
110
+ message: "changeId is only valid on code_change tasks"
111
+ });
112
+ if (task.reportRef !== void 0 && task.kind !== "investigation") ctx.addIssue({
113
+ code: "custom",
114
+ path: ["reportRef"],
115
+ message: "reportRef is only valid on investigation tasks"
116
+ });
96
117
  });
97
- const approvalPolicySchema = z.array(approvalRuleSchema).describe("First-match rules deciding which tasks need a human before they run.");
98
- /**
99
- * The default: fixes for security findings wait for a human; everything else
100
- * runs as it always has. Handoffs between agents (verification) never wait,
101
- * because a human already approved the work they continue.
102
- */
103
- const defaultApprovalPolicy = [
104
- {
105
- kind: "verification",
106
- require: false
107
- },
108
- {
109
- source: "security_scan",
110
- require: true
111
- },
112
- { require: false }
113
- ];
114
- /**
115
- * Decide at task-creation time whether a task needs approval. Pure: the answer
116
- * is stamped on the task and never re-evaluated, so a later policy change
117
- * cannot silently release work a human was expecting to see.
118
- */
119
- function requiresApproval(policy, subject) {
120
- for (const rule of policy) {
121
- if (rule.source !== void 0 && rule.source !== subject.source) continue;
122
- if (rule.kind !== void 0 && rule.kind !== subject.kind) continue;
123
- if (rule.priority !== void 0) {
124
- if (subject.priority === void 0 || !rule.priority.includes(subject.priority)) continue;
125
- }
126
- return rule.require;
127
- }
128
- return false;
129
- }
130
118
  //#endregion
131
119
  //#region src/dispatch.ts
132
120
  var DispatchRefusedError = class extends Error {
@@ -151,6 +139,8 @@ async function dispatchTask(stores, taskId, options) {
151
139
  const task = await stores.tasks.get(taskId);
152
140
  if (task === null) throw new RecordNotFoundError("tasks", taskId);
153
141
  if (task.kind === "question") throw new DispatchRefusedError(taskId, "question tasks are answered, not dispatched");
142
+ if (task.kind === "coordination") throw new DispatchRefusedError(taskId, "coordination tasks are reconciled, not dispatched");
143
+ if (!taskExecutionRepositoryIdsSchema.safeParse(task.repositoryIds).success) throw new DispatchRefusedError(taskId, "task execution requires exactly one repository");
154
144
  if (task.approval === "required") throw new DispatchRefusedError(taskId, "awaiting human approval");
155
145
  if (task.approval === "denied") throw new DispatchRefusedError(taskId, "approval was denied");
156
146
  for (const dependencyId of task.dependsOn ?? []) {
@@ -235,103 +225,6 @@ const changeSchema = z.strictObject({
235
225
  });
236
226
  });
237
227
  //#endregion
238
- //#region src/schema/task.ts
239
- /**
240
- * Kinds the standard loop understands. Any vocabulary value is valid; the
241
- * kind-scoped rules below apply only to these standard kinds.
242
- */
243
- const standardTaskKinds = [
244
- "code_change",
245
- "verification",
246
- "investigation",
247
- "question"
248
- ];
249
- const taskKindSchema = vocabularySchema.describe("What kind of work this is, e.g. code_change, question, or a registered custom kind.");
250
- const taskStateSchema = z.enum([
251
- "queued",
252
- "running",
253
- "verifying",
254
- "succeeded",
255
- "failed",
256
- "needs_human",
257
- "cancelled"
258
- ]).describe("Lifecycle state. Transitions are fixed; see taskTransitions.");
259
- const taskApprovalSchema = z.enum([
260
- "required",
261
- "granted",
262
- "denied"
263
- ]).describe("Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator.");
264
- const harnessSchema = z.string().min(1).describe("Coding harness used in the devbox, e.g. claude-code or codex.");
265
- const taskOriginSchema = z.strictObject({
266
- signalId: signalIdSchema.optional().describe("Signal that led to this task."),
267
- parentTaskId: taskIdSchema.optional().describe("Parent task that planned this child."),
268
- operator: z.string().min(1).optional().describe("Human operator who requested it.")
269
- }).refine((origin) => origin.signalId !== void 0 || origin.parentTaskId !== void 0 || origin.operator !== void 0, { message: "origin requires a signalId, parentTaskId, or operator" });
270
- const taskDevboxSchema = z.strictObject({
271
- devboxId: z.string().min(1).describe("Devbox running or having run this task."),
272
- remoteId: z.string().min(1).describe("Provider-side id of the execution."),
273
- harness: harnessSchema
274
- });
275
- const taskQuestionSchema = z.strictObject({
276
- text: z.string().min(1).describe("The question a human must answer."),
277
- options: z.array(z.string().min(1)).describe("Suggested answers; free-text is also allowed."),
278
- answer: z.string().min(1).optional(),
279
- answeredBy: z.string().min(1).optional().describe("Authenticated operator who answered.")
280
- });
281
- const taskSchema = z.strictObject({
282
- schemaVersion: schemaVersionSchema,
283
- id: taskIdSchema,
284
- repositoryIds: repositoryIdsSchema.optional().describe("Repositories the task works on; absent only on a multi-repo parent."),
285
- kind: taskKindSchema,
286
- area: z.string().min(1).optional().describe("Investigation area, e.g. onboarding or security. Investigation tasks only."),
287
- state: taskStateSchema,
288
- approval: taskApprovalSchema.optional(),
289
- origin: taskOriginSchema,
290
- dependsOn: z.array(taskIdSchema).min(1).optional().describe("Sibling tasks that must produce a change before this one may run."),
291
- replyTo: replyToSchema,
292
- devbox: taskDevboxSchema.optional(),
293
- attempt: z.number().int().min(1).describe("Execution attempt, starting at 1; bumps on retry."),
294
- reservedUsd: usdSchema.optional().describe("Budget reserved before dispatch."),
295
- settledUsd: usdSchema.optional().describe("Measured cost settled after execution."),
296
- question: taskQuestionSchema.optional(),
297
- changeId: changeIdSchema.optional().describe("Change this code_change task produced."),
298
- reportRef: z.string().min(1).optional().describe("Reference to the report artifact an investigation produced."),
299
- createdAt: isoDateTimeSchema,
300
- updatedAt: isoDateTimeSchema
301
- }).superRefine((task, ctx) => {
302
- if (task.area !== void 0 && task.kind !== "investigation") ctx.addIssue({
303
- code: "custom",
304
- path: ["area"],
305
- message: "area is only valid on investigation tasks"
306
- });
307
- if (task.kind === "question") {
308
- if (task.question === void 0) ctx.addIssue({
309
- code: "custom",
310
- path: ["question"],
311
- message: "question tasks require a question"
312
- });
313
- if (task.devbox !== void 0) ctx.addIssue({
314
- code: "custom",
315
- path: ["devbox"],
316
- message: "question tasks never run in a devbox"
317
- });
318
- } else if (task.question !== void 0) ctx.addIssue({
319
- code: "custom",
320
- path: ["question"],
321
- message: "question is only valid on question tasks"
322
- });
323
- if (task.changeId !== void 0 && task.kind !== "code_change") ctx.addIssue({
324
- code: "custom",
325
- path: ["changeId"],
326
- message: "changeId is only valid on code_change tasks"
327
- });
328
- if (task.reportRef !== void 0 && task.kind !== "investigation") ctx.addIssue({
329
- code: "custom",
330
- path: ["reportRef"],
331
- message: "reportRef is only valid on investigation tasks"
332
- });
333
- });
334
- //#endregion
335
- export { findingPrioritySchema as C, findingVerificationSchema as D, findingVerificationMethodSchema as E, findingFingerprint as S, findingVerificationLevelSchema as T, approvalPolicySchema as _, taskKindSchema as a, requiresApproval as b, taskSchema as c, changeSchema as d, changeStateSchema as f, dispatchTask as g, DispatchRefusedError as h, taskDevboxSchema as i, taskStateSchema as l, DEFAULT_MAX_LAUNCH_ATTEMPTS as m, standardTaskKinds as n, taskOriginSchema as o, levelSchema as p, taskApprovalSchema as r, taskQuestionSchema as s, harnessSchema as t, changeEvidenceSchema as u, approvalRuleSchema as v, findingSchema as w, findingCategorySchema as x, defaultApprovalPolicy as y };
228
+ export { taskSchema as _, DEFAULT_MAX_LAUNCH_ATTEMPTS as a, coordinationRepositoryIdsSchema as c, taskApprovalSchema as d, taskDevboxSchema as f, taskQuestionSchema as g, taskOriginSchema as h, levelSchema as i, harnessSchema as l, taskKindSchema as m, changeSchema as n, DispatchRefusedError as o, taskExecutionRepositoryIdsSchema as p, changeStateSchema as r, dispatchTask as s, changeEvidenceSchema as t, standardTaskKinds as u, taskStateSchema as v };
336
229
 
337
- //# sourceMappingURL=task-BxTU3MJb.mjs.map
230
+ //# sourceMappingURL=change-BPYhWKuL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-BPYhWKuL.mjs","names":[],"sources":["../src/schema/task.ts","../src/dispatch.ts","../src/schema/change.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isoDateTimeSchema,\n replyToSchema,\n schemaVersionSchema,\n usdSchema,\n vocabularySchema,\n} from \"./common\";\nimport {\n changeIdSchema,\n repositoryIdSchema,\n repositoryIdsSchema,\n signalIdSchema,\n taskIdSchema,\n} from \"./id\";\n\n/**\n * Kinds the standard loop understands. Any vocabulary value is valid; the\n * kind-scoped rules below apply only to these standard kinds.\n */\nexport const standardTaskKinds = [\n \"coordination\",\n \"code_change\",\n \"verification\",\n \"investigation\",\n \"question\",\n] as const;\n\nexport const taskKindSchema = vocabularySchema.describe(\n \"What kind of work this is, e.g. code_change, question, or a registered custom kind.\",\n);\n\nexport const taskStateSchema = z\n .enum([\"queued\", \"running\", \"verifying\", \"succeeded\", \"failed\", \"needs_human\", \"cancelled\"])\n .describe(\"Lifecycle state. Transitions are fixed; see taskTransitions.\");\n\nexport const taskApprovalSchema = z\n .enum([\"required\", \"granted\", \"denied\"])\n .describe(\n \"Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator.\",\n );\n\nexport const taskExecutionRepositoryIdsSchema = z\n .tuple([repositoryIdSchema])\n .describe(\"The one repository used to execute a task.\");\n\nexport const coordinationRepositoryIdsSchema = z\n .tuple([repositoryIdSchema, repositoryIdSchema])\n .rest(repositoryIdSchema)\n .refine((repositoryIds) => new Set(repositoryIds).size === repositoryIds.length, {\n message: \"Coordination tasks require distinct repositories.\",\n })\n .describe(\"The distinct repositories coordinated by a non-executable parent task.\");\n\nexport const harnessSchema = z\n .string()\n .min(1)\n .describe(\"Coding harness used in the devbox, e.g. claude-code or codex.\");\n\nexport const taskOriginSchema = z\n .strictObject({\n signalId: signalIdSchema.optional().describe(\"Signal that led to this task.\"),\n parentTaskId: taskIdSchema.optional().describe(\"Parent task that planned this child.\"),\n operator: z.string().min(1).optional().describe(\"Human operator who requested it.\"),\n })\n .refine(\n (origin) =>\n origin.signalId !== undefined ||\n origin.parentTaskId !== undefined ||\n origin.operator !== undefined,\n { message: \"origin requires a signalId, parentTaskId, or operator\" },\n );\n\nexport const taskDevboxSchema = z.strictObject({\n devboxId: z.string().min(1).describe(\"Devbox running or having run this task.\"),\n remoteId: z.string().min(1).describe(\"Provider-side id of the execution.\"),\n harness: harnessSchema,\n});\n\nexport const taskQuestionSchema = z.strictObject({\n text: z.string().min(1).describe(\"The question a human must answer.\"),\n options: z.array(z.string().min(1)).describe(\"Suggested answers; free-text is also allowed.\"),\n answer: z.string().min(1).optional(),\n answeredBy: z.string().min(1).optional().describe(\"Authenticated operator who answered.\"),\n});\n\nexport const taskSchema = z\n .strictObject({\n schemaVersion: schemaVersionSchema,\n id: taskIdSchema,\n repositoryIds: repositoryIdsSchema.describe(\"Repositories the task concerns.\"),\n kind: taskKindSchema,\n area: z\n .string()\n .min(1)\n .optional()\n .describe(\"Investigation area, e.g. onboarding or security. Investigation tasks only.\"),\n state: taskStateSchema,\n approval: taskApprovalSchema.optional(),\n origin: taskOriginSchema,\n dependsOn: z\n .array(taskIdSchema)\n .min(1)\n .optional()\n .describe(\"Sibling tasks that must produce a change before this one may run.\"),\n replyTo: replyToSchema,\n devbox: taskDevboxSchema.optional(),\n attempt: z\n .number()\n .int()\n .min(1)\n .describe(\"Execution attempt, starting at 1; bumps on retry.\"),\n reservedUsd: usdSchema.optional().describe(\"Budget reserved before dispatch.\"),\n settledUsd: usdSchema.optional().describe(\"Measured cost settled after execution.\"),\n question: taskQuestionSchema.optional(),\n changeId: changeIdSchema.optional().describe(\"Change this code_change task produced.\"),\n reportRef: z\n .string()\n .min(1)\n .optional()\n .describe(\"Reference to the report artifact an investigation produced.\"),\n createdAt: isoDateTimeSchema,\n updatedAt: isoDateTimeSchema,\n })\n .superRefine((task, ctx) => {\n if (\n task.kind === \"coordination\" &&\n !coordinationRepositoryIdsSchema.safeParse(task.repositoryIds).success\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"repositoryIds\"],\n message: \"coordination tasks require at least two distinct repositories\",\n });\n }\n if (\n (task.kind === \"code_change\" || task.kind === \"verification\") &&\n task.repositoryIds.length !== 1\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"repositoryIds\"],\n message: `${task.kind} tasks require exactly one repository`,\n });\n }\n if (task.area !== undefined && task.kind !== \"investigation\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"area\"],\n message: \"area is only valid on investigation tasks\",\n });\n }\n if (task.kind === \"question\") {\n if (task.question === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"question\"],\n message: \"question tasks require a question\",\n });\n }\n if (task.devbox !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"devbox\"],\n message: \"question tasks never run in a devbox\",\n });\n }\n } else if (task.question !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"question\"],\n message: \"question is only valid on question tasks\",\n });\n }\n if (task.kind === \"coordination\" && task.devbox !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"devbox\"],\n message: \"coordination tasks never run in a devbox\",\n });\n }\n if (task.changeId !== undefined && task.kind !== \"code_change\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"changeId\"],\n message: \"changeId is only valid on code_change tasks\",\n });\n }\n if (task.reportRef !== undefined && task.kind !== \"investigation\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"reportRef\"],\n message: \"reportRef is only valid on investigation tasks\",\n });\n }\n });\n\nexport type TaskApproval = z.infer<typeof taskApprovalSchema>;\nexport type TaskKind = z.infer<typeof taskKindSchema>;\nexport type TaskState = z.infer<typeof taskStateSchema>;\nexport type Task = z.infer<typeof taskSchema>;\n","import type { TaskId } from \"./schema/id\";\nimport { taskExecutionRepositoryIdsSchema, type Task } from \"./schema/task\";\nimport { RecordNotFoundError } from \"./store/driver\";\nimport type { FactoryStores } from \"./store/engine\";\n\nexport class DispatchRefusedError extends Error {\n readonly taskId: TaskId;\n readonly reason: string;\n\n constructor(taskId: TaskId, reason: string) {\n super(`dispatch of \"${taskId}\" refused: ${reason}`);\n this.name = \"DispatchRefusedError\";\n this.taskId = taskId;\n this.reason = reason;\n }\n}\n\nexport interface DispatchOptions {\n /**\n * Starts the durable execution for the task (an Eve agent run). Runs after\n * the task has won the queued -> running transition. The execution owns its\n * own provisioning: it creates its Devbox as its first step and patches the\n * task record with the result.\n */\n launch: (task: Task) => Promise<void>;\n /** How many launches to try before the task fails for good; a failure re-queues for the next sweep. */\n maxLaunchAttempts?: number;\n}\n\n// A fresh Vercel project rejects its own agents' sessions until its identity\n// finishes provisioning; at one sweep per minute the budget must outlast that.\nexport const DEFAULT_MAX_LAUNCH_ATTEMPTS = 45;\n\n/**\n * The handshake between recorded work and execution: win the store-gated\n * transition (at most one dispatcher can succeed), then start the run. A\n * launch failure re-queues the task (bumping its attempt) until the attempt\n * limit, then fails it; a crash between the transition and the launch leaves\n * a running task with no execution, which the sweep reaps.\n */\nexport async function dispatchTask(\n stores: FactoryStores,\n taskId: TaskId,\n options: DispatchOptions,\n): Promise<Task> {\n const task = await stores.tasks.get(taskId);\n if (task === null) {\n throw new RecordNotFoundError(\"tasks\", taskId);\n }\n if (task.kind === \"question\") {\n throw new DispatchRefusedError(taskId, \"question tasks are answered, not dispatched\");\n }\n if (task.kind === \"coordination\") {\n throw new DispatchRefusedError(taskId, \"coordination tasks are reconciled, not dispatched\");\n }\n if (!taskExecutionRepositoryIdsSchema.safeParse(task.repositoryIds).success) {\n throw new DispatchRefusedError(taskId, \"task execution requires exactly one repository\");\n }\n if (task.approval === \"required\") {\n throw new DispatchRefusedError(taskId, \"awaiting human approval\");\n }\n if (task.approval === \"denied\") {\n throw new DispatchRefusedError(taskId, \"approval was denied\");\n }\n for (const dependencyId of task.dependsOn ?? []) {\n const dependency = await stores.tasks.get(dependencyId);\n if (dependency === null) {\n throw new DispatchRefusedError(taskId, `dependency \"${dependencyId}\" does not exist`);\n }\n if (dependency.changeId === undefined) {\n throw new DispatchRefusedError(\n taskId,\n `dependency \"${dependencyId}\" has not produced a change`,\n );\n }\n }\n\n const running = await stores.tasks.transition(taskId, \"running\");\n try {\n await options.launch(running);\n } catch (error) {\n const reason = (error instanceof Error ? error.message : String(error)).slice(0, 500);\n const limit = options.maxLaunchAttempts ?? DEFAULT_MAX_LAUNCH_ATTEMPTS;\n if (running.attempt < limit) {\n const retryReason = `launch failed (attempt ${running.attempt} of ${limit}), will retry: ${reason}`;\n await stores.tasks.transition(taskId, \"queued\", { reason: retryReason }).catch(() => undefined);\n // The queued transition writes no receipt; leave one so the retry is visible.\n if (running.repositoryIds !== undefined) {\n await stores.receipts\n .append({\n repositoryIds: running.repositoryIds,\n taskId,\n kind: \"task\",\n state: \"launch_retry\",\n reason: retryReason,\n dedupeKey: `task:${taskId}:launch_retry:${running.attempt}`,\n })\n .catch(() => undefined);\n }\n } else {\n await stores.tasks\n .transition(taskId, \"failed\", { reason: `launch failed after ${running.attempt} attempts: ${reason}` })\n .catch(() => undefined);\n }\n throw error;\n }\n return running;\n}\n","import { z } from \"zod\";\nimport { isoDateTimeSchema, schemaVersionSchema } from \"./common\";\nimport { changeIdSchema, repositoryIdSchema, taskIdSchema } from \"./id\";\n\nexport const levelSchema = z.enum([\"low\", \"medium\", \"high\"]);\n\nexport const changeStateSchema = z.enum([\n \"verifying\",\n \"ready\",\n \"merged\",\n \"deployed\",\n \"rolled_out\",\n \"rolled_back\",\n \"closed\",\n]);\n\nconst postMergeStates: readonly string[] = [\"merged\", \"deployed\", \"rolled_out\", \"rolled_back\"];\n\nexport const changeEvidenceSchema = z.strictObject({\n reproVerified: z.boolean(),\n testsAdded: z.number().int().min(0),\n checksGreen: z.boolean(),\n attackPassed: z.boolean(),\n scopeMatches: z.boolean(),\n previewUrl: z.url().optional(),\n});\n\nexport const changeSchema = z\n .strictObject({\n schemaVersion: schemaVersionSchema,\n id: changeIdSchema,\n repositoryId: repositoryIdSchema,\n taskId: taskIdSchema.optional(),\n groupId: taskIdSchema.optional(),\n prNumber: z.number().int().min(1),\n prUrl: z.url(),\n author: z.string().min(1),\n risk: levelSchema,\n confidence: levelSchema,\n evidence: changeEvidenceSchema,\n state: changeStateSchema,\n mergeSha: z\n .string()\n .regex(/^[0-9a-f]{40}$/)\n .optional()\n .describe(\"Merge commit sha recorded when the pull request merges, matched against production deployments.\"),\n decidedBy: z.string().min(1).optional(),\n createdAt: isoDateTimeSchema,\n updatedAt: isoDateTimeSchema,\n })\n .superRefine((change, ctx) => {\n if (postMergeStates.includes(change.state) && change.decidedBy === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"decidedBy\"],\n message: `${change.state} changes require decidedBy`,\n });\n }\n });\n\nexport type Level = z.infer<typeof levelSchema>;\nexport type ChangeState = z.infer<typeof changeStateSchema>;\nexport type ChangeEvidence = z.infer<typeof changeEvidenceSchema>;\nexport type Change = z.infer<typeof changeSchema>;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as NormalizedSignal, c as communicationEventSchema, d as createCommunicationRouter, i as CommunicationRouter, l as communicationOutcomeSchema, n as CommunicationEvent, o as SignalNormalizer, r as CommunicationOutcome, s as WebhookEvent, t as CommunicationAdapter, u as communicationOutcomes } from "../index-DUb-U5cy.mjs";
1
+ import { a as NormalizedSignal, c as communicationEventSchema, d as createCommunicationRouter, i as CommunicationRouter, l as communicationOutcomeSchema, n as CommunicationEvent, o as SignalNormalizer, r as CommunicationOutcome, s as WebhookEvent, t as CommunicationAdapter, u as communicationOutcomes } from "../index-Cy4jfXh5.mjs";
2
2
  export { CommunicationAdapter, CommunicationEvent, CommunicationOutcome, CommunicationRouter, NormalizedSignal, SignalNormalizer, WebhookEvent, communicationEventSchema, communicationOutcomeSchema, communicationOutcomes, createCommunicationRouter };
@@ -1,4 +1,4 @@
1
- import { a as NormalizedSignal, n as CommunicationEvent, t as CommunicationAdapter } from "../index-DUb-U5cy.mjs";
1
+ import { a as NormalizedSignal, n as CommunicationEvent, t as CommunicationAdapter } from "../index-Cy4jfXh5.mjs";
2
2
  //#region src/connectors/slack.d.ts
3
3
  interface SlackCommunicationDelivery {
4
4
  eventId: string;