@osolmaz/pi-workflows 0.13.0 → 0.13.2

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 (84) hide show
  1. package/README.md +11 -9
  2. package/dist/builtins/autodoc.workflow.d.ts +191 -4
  3. package/dist/builtins/autodoc.workflow.js +156 -30
  4. package/dist/builtins/autodoc.workflow.js.map +1 -1
  5. package/dist/builtins/autoimplement-command-batches.d.ts +1 -0
  6. package/dist/builtins/autoimplement-command-batches.js +29 -31
  7. package/dist/builtins/autoimplement-command-batches.js.map +1 -1
  8. package/dist/builtins/autoimplement.workflow.d.ts +1259 -29
  9. package/dist/builtins/autoimplement.workflow.js +416 -153
  10. package/dist/builtins/autoimplement.workflow.js.map +1 -1
  11. package/dist/builtins/autoplan.workflow.d.ts +6 -0
  12. package/dist/builtins/autoplan.workflow.js +68 -32
  13. package/dist/builtins/autoplan.workflow.js.map +1 -1
  14. package/dist/builtins/catalog.js +5 -5
  15. package/dist/builtins/catalog.js.map +1 -1
  16. package/dist/builtins/change-verification.workflow.d.ts +110 -0
  17. package/dist/builtins/change-verification.workflow.js +860 -0
  18. package/dist/builtins/change-verification.workflow.js.map +1 -0
  19. package/dist/builtins/monitor.workflow.js +4 -3
  20. package/dist/builtins/monitor.workflow.js.map +1 -1
  21. package/dist/builtins/plain-summary.workflow.js +35 -24
  22. package/dist/builtins/plain-summary.workflow.js.map +1 -1
  23. package/dist/builtins/plan-change.workflow.d.ts +361 -6
  24. package/dist/builtins/plan-change.workflow.js +26 -0
  25. package/dist/builtins/plan-change.workflow.js.map +1 -1
  26. package/dist/builtins/sanity-check.workflow.js +19 -22
  27. package/dist/builtins/sanity-check.workflow.js.map +1 -1
  28. package/dist/builtins/workspace-preparation.workflow.d.ts +75 -0
  29. package/dist/builtins/workspace-preparation.workflow.js +498 -0
  30. package/dist/builtins/workspace-preparation.workflow.js.map +1 -0
  31. package/dist/controllers/sqlite.js +16 -51
  32. package/dist/controllers/sqlite.js.map +1 -1
  33. package/dist/extension/decision-channels.js +45 -7
  34. package/dist/extension/decision-channels.js.map +1 -1
  35. package/dist/extension/executor.js +1 -4
  36. package/dist/extension/executor.js.map +1 -1
  37. package/dist/extension/index.js +2 -15
  38. package/dist/extension/index.js.map +1 -1
  39. package/dist/extension/recorder.d.ts +1 -1
  40. package/dist/extension/recorder.js +8 -8
  41. package/dist/extension/recorder.js.map +1 -1
  42. package/dist/state/schema.js +22 -3
  43. package/dist/state/schema.js.map +1 -1
  44. package/dist/viewer/session-reducer.d.ts +0 -1
  45. package/dist/viewer/session-reducer.js +2 -24
  46. package/dist/viewer/session-reducer.js.map +1 -1
  47. package/dist/workflows/engine.js +4 -3
  48. package/dist/workflows/engine.js.map +1 -1
  49. package/dist/workflows/store.d.ts +6 -1
  50. package/dist/workflows/store.js +286 -33
  51. package/dist/workflows/store.js.map +1 -1
  52. package/dist/workflows/types.d.ts +1 -1
  53. package/docs/SQLITE_STATE.md +20 -14
  54. package/docs/WORKFLOW_COMPOSITION.md +8 -0
  55. package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +1 -1
  56. package/docs/plans/2026-08-24-change-scoped-verification-plan.md +419 -0
  57. package/docs/plans/2026-08-25-autoplan-user-intent-capture-plan.md +107 -0
  58. package/docs/session-event-journal.md +2 -3
  59. package/docs/workflows.md +43 -21
  60. package/herdr-plugin.toml +1 -1
  61. package/package.json +1 -1
  62. package/skills/autodoc/SKILL.md +7 -0
  63. package/skills/autoimplement/SKILL.md +4 -0
  64. package/src/builtins/autodoc.workflow.ts +184 -33
  65. package/src/builtins/autoimplement-command-batches.ts +39 -33
  66. package/src/builtins/autoimplement.workflow.ts +483 -175
  67. package/src/builtins/autoplan.workflow.ts +80 -32
  68. package/src/builtins/catalog.ts +5 -5
  69. package/src/builtins/change-verification.workflow.ts +1143 -0
  70. package/src/builtins/monitor.workflow.ts +6 -3
  71. package/src/builtins/plain-summary.workflow.ts +38 -40
  72. package/src/builtins/plan-change.workflow.ts +35 -0
  73. package/src/builtins/sanity-check.workflow.ts +19 -22
  74. package/src/builtins/workspace-preparation.workflow.ts +668 -0
  75. package/src/controllers/sqlite.ts +19 -53
  76. package/src/extension/decision-channels.ts +47 -7
  77. package/src/extension/executor.ts +1 -4
  78. package/src/extension/index.ts +2 -15
  79. package/src/extension/recorder.ts +10 -8
  80. package/src/state/schema.ts +22 -3
  81. package/src/viewer/session-reducer.ts +2 -29
  82. package/src/workflows/engine.ts +4 -3
  83. package/src/workflows/store.ts +397 -43
  84. package/src/workflows/types.ts +0 -1
@@ -4,8 +4,10 @@ import { action, agent, compute, defineWorkflow, includeWorkflow, includedResult
4
4
  import { digest } from "../workflows/human-decision.js";
5
5
  import autodocWorkflow, {} from "./autodoc.workflow.js";
6
6
  import { parseAutoimplementConcurrency, parseCiInspectionBatch, parsePublishedRepositories, parseVerificationCommandPlan, reviewerCommand, } from "./autoimplement-command-batches.js";
7
+ import changeVerificationWorkflow, {} from "./change-verification.workflow.js";
7
8
  import { parsePlanApprovalPolicy } from "./plan-approval.workflow.js";
8
9
  import planChangeWorkflow, {} from "./plan-change.workflow.js";
10
+ import workspacePreparationWorkflow, { parsePreparedWorkspace, } from "./workspace-preparation.workflow.js";
9
11
  const MAX_BLOCKER_CHALLENGES = 3;
10
12
  const MAX_CHALLENGE_ITEMS = 5;
11
13
  const MAX_CHALLENGE_TEXT = 500;
@@ -22,6 +24,7 @@ const TIMEOUT_FALLBACK_SOURCES = [
22
24
  "inspectComments",
23
25
  "inspectCi",
24
26
  "opportunisticTest",
27
+ "finalizeDefaultBranch",
25
28
  "finalizeDelivery",
26
29
  ];
27
30
  const WORK_ATTEMPT_NODES = ["implement", "fix", "addressP2"];
@@ -36,6 +39,7 @@ const TIMEOUT_FALLBACK_ROUTES = {
36
39
  inspectComments: ["retry", "review", "ci", "replan", "blocked"],
37
40
  inspectCi: ["retry", "ci", "deliver", "replan", "blocked"],
38
41
  opportunisticTest: ["retry", "ci", "deliver", "replan", "blocked"],
42
+ finalizeDefaultBranch: ["retry", "replan", "blocked"],
39
43
  finalizeDelivery: ["retry", "deliver", "replan", "blocked"],
40
44
  };
41
45
  function requireRecord(value, label) {
@@ -50,6 +54,12 @@ function requireString(value, label) {
50
54
  }
51
55
  return value.trim();
52
56
  }
57
+ function requireAbsolutePath(value, label) {
58
+ const result = requireString(value, label);
59
+ if (!path.isAbsolute(result))
60
+ throw new Error(`${label} must be absolute`);
61
+ return path.resolve(result);
62
+ }
53
63
  function requireStringArray(value, label) {
54
64
  if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
55
65
  throw new Error(`${label} must be an array of strings`);
@@ -74,10 +84,12 @@ function isTimeoutFallbackSource(nodeId) {
74
84
  function latestTimedOutStep(context) {
75
85
  for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
76
86
  const step = context.state.steps[index];
77
- if (step?.outcome === "timed_out" && isTimeoutFallbackSource(step.nodeId))
87
+ if ((step?.outcome === "timed_out" || step?.outcome === "failed") &&
88
+ isTimeoutFallbackSource(step.nodeId)) {
78
89
  return step;
90
+ }
79
91
  }
80
- throw new Error("No supported timed-out Autoimplement step is available");
92
+ throw new Error("No supported failed Autoimplement step is available");
81
93
  }
82
94
  function latestStepIndex(context, predicate) {
83
95
  for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
@@ -158,7 +170,7 @@ function timeoutFallbackTarget(context) {
158
170
  const fallback = context.outputs.timeoutFallback;
159
171
  if (fallback.route !== "retry") {
160
172
  const routes = {
161
- verify: "planVerification",
173
+ verify: "selectVerificationPath",
162
174
  review: "selectReviewCommands",
163
175
  ci: "inspectCi",
164
176
  deliver: "finalizeDelivery",
@@ -174,7 +186,8 @@ function timeoutFallbackGuard(context) {
174
186
  const attempts = context.state.steps.filter((step) => step.nodeId === "timeoutFallback" && step.outcome === "ok").length;
175
187
  if (attempts >= MAX_TIMEOUT_FALLBACKS) {
176
188
  const timeouts = context.state.steps
177
- .filter((step) => step.outcome === "timed_out" && isTimeoutFallbackSource(step.nodeId))
189
+ .filter((step) => (step.outcome === "timed_out" || step.outcome === "failed") &&
190
+ isTimeoutFallbackSource(step.nodeId))
178
191
  .map((step) => ({
179
192
  nodeId: step.nodeId,
180
193
  attemptId: step.attemptId,
@@ -201,15 +214,6 @@ function timeoutFallbackGuard(context) {
201
214
  },
202
215
  };
203
216
  }
204
- function throwLatestSupportedFailure(context) {
205
- for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
206
- const step = context.state.steps[index];
207
- if (step?.outcome === "failed" && isTimeoutFallbackSource(step.nodeId)) {
208
- throw new Error(step.error ?? `Autoimplement node failed: ${step.nodeId}`);
209
- }
210
- }
211
- throw new Error("No supported failed Autoimplement step is available");
212
- }
213
217
  function parseBlockerChallenge(value) {
214
218
  const result = requireRecord(value, "blocker challenge");
215
219
  if (result.route !== "continue" && result.route !== "blocked") {
@@ -234,6 +238,20 @@ function parseBlockerChallenge(value) {
234
238
  if (nextAction.length > MAX_CHALLENGE_TEXT) {
235
239
  throw new Error(`blocker challenge nextAction must be at most ${MAX_CHALLENGE_TEXT} characters`);
236
240
  }
241
+ const stages = [
242
+ "planDiscovery",
243
+ "documentation",
244
+ "implementation",
245
+ "repair",
246
+ "review",
247
+ "ci",
248
+ "delivery",
249
+ "redesign",
250
+ ];
251
+ const nextStage = result.nextStage === null ? null : result.nextStage;
252
+ if (nextStage !== null && !stages.includes(nextStage)) {
253
+ throw new Error(`blocker challenge nextStage must be one of ${stages.join(", ")} or null`);
254
+ }
237
255
  const alternativesChecked = boundedChallengeItems(result.alternativesChecked, "blocker challenge alternativesChecked");
238
256
  const evidence = boundedChallengeItems(result.evidence, "blocker challenge evidence");
239
257
  if (result.route === "blocked") {
@@ -241,13 +259,14 @@ function parseBlockerChallenge(value) {
241
259
  outsideAuthority !== true ||
242
260
  canProceed !== false ||
243
261
  nextAction.length > 0 ||
262
+ nextStage !== null ||
244
263
  alternativesChecked.length === 0 ||
245
264
  evidence.length === 0) {
246
265
  throw new Error("blocked challenge requires blockingNow=true, outsideAuthority=true, canProceed=false, an empty nextAction, and concrete alternatives and evidence");
247
266
  }
248
267
  }
249
- else if (canProceed !== true || nextAction.length === 0) {
250
- throw new Error("continue challenge requires canProceed=true and a practical nextAction");
268
+ else if (canProceed !== true || nextAction.length === 0 || nextStage === null) {
269
+ throw new Error("continue challenge requires canProceed=true, a practical nextAction, and nextStage");
251
270
  }
252
271
  return {
253
272
  route: result.route,
@@ -256,6 +275,7 @@ function parseBlockerChallenge(value) {
256
275
  canProceed,
257
276
  reason,
258
277
  nextAction,
278
+ nextStage: nextStage,
259
279
  alternativesChecked,
260
280
  evidence,
261
281
  };
@@ -299,14 +319,31 @@ function parseInput(value) {
299
319
  }
300
320
  const concurrency = parseAutoimplementConcurrency(input.concurrency);
301
321
  const approval = parsePlanApprovalPolicy(input.approval);
322
+ let workspaceMode;
323
+ if (input.workspaceMode !== undefined) {
324
+ if (input.workspaceMode !== "auto" &&
325
+ input.workspaceMode !== "branch" &&
326
+ input.workspaceMode !== "worktree" &&
327
+ input.workspaceMode !== "defaultBranch") {
328
+ throw new Error("autoimplement workspaceMode must be auto, branch, worktree, or defaultBranch");
329
+ }
330
+ workspaceMode = input.workspaceMode;
331
+ }
332
+ const preparedWorkspace = input.preparedWorkspace === undefined
333
+ ? undefined
334
+ : parsePreparedWorkspace(input.preparedWorkspace);
335
+ if (input.verificationChecks !== undefined && !Array.isArray(input.verificationChecks)) {
336
+ throw new Error("autoimplement verificationChecks must be an array");
337
+ }
338
+ if (Array.isArray(input.verificationChecks) && input.verificationChecks.length === 0) {
339
+ throw new Error("autoimplement verificationChecks must be non-empty when supplied");
340
+ }
302
341
  return {
303
342
  task: requireString(input.task, "autoimplement task"),
304
343
  ...(input.plan !== undefined ? { plan: input.plan } : {}),
305
344
  ...(input.scope !== undefined ? { scope: requireString(input.scope, "scope") } : {}),
306
345
  ...(constraints !== undefined ? { constraints: [...constraints] } : {}),
307
- ...(input.repository !== undefined
308
- ? { repository: requireString(input.repository, "repository") }
309
- : {}),
346
+ repository: requireAbsolutePath(input.repository, "repository"),
310
347
  ...(input.baseBranch !== undefined
311
348
  ? { baseBranch: requireString(input.baseBranch, "baseBranch") }
312
349
  : {}),
@@ -315,6 +352,14 @@ function parseInput(value) {
315
352
  ...(documentation !== undefined ? { documentation } : {}),
316
353
  approval,
317
354
  concurrency,
355
+ ...(workspaceMode === undefined ? {} : { workspaceMode }),
356
+ ...(input.directDefaultBranchAuthorized === undefined
357
+ ? {}
358
+ : { directDefaultBranchAuthorized: input.directDefaultBranchAuthorized === true }),
359
+ ...(preparedWorkspace === undefined ? {} : { preparedWorkspace }),
360
+ ...(input.verificationChecks === undefined
361
+ ? {}
362
+ : { verificationChecks: input.verificationChecks }),
318
363
  };
319
364
  }
320
365
  function parseExistingPlan(value) {
@@ -423,31 +468,96 @@ function currentPlan(context) {
423
468
  return discovered.plan;
424
469
  return context.input.plan;
425
470
  }
471
+ function preparedWorkspace(context) {
472
+ const request = context.input;
473
+ if (request.preparedWorkspace !== undefined)
474
+ return request.preparedWorkspace;
475
+ const result = includedResult(workspacePreparationWorkflow, context.outputs.workspace);
476
+ if (result.exit !== "ready")
477
+ throw new Error("autoimplement workspace is not ready");
478
+ return result.output;
479
+ }
426
480
  function blockerChallenges(context) {
427
481
  return context.state.steps
428
482
  .filter((step) => step.nodeId === "challengeBlocker" && step.outcome === "ok")
429
483
  .map((step) => step.output);
430
484
  }
431
485
  function latestBlockerClaim(context) {
432
- const ids = [
433
- "classifyImplementation",
434
- "classifyVerification",
435
- "repairReviewCommand",
436
- "inspectComments",
437
- "inspectCi",
438
- "repairCiCommand",
439
- "assessTrackedCi",
440
- "classifyCi",
441
- "finalizeDelivery",
442
- "timeoutFallback",
443
- ];
444
486
  for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
445
487
  const step = context.state.steps[index];
446
- if (step && ids.includes(step.nodeId)) {
447
- return { source: step.nodeId, result: step.output };
488
+ if (step?.nodeId === "createBlockerClaim" && step.outcome === "ok") {
489
+ return step.output;
490
+ }
491
+ }
492
+ throw new Error("No durable blocker claim is available to challenge");
493
+ }
494
+ function unwrapResult(value) {
495
+ const record = requireRecord(value, "blocker source output");
496
+ const output = record.output;
497
+ return output !== null && typeof output === "object" && !Array.isArray(output)
498
+ ? output
499
+ : record;
500
+ }
501
+ function createBlockerClaim(context) {
502
+ const source = [...context.state.steps].reverse().find((step) => {
503
+ if (step.nodeId === "createBlockerClaim")
504
+ return false;
505
+ if (step.error !== undefined)
506
+ return true;
507
+ if (step.output === null || typeof step.output !== "object" || Array.isArray(step.output)) {
508
+ return false;
509
+ }
510
+ const result = unwrapResult(step.output);
511
+ return (typeof result.reason === "string" ||
512
+ typeof result.summary === "string" ||
513
+ typeof result.blocker === "string");
514
+ });
515
+ if (source === undefined)
516
+ throw new Error("No blocker source step is available");
517
+ const result = unwrapResult(source.output ?? { reason: source.error ?? "Step failed" });
518
+ const reasonValue = result.reason ?? result.summary ?? result.blocker ?? source.error;
519
+ const reason = typeof reasonValue === "string" && reasonValue.trim().length > 0
520
+ ? reasonValue.trim()
521
+ : `Autoimplement could not continue after ${source.nodeId}.`;
522
+ const commands = result.candidateCommands ?? result.commands;
523
+ const failedCommands = commands !== null && typeof commands === "object" && !Array.isArray(commands)
524
+ ? (commands.items ?? [])
525
+ : [];
526
+ return {
527
+ schema: "pi-workflows.blocker-claim.v1",
528
+ sourceNode: typeof result.sourceNode === "string" && result.sourceNode.length > 0
529
+ ? result.sourceNode
530
+ : source.nodeId,
531
+ attemptId: source.attemptId,
532
+ route: typeof result.route === "string" ? result.route : source.outcome,
533
+ reason,
534
+ evidence: typeof result.sourceNode === "string"
535
+ ? result
536
+ : (result.evidence ?? source.output ?? source.error),
537
+ failedCommands,
538
+ relatedFailures: Array.isArray(result.relatedFailures) ? result.relatedFailures : [],
539
+ unrelatedFailures: Array.isArray(result.unrelatedFailures) ? result.unrelatedFailures : [],
540
+ recoveryAttempts: Array.isArray(result.repairAttempts) ? result.repairAttempts : [],
541
+ alternativesChecked: [],
542
+ authorityFact: `scope=${context.input.scope ?? "unspecified"}; merge=${context.input.merge === true}`,
543
+ };
544
+ }
545
+ function challengeTarget(context) {
546
+ const challenge = context.outputs.challengeBlocker;
547
+ if (challenge.route === "blocked" || challenge.nextStage === null)
548
+ return { route: "blocked" };
549
+ if (challenge.nextStage !== "planDiscovery" && currentPlan(context) === undefined) {
550
+ return { route: "planDiscovery" };
551
+ }
552
+ if (["documentation", "implementation", "repair", "redesign"].includes(challenge.nextStage)) {
553
+ try {
554
+ preparedWorkspace(context);
555
+ }
556
+ catch {
557
+ return { route: "workspace" };
448
558
  }
449
559
  }
450
- throw new Error("No model-generated blocker claim is available to challenge");
560
+ return { route: challenge.nextStage };
451
561
  }
452
562
  function recentWorkflowAttempts(context) {
453
563
  return context.state.steps.slice(-12).map((step) => ({
@@ -487,23 +597,26 @@ function parseFinding(value, severity) {
487
597
  }
488
598
  function parseVerificationForContext(value, context) {
489
599
  const plan = parseVerificationCommandPlan(value);
490
- const implementation = latestOutput(context, ["implement"]);
491
- const reported = Array.isArray(implementation.repositories)
492
- ? implementation.repositories.filter((entry) => typeof entry === "string")
493
- : [];
494
- const request = context.input;
495
- const roots = new Set((reported.length > 0 ? reported : [request.repository ?? process.cwd()]).map((entry) => path.resolve(entry)));
600
+ const root = preparedWorkspace(context).worktreePath ?? preparedWorkspace(context).repository;
496
601
  for (const command of plan.commands) {
497
- const cwd = path.resolve(command.cwd);
498
- if (!roots.delete(cwd)) {
499
- throw new Error(`verification command cwd was not reported by implementation: ${command.cwd}`);
602
+ if (path.resolve(command.cwd) !== path.resolve(root)) {
603
+ throw new Error(`verification command cwd must match the prepared workspace: ${root}`);
500
604
  }
501
605
  }
502
- if (roots.size > 0) {
503
- throw new Error(`verification plan is missing reported repositories: ${[...roots].join(", ")}`);
504
- }
505
606
  return plan;
506
607
  }
608
+ function parsePublishedForContext(value, context) {
609
+ const result = parsePublishedRepositories(value);
610
+ const workspace = preparedWorkspace(context);
611
+ const expected = path.resolve(workspace.worktreePath ?? workspace.repository);
612
+ if (result.repositories[0]?.repository !== expected) {
613
+ throw new Error(`publication repository must match the prepared workspace: ${expected}`);
614
+ }
615
+ if (result.repositories.some((repository) => repository.repository !== expected)) {
616
+ throw new Error("publication cannot include an unprepared repository");
617
+ }
618
+ return result;
619
+ }
507
620
  function currentPublishedRepositories(context) {
508
621
  return latestOutput(context, ["verifyP2", "publish"]);
509
622
  }
@@ -807,7 +920,15 @@ function ciForOutput(context) {
807
920
  return aggregate;
808
921
  }
809
922
  function latestBlockedReason(context) {
923
+ for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
924
+ const step = context.state.steps[index];
925
+ if (step?.nodeId === "createBlockerClaim" && step.outcome === "ok") {
926
+ const claim = step.output;
927
+ return { reason: claim.reason, evidence: claim };
928
+ }
929
+ }
810
930
  const candidates = [
931
+ "createBlockerClaim",
811
932
  "timeoutFallbackGuard",
812
933
  "timeoutFallback",
813
934
  "challengeBlockerGuard",
@@ -847,8 +968,28 @@ export const autoimplementWorkflow = defineWorkflow({
847
968
  title: ({ input }) => `autoimplement: ${input.task.slice(0, 60)}`,
848
969
  presentationPrompt: "Summarize what was implemented, the review rounds by severity, the CI result, the PR or merge result, and any remaining limitation. Include exact validation commands.",
849
970
  startAt: "prepare",
850
- maxSteps: 240,
971
+ maxSteps: 320,
851
972
  includes: {
973
+ workspace: includeWorkflow(workspacePreparationWorkflow, {
974
+ input: (context) => {
975
+ const request = context.input;
976
+ if (request.repository === undefined) {
977
+ throw new Error("autoimplement workspace preparation requires an absolute repository");
978
+ }
979
+ return {
980
+ repository: request.repository,
981
+ ...(request.baseBranch === undefined ? {} : { baseBranch: request.baseBranch }),
982
+ ...(request.scope === undefined ? {} : { scope: request.scope }),
983
+ ...(request.workspaceMode === undefined ? {} : { workspaceMode: request.workspaceMode }),
984
+ ...(request.directDefaultBranchAuthorized === undefined
985
+ ? {}
986
+ : { directDefaultBranchAuthorized: request.directDefaultBranchAuthorized }),
987
+ ...(request.preparedWorkspace === undefined
988
+ ? {}
989
+ : { preparedWorkspace: request.preparedWorkspace }),
990
+ };
991
+ },
992
+ }),
852
993
  documentation: includeWorkflow(autodocWorkflow, {
853
994
  input: (context) => {
854
995
  const request = context.input;
@@ -860,11 +1001,48 @@ export const autoimplementWorkflow = defineWorkflow({
860
1001
  task: request.task,
861
1002
  plan,
862
1003
  ...(request.repository !== undefined ? { repository: request.repository } : {}),
1004
+ ...(request.baseBranch !== undefined ? { baseBranch: request.baseBranch } : {}),
1005
+ ...(request.scope !== undefined ? { scope: request.scope } : {}),
1006
+ ...(request.directDefaultBranchAuthorized === undefined
1007
+ ? {}
1008
+ : { directDefaultBranchAuthorized: request.directDefaultBranchAuthorized }),
1009
+ preparedWorkspace: preparedWorkspace(context),
1010
+ ...(request.verificationChecks === undefined
1011
+ ? {}
1012
+ : { verificationChecks: request.verificationChecks }),
863
1013
  documents: request.documents ?? request.documentation?.documents ?? discovery?.documents ?? [],
864
1014
  evidence: latestIssue(context),
865
1015
  };
866
1016
  },
867
1017
  }),
1018
+ localVerification: includeWorkflow(changeVerificationWorkflow, {
1019
+ input: (context) => {
1020
+ const request = context.input;
1021
+ const plan = request.verificationChecks === undefined
1022
+ ? latestOutput(context, ["planVerification"])
1023
+ : { commands: [], untested: [] };
1024
+ const implementation = latestOutput(context, ["implement"]);
1025
+ return {
1026
+ originatingWorkflow: "autoimplement",
1027
+ qualifiedNode: "autoimplement/localVerification",
1028
+ workspace: preparedWorkspace(context),
1029
+ checks: request.verificationChecks ??
1030
+ plan.commands.map((command) => ({
1031
+ ...command,
1032
+ readOnly: true,
1033
+ baseEligible: true,
1034
+ changedFileScope: false,
1035
+ findingFormat: "text",
1036
+ })),
1037
+ changedFiles: Array.isArray(implementation.files)
1038
+ ? implementation.files.filter((file) => typeof file === "string")
1039
+ : [],
1040
+ untested: plan.untested,
1041
+ plan: currentPlan(context),
1042
+ maxConcurrency: concurrency(context).verification,
1043
+ };
1044
+ },
1045
+ }),
868
1046
  redesign: includeWorkflow(planChangeWorkflow, {
869
1047
  input: (context) => {
870
1048
  const request = context.input;
@@ -872,7 +1050,14 @@ export const autoimplementWorkflow = defineWorkflow({
872
1050
  task: request.task,
873
1051
  ...(request.scope !== undefined ? { scope: request.scope } : {}),
874
1052
  ...(request.constraints !== undefined ? { constraints: request.constraints } : {}),
875
- ...(request.repository !== undefined ? { repository: request.repository } : {}),
1053
+ repository: request.repository,
1054
+ preparedWorkspace: preparedWorkspace(context),
1055
+ ...(request.directDefaultBranchAuthorized === undefined
1056
+ ? {}
1057
+ : { directDefaultBranchAuthorized: request.directDefaultBranchAuthorized }),
1058
+ ...(request.verificationChecks === undefined
1059
+ ? {}
1060
+ : { verificationChecks: request.verificationChecks }),
876
1061
  documents: request.documents ?? request.documentation?.documents ?? [],
877
1062
  ...(currentPlan(context) !== undefined ? { previousPlan: currentPlan(context) } : {}),
878
1063
  newEvidence: latestIssue(context),
@@ -895,13 +1080,7 @@ export const autoimplementWorkflow = defineWorkflow({
895
1080
  prepare: compute({
896
1081
  run: ({ input }) => {
897
1082
  const request = input;
898
- return {
899
- route: request.plan === undefined
900
- ? "find"
901
- : request.documentation?.status === "current"
902
- ? "ready"
903
- : "document",
904
- };
1083
+ return { route: request.plan === undefined ? "find" : "workspace" };
905
1084
  },
906
1085
  }),
907
1086
  findPlan: agent({
@@ -929,13 +1108,26 @@ export const autoimplementWorkflow = defineWorkflow({
929
1108
  return { route: "blocked", reason: discovered.reason, evidence: discovered.evidence };
930
1109
  }
931
1110
  return {
932
- route: discovered.documentation === "current" ? "ready" : "document",
1111
+ route: "workspace",
933
1112
  plan: discovered.plan,
1113
+ documentation: discovered.documentation,
934
1114
  reason: discovered.reason,
935
1115
  evidence: discovered.evidence,
936
1116
  };
937
1117
  },
938
1118
  }),
1119
+ routeWorkspace: compute({
1120
+ run: ({ input, outputs }) => {
1121
+ const request = input;
1122
+ const discovered = outputs.findPlan;
1123
+ return {
1124
+ route: request.documentation?.status === "current" || discovered?.documentation === "current"
1125
+ ? "implement"
1126
+ : "document",
1127
+ workspace: preparedWorkspace({ input, outputs }),
1128
+ };
1129
+ },
1130
+ }),
939
1131
  adoptPlan: compute({
940
1132
  run: ({ outputs }) => {
941
1133
  const result = includedResult(planChangeWorkflow, outputs.redesign);
@@ -963,10 +1155,10 @@ export const autoimplementWorkflow = defineWorkflow({
963
1155
  .filter((step) => step.nodeId === "timeoutFallback" && step.outcome === "ok")
964
1156
  .map((step) => step.output);
965
1157
  return [
966
- "A bounded Autoimplement agent step timed out. Choose the safest existing workflow stage to run next instead of ending the run blindly.",
1158
+ "A bounded Autoimplement step failed or timed out. Choose the safest existing workflow stage to run next instead of ending the run blindly.",
967
1159
  "This is a read-only fallback step. Inspect state, but do not edit files, run mutating commands, commit, push, open or update a pull request, post comments, merge, deploy, or release.",
968
1160
  "Inspect the current repository worktree, branch, diff, and commits. Inspect the remote branch, pull request, review, CI, merge, and final report when they exist and affect the next route.",
969
- "Do not assume that the timed-out step failed or completed. Use accepted workflow outputs and durable repository or pull-request state.",
1161
+ "Do not assume that a mutating step failed or completed. Observe durable repository or pull-request state first, adopt an effect that already completed, and retry only a missing effect.",
970
1162
  "Before any forward route, confirm that its accepted output belongs to the current work attempt and that observed local and remote heads match the accepted publication. Otherwise retry, replan, or block.",
971
1163
  "Choose retry only when the timed-out stage must run again. Choose verify when accepted implementation output exists and verification is next. Choose review when accepted publication output exists. Choose ci only after comment inspection routed to CI. Choose deliver only after CI is green or classified unrelated. Choose replan when evidence invalidates the approved plan. Choose blocked only when no safe route exists.",
972
1164
  "Do not skip required implementation, verification, review, CI, authorization, or delivery checks.",
@@ -985,9 +1177,6 @@ export const autoimplementWorkflow = defineWorkflow({
985
1177
  routeTimeoutFallback: compute({
986
1178
  run: timeoutFallbackTarget,
987
1179
  }),
988
- propagateSupportedFailure: compute({
989
- run: throwLatestSupportedFailure,
990
- }),
991
1180
  routeVerifyP2Result: compute({
992
1181
  run: ({ outputs }) => outputs.verifyP2,
993
1182
  }),
@@ -1010,6 +1199,8 @@ export const autoimplementWorkflow = defineWorkflow({
1010
1199
  `Plan: ${JSON.stringify(currentPlan(context))}`,
1011
1200
  `Authorized scope: ${request.scope ?? request.repository ?? "the current repository and task"}`,
1012
1201
  `Constraints: ${JSON.stringify(request.constraints ?? [])}`,
1202
+ `Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
1203
+ "Use the prepared absolute workspace path for every read, edit, command, and report. Do not fall back to the Pi process working directory.",
1013
1204
  "Before changing files, inspect the current worktree, diff, commits, branch, remote state, and matching pull request. Continue existing work and do not repeat completed effects.",
1014
1205
  "Follow repository instructions and use the most elegant long-term production-ready implementation without unnecessary work.",
1015
1206
  "If implementation exposes a new design or scope problem, report it precisely instead of forcing the old plan.",
@@ -1033,6 +1224,17 @@ export const autoimplementWorkflow = defineWorkflow({
1033
1224
  expectedOutput: `{ "route": "verify" | "redesign" | "fix" | "blocked", "summary": "reason", "evidence": "evidence" }`,
1034
1225
  validate: (value) => parseRoute(value, ["verify", "redesign", "fix", "blocked"], "implementation assessment"),
1035
1226
  }),
1227
+ createBlockerClaim: compute({
1228
+ run: createBlockerClaim,
1229
+ }),
1230
+ routeBlockerClaim: compute({
1231
+ run: ({ outputs }) => {
1232
+ const claim = outputs.createBlockerClaim;
1233
+ return {
1234
+ route: claim.sourceNode === "challengeBlockerGuard" ? "blocked" : "challenge",
1235
+ };
1236
+ },
1237
+ }),
1036
1238
  challengeBlockerGuard: compute({
1037
1239
  run: (context) => {
1038
1240
  const challenges = blockerChallenges(context);
@@ -1064,7 +1266,8 @@ export const autoimplementWorkflow = defineWorkflow({
1064
1266
  "A local test failure, stale package, packaging or artifact mismatch, rollback preparation, or deployment procedure is not by itself outside authority.",
1065
1267
  "If a safe deployment and rollback path is already authorized, a supported cutover is work to do, not a blocker.",
1066
1268
  "Confirm blocked only when the issue blocks progress now, is outside authority, and has no safe practical path forward.",
1067
- "Return continue with the next practical action when work can proceed. Keep text concise, with at most five alternatives and five evidence items.",
1269
+ "Return continue with the next practical action and its exact nextStage: planDiscovery, documentation, implementation, repair, review, ci, delivery, or redesign.",
1270
+ "Keep text concise, with at most five alternatives and five evidence items.",
1068
1271
  `Task: ${request.task}`,
1069
1272
  `Approved plan: ${JSON.stringify(currentPlan(context))}`,
1070
1273
  `Current result and claimed blocker: ${JSON.stringify(latestBlockerClaim(context))}`,
@@ -1075,58 +1278,62 @@ export const autoimplementWorkflow = defineWorkflow({
1075
1278
  `Recent workflow attempts: ${JSON.stringify(recentWorkflowAttempts(context))}`,
1076
1279
  ].join("\n");
1077
1280
  },
1078
- expectedOutput: `{ "route": "continue" | "blocked", "blockingNow": true | false, "outsideAuthority": true | false, "canProceed": true | false, "reason": "concise reason", "nextAction": "practical action or empty when blocked", "alternativesChecked": ["checked alternative"], "evidence": ["concrete evidence"] }`,
1281
+ expectedOutput: `{ "route": "continue" | "blocked", "blockingNow": true | false, "outsideAuthority": true | false, "canProceed": true | false, "reason": "concise reason", "nextAction": "practical action or empty when blocked", "nextStage": "planDiscovery" | "documentation" | "implementation" | "repair" | "review" | "ci" | "delivery" | "redesign" | null, "alternativesChecked": ["checked alternative"], "evidence": ["concrete evidence"] }`,
1079
1282
  validate: parseBlockerChallenge,
1080
1283
  }),
1284
+ routeChallenge: compute({ run: challengeTarget }),
1285
+ selectVerificationPath: compute({
1286
+ run: ({ input }) => ({
1287
+ route: input.verificationChecks === undefined ? "plan" : "verify",
1288
+ }),
1289
+ }),
1081
1290
  planVerification: agent({
1082
1291
  timeoutMs: 15 * 60_000,
1083
1292
  statusDetail: "planning independent verification commands",
1084
- prompt: () => [
1085
- "Select the required local verification commands for the implementation.",
1086
- "Return one command per independent repository working directory.",
1293
+ prompt: (context) => [
1294
+ "Select all required local verification commands for the implementation.",
1295
+ "Return one or more commands for the prepared repository workspace.",
1087
1296
  "Use exact executables and argument arrays without shell wrappers, environment overrides, stdin, Git or GitHub mutations, package publication, deployment, merge, or release commands.",
1088
- "Use absolute repository paths, explicit timeouts no longer than 2700000ms, and maxOutputChars no larger than 1000000.",
1297
+ "Use the prepared absolute workspace path as cwd for every command, explicit timeouts no longer than 2700000ms, and maxOutputChars no larger than 1000000.",
1089
1298
  "List checks that cannot run locally under untested.",
1299
+ `Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
1090
1300
  ].join("\n"),
1091
1301
  expectedOutput: `{ "commands": [{ "id": "stable-id", "command": "npm", "args": ["run", "check"], "cwd": "/absolute/repository", "timeoutMs": 2700000, "maxOutputChars": 1000000 }], "untested": ["remaining check"] }`,
1092
1302
  validate: parseVerificationForContext,
1093
1303
  }),
1094
- runVerification: action({
1095
- timeoutMs: (context) => {
1096
- const plan = latestOutput(context, ["planVerification"]);
1097
- return commandBatchTimeoutMs(plan.commands, concurrency(context).verification);
1098
- },
1099
- statusDetail: "running independent verification commands",
1100
- run: async (context) => {
1101
- const plan = latestOutput(context, ["planVerification"]);
1102
- return await runAutoimplementBatch(context, "verification", plan.commands, concurrency(context).verification);
1103
- },
1304
+ routeVerifiedWorkspace: compute({
1305
+ run: (context) => ({
1306
+ route: preparedWorkspace(context).mode === "defaultBranch" ? "defaultBranch" : "pullRequest",
1307
+ }),
1104
1308
  }),
1105
- verify: agent({
1106
- timeoutMs: 20 * 60_000,
1107
- statusDetail: "assessing verification",
1108
- prompt: (context) => [
1109
- "Assess the completed local verification commands.",
1110
- "Set passed true only when every required command succeeded without truncated output.",
1111
- "Report exact command outcomes, failures, and checks that still need remote verification.",
1112
- `Command plan: ${JSON.stringify(latestOutput(context, ["planVerification"]))}`,
1113
- `Command results: ${JSON.stringify(latestOutput(context, ["runVerification"]))}`,
1114
- ].join("\n"),
1115
- expectedOutput: `{ "passed": true | false, "commands": [{ "command": "exact command", "outcome": "result" }], "failures": ["failure"], "untested": ["remaining check"] }`,
1116
- validate: (value) => requireRecord(value, "verification result"),
1309
+ routeFinalizeDefaultBranchResult: compute({
1310
+ run: ({ outputs }) => outputs.finalizeDefaultBranch,
1117
1311
  }),
1118
- classifyVerification: agent({
1119
- statusDetail: "classifying verification",
1120
- prompt: ({ outputs }) => [
1121
- "Classify the verification result.",
1122
- "Choose publish when required local checks passed.",
1123
- "Choose redesign for evidence that invalidates the plan.",
1124
- "Choose fix for a local implementation or test issue.",
1125
- "Choose blocked only when the work cannot continue in scope.",
1126
- `Verification: ${JSON.stringify(outputs.verify)}`,
1127
- ].join("\n"),
1128
- expectedOutput: `{ "route": "publish" | "redesign" | "fix" | "blocked", "summary": "reason", "evidence": "evidence" }`,
1129
- validate: (value) => parseRoute(value, ["publish", "redesign", "fix", "blocked"], "verification assessment"),
1312
+ finalizeDefaultBranch: agent({
1313
+ timeoutMs: 30 * 60_000,
1314
+ statusDetail: "finalizing default-branch work",
1315
+ prompt: (context) => {
1316
+ const request = context.input;
1317
+ return [
1318
+ "Finalize verified work in the explicitly authorized default-branch workspace.",
1319
+ "Never open a pull request from the default branch to itself.",
1320
+ "Commit and push only when the authorized scope explicitly allows each action. Otherwise leave the verified local change and report it.",
1321
+ "Do not merge, release, or deploy.",
1322
+ `Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
1323
+ `Authorized scope: ${request.scope}`,
1324
+ ].join("\n");
1325
+ },
1326
+ expectedOutput: `{ "status": "completed" | "blocked", "committed": true | false, "pushed": true | false, "merged": false, "pr": "none", "reportComment": "summary", "reason": "result" }`,
1327
+ validate: (value) => {
1328
+ const result = requireRecord(value, "default-branch delivery");
1329
+ if (result.status !== "completed" && result.status !== "blocked") {
1330
+ throw new Error("default-branch delivery status must be completed or blocked");
1331
+ }
1332
+ if (result.merged !== false || result.pr !== "none") {
1333
+ throw new Error("default-branch delivery cannot merge or open a pull request to itself");
1334
+ }
1335
+ return result;
1336
+ },
1130
1337
  }),
1131
1338
  fix: agent({
1132
1339
  timeoutMs: 45 * 60_000,
@@ -1136,6 +1343,7 @@ export const autoimplementWorkflow = defineWorkflow({
1136
1343
  "Inspect the current diff and commits first. Continue any partial fix and change only work that is still missing.",
1137
1344
  `Issue: ${JSON.stringify(latestIssue(context))}`,
1138
1345
  `Current plan: ${JSON.stringify(currentPlan(context))}`,
1346
+ `Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
1139
1347
  "Stop after the fix so verification can run again.",
1140
1348
  ].join("\n"),
1141
1349
  expectedOutput: `{ "fixed": "what changed", "files": ["changed file"] }`,
@@ -1144,8 +1352,8 @@ export const autoimplementWorkflow = defineWorkflow({
1144
1352
  publish: agent({
1145
1353
  timeoutMs: 30 * 60_000,
1146
1354
  statusDetail: "committing and pushing",
1147
- prompt: ({ input }) => {
1148
- const request = input;
1355
+ prompt: (context) => {
1356
+ const request = context.input;
1149
1357
  return [
1150
1358
  "Commit and push the verified implementation before review.",
1151
1359
  "Inspect the branch, local and remote heads, and matching pull requests first. Do not push an already-pushed head or create a second pull request for the same branch and base.",
@@ -1154,11 +1362,12 @@ export const autoimplementWorkflow = defineWorkflow({
1154
1362
  "Report every repository that received a pushed pull request with its absolute repository path, branch, base branch, pushed head revision, and PR URL.",
1155
1363
  "Include dependencyFingerprint only when a declared dependency result is relevant to review reuse.",
1156
1364
  `Requested base branch: ${request.baseBranch ?? "discover each repository default branch"}.`,
1365
+ `Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
1157
1366
  "Do not merge yet.",
1158
1367
  ].join("\n");
1159
1368
  },
1160
1369
  expectedOutput: `{ "repositories": [{ "repository": "/absolute/repository", "branch": "branch", "baseBranch": "base", "headRevision": "revision", "pr": "URL", "pushed": true, "dependencyFingerprint": "optional digest" }] }`,
1161
- validate: parsePublishedRepositories,
1370
+ validate: parsePublishedForContext,
1162
1371
  }),
1163
1372
  selectReviewCommands: compute({
1164
1373
  run: selectReviewCommands,
@@ -1374,10 +1583,20 @@ export const autoimplementWorkflow = defineWorkflow({
1374
1583
  task: request.task,
1375
1584
  plan: currentPlan(context),
1376
1585
  implementation: latestOutput(context, ["implement"]),
1377
- verification: latestOutput(context, ["verifyP2", "verify"]),
1378
- reviewRounds: reviewRoundsForOutput(context),
1379
- ci: ciForOutput(context),
1380
- delivery: latestOutput(context, ["finalizeDelivery"]),
1586
+ verification: context.outputs.localVerification === undefined
1587
+ ? latestOutput(context, ["verifyP2"])
1588
+ : includedResult(changeVerificationWorkflow, context.outputs.localVerification)
1589
+ .output,
1590
+ reviewRounds: context.outputs.finalizeDefaultBranch === undefined
1591
+ ? reviewRoundsForOutput(context)
1592
+ : [],
1593
+ ci: context.outputs.finalizeDefaultBranch === undefined
1594
+ ? ciForOutput(context)
1595
+ : {
1596
+ route: "notApplicable",
1597
+ reason: "Direct default-branch work has no pull request.",
1598
+ },
1599
+ delivery: latestOutput(context, ["finalizeDefaultBranch", "finalizeDelivery"]),
1381
1600
  };
1382
1601
  },
1383
1602
  }),
@@ -1385,33 +1604,41 @@ export const autoimplementWorkflow = defineWorkflow({
1385
1604
  edges: [
1386
1605
  {
1387
1606
  from: "prepare",
1388
- switch: {
1389
- on: "$.route",
1390
- cases: { find: "findPlan", document: "documentation", ready: "implement" },
1391
- },
1607
+ switch: { on: "$.route", cases: { find: "findPlan", workspace: "workspace" } },
1392
1608
  },
1393
1609
  {
1394
1610
  from: "findPlan",
1395
- switch: { on: "$.route", cases: { found: "routeFoundPlan", blocked: "blocked" } },
1611
+ switch: {
1612
+ on: "$.route",
1613
+ cases: { found: "routeFoundPlan", blocked: "createBlockerClaim" },
1614
+ },
1396
1615
  },
1397
1616
  {
1398
1617
  from: "routeFoundPlan",
1399
1618
  switch: {
1400
1619
  on: "$.route",
1401
- cases: { ready: "implement", document: "documentation", blocked: "blocked" },
1620
+ cases: { workspace: "workspace", blocked: "createBlockerClaim" },
1402
1621
  },
1403
1622
  },
1623
+ { from: "workspace.ready", to: "routeWorkspace" },
1624
+ { from: "workspace.blocked", to: "createBlockerClaim" },
1625
+ {
1626
+ from: "routeWorkspace",
1627
+ switch: { on: "$.route", cases: { implement: "implement", document: "documentation" } },
1628
+ },
1404
1629
  { from: "redesign.ready", to: "adoptPlan" },
1405
1630
  { from: "redesign.blocked", to: "blocked" },
1406
1631
  { from: "adoptPlan", to: "implement" },
1407
1632
  { from: "documentation.ready", to: "implement" },
1408
- { from: "documentation.blocked", to: "blocked" },
1633
+ { from: "documentation.blocked", to: "createBlockerClaim" },
1409
1634
  {
1410
1635
  from: "timeoutFallbackGuard",
1411
- switch: { on: "$.route", cases: { recover: "timeoutFallback", blocked: "blocked" } },
1636
+ switch: {
1637
+ on: "$.route",
1638
+ cases: { recover: "timeoutFallback", blocked: "createBlockerClaim" },
1639
+ },
1412
1640
  },
1413
1641
  { from: "timeoutFallback", to: "routeTimeoutFallback" },
1414
- { from: "propagateSupportedFailure", to: "blocked" },
1415
1642
  {
1416
1643
  from: "routeTimeoutFallback",
1417
1644
  switch: {
@@ -1419,7 +1646,6 @@ export const autoimplementWorkflow = defineWorkflow({
1419
1646
  cases: {
1420
1647
  implement: "implement",
1421
1648
  planVerification: "planVerification",
1422
- verify: "verify",
1423
1649
  fix: "fix",
1424
1650
  publish: "publish",
1425
1651
  addressP2: "addressP2",
@@ -1427,10 +1653,11 @@ export const autoimplementWorkflow = defineWorkflow({
1427
1653
  inspectComments: "inspectComments",
1428
1654
  inspectCi: "inspectCi",
1429
1655
  opportunisticTest: "opportunisticTest",
1656
+ finalizeDefaultBranch: "finalizeDefaultBranch",
1430
1657
  finalizeDelivery: "finalizeDelivery",
1431
1658
  selectReviewCommands: "selectReviewCommands",
1432
1659
  redesign: "redesign",
1433
- blocked: "blocked",
1660
+ blocked: "createBlockerClaim",
1434
1661
  },
1435
1662
  },
1436
1663
  },
@@ -1441,7 +1668,7 @@ export const autoimplementWorkflow = defineWorkflow({
1441
1668
  cases: {
1442
1669
  ok: "classifyImplementation",
1443
1670
  timed_out: "timeoutFallbackGuard",
1444
- failed: "propagateSupportedFailure",
1671
+ failed: "timeoutFallbackGuard",
1445
1672
  },
1446
1673
  },
1447
1674
  },
@@ -1450,64 +1677,100 @@ export const autoimplementWorkflow = defineWorkflow({
1450
1677
  switch: {
1451
1678
  on: "$.route",
1452
1679
  cases: {
1453
- verify: "planVerification",
1680
+ verify: "selectVerificationPath",
1454
1681
  redesign: "redesign",
1455
1682
  fix: "fix",
1456
- blocked: "challengeBlockerGuard",
1683
+ blocked: "createBlockerClaim",
1457
1684
  },
1458
1685
  },
1459
1686
  },
1687
+ { from: "createBlockerClaim", to: "routeBlockerClaim" },
1688
+ {
1689
+ from: "routeBlockerClaim",
1690
+ switch: {
1691
+ on: "$.route",
1692
+ cases: { challenge: "challengeBlockerGuard", blocked: "blocked" },
1693
+ },
1694
+ },
1460
1695
  {
1461
1696
  from: "challengeBlockerGuard",
1462
- switch: { on: "$.route", cases: { challenge: "challengeBlocker", blocked: "blocked" } },
1697
+ switch: {
1698
+ on: "$.route",
1699
+ cases: { challenge: "challengeBlocker", blocked: "createBlockerClaim" },
1700
+ },
1463
1701
  },
1464
1702
  {
1465
1703
  from: "challengeBlocker",
1466
- switch: { on: "$.route", cases: { continue: "redesign", blocked: "blocked" } },
1704
+ switch: { on: "$.route", cases: { continue: "routeChallenge", blocked: "blocked" } },
1467
1705
  },
1468
1706
  {
1469
- from: "planVerification",
1707
+ from: "routeChallenge",
1470
1708
  switch: {
1471
- on: "$result.outcome",
1709
+ on: "$.route",
1472
1710
  cases: {
1473
- ok: "runVerification",
1474
- timed_out: "timeoutFallbackGuard",
1475
- failed: "propagateSupportedFailure",
1711
+ planDiscovery: "findPlan",
1712
+ workspace: "workspace",
1713
+ documentation: "documentation",
1714
+ implementation: "implement",
1715
+ repair: "fix",
1716
+ review: "selectReviewCommands",
1717
+ ci: "inspectCi",
1718
+ delivery: "finalizeDelivery",
1719
+ redesign: "redesign",
1720
+ blocked: "blocked",
1476
1721
  },
1477
1722
  },
1478
1723
  },
1479
- { from: "runVerification", to: "verify" },
1480
1724
  {
1481
- from: "verify",
1725
+ from: "selectVerificationPath",
1726
+ switch: { on: "$.route", cases: { plan: "planVerification", verify: "localVerification" } },
1727
+ },
1728
+ {
1729
+ from: "planVerification",
1482
1730
  switch: {
1483
1731
  on: "$result.outcome",
1484
1732
  cases: {
1485
- ok: "classifyVerification",
1733
+ ok: "localVerification",
1486
1734
  timed_out: "timeoutFallbackGuard",
1487
- failed: "propagateSupportedFailure",
1735
+ failed: "timeoutFallbackGuard",
1488
1736
  },
1489
1737
  },
1490
1738
  },
1739
+ { from: "localVerification.ready", to: "routeVerifiedWorkspace" },
1740
+ { from: "localVerification.blocked", to: "createBlockerClaim" },
1491
1741
  {
1492
- from: "classifyVerification",
1742
+ from: "routeVerifiedWorkspace",
1493
1743
  switch: {
1494
1744
  on: "$.route",
1745
+ cases: { pullRequest: "publish", defaultBranch: "finalizeDefaultBranch" },
1746
+ },
1747
+ },
1748
+ {
1749
+ from: "finalizeDefaultBranch",
1750
+ switch: {
1751
+ on: "$result.outcome",
1495
1752
  cases: {
1496
- publish: "publish",
1497
- redesign: "redesign",
1498
- fix: "fix",
1499
- blocked: "challengeBlockerGuard",
1753
+ ok: "routeFinalizeDefaultBranchResult",
1754
+ timed_out: "timeoutFallbackGuard",
1755
+ failed: "timeoutFallbackGuard",
1500
1756
  },
1501
1757
  },
1502
1758
  },
1759
+ {
1760
+ from: "routeFinalizeDefaultBranchResult",
1761
+ switch: {
1762
+ on: "$.status",
1763
+ cases: { completed: "finalize", blocked: "createBlockerClaim" },
1764
+ },
1765
+ },
1503
1766
  {
1504
1767
  from: "fix",
1505
1768
  switch: {
1506
1769
  on: "$result.outcome",
1507
1770
  cases: {
1508
- ok: "planVerification",
1771
+ ok: "selectVerificationPath",
1509
1772
  timed_out: "timeoutFallbackGuard",
1510
- failed: "propagateSupportedFailure",
1773
+ failed: "timeoutFallbackGuard",
1511
1774
  },
1512
1775
  },
1513
1776
  },
@@ -1518,7 +1781,7 @@ export const autoimplementWorkflow = defineWorkflow({
1518
1781
  cases: {
1519
1782
  ok: "selectReviewCommands",
1520
1783
  timed_out: "timeoutFallbackGuard",
1521
- failed: "propagateSupportedFailure",
1784
+ failed: "timeoutFallbackGuard",
1522
1785
  },
1523
1786
  },
1524
1787
  },
@@ -1534,7 +1797,7 @@ export const autoimplementWorkflow = defineWorkflow({
1534
1797
  from: "repairReviewCommand",
1535
1798
  switch: {
1536
1799
  on: "$.route",
1537
- cases: { retry: "runReview", blocked: "challengeBlockerGuard" },
1800
+ cases: { retry: "runReview", blocked: "createBlockerClaim" },
1538
1801
  },
1539
1802
  },
1540
1803
  {
@@ -1560,7 +1823,7 @@ export const autoimplementWorkflow = defineWorkflow({
1560
1823
  cases: {
1561
1824
  ok: "verifyP2",
1562
1825
  timed_out: "timeoutFallbackGuard",
1563
- failed: "propagateSupportedFailure",
1826
+ failed: "timeoutFallbackGuard",
1564
1827
  },
1565
1828
  },
1566
1829
  },
@@ -1571,7 +1834,7 @@ export const autoimplementWorkflow = defineWorkflow({
1571
1834
  cases: {
1572
1835
  ok: "routeVerifyP2Result",
1573
1836
  timed_out: "timeoutFallbackGuard",
1574
- failed: "propagateSupportedFailure",
1837
+ failed: "timeoutFallbackGuard",
1575
1838
  },
1576
1839
  },
1577
1840
  },
@@ -1586,7 +1849,7 @@ export const autoimplementWorkflow = defineWorkflow({
1586
1849
  cases: {
1587
1850
  ok: "routeInspectCommentsResult",
1588
1851
  timed_out: "timeoutFallbackGuard",
1589
- failed: "propagateSupportedFailure",
1852
+ failed: "timeoutFallbackGuard",
1590
1853
  },
1591
1854
  },
1592
1855
  },
@@ -1598,7 +1861,7 @@ export const autoimplementWorkflow = defineWorkflow({
1598
1861
  redesign: "redesign",
1599
1862
  fix: "fix",
1600
1863
  ci: "inspectCi",
1601
- blocked: "challengeBlockerGuard",
1864
+ blocked: "createBlockerClaim",
1602
1865
  },
1603
1866
  },
1604
1867
  },
@@ -1609,7 +1872,7 @@ export const autoimplementWorkflow = defineWorkflow({
1609
1872
  cases: {
1610
1873
  ok: "routeInspectCiResult",
1611
1874
  timed_out: "timeoutFallbackGuard",
1612
- failed: "propagateSupportedFailure",
1875
+ failed: "timeoutFallbackGuard",
1613
1876
  },
1614
1877
  },
1615
1878
  },
@@ -1621,7 +1884,7 @@ export const autoimplementWorkflow = defineWorkflow({
1621
1884
  green: "finalizeDelivery",
1622
1885
  failed: "classifyCi",
1623
1886
  pending: "trackCi",
1624
- unavailable: "challengeBlockerGuard",
1887
+ unavailable: "createBlockerClaim",
1625
1888
  },
1626
1889
  },
1627
1890
  },
@@ -1633,7 +1896,7 @@ export const autoimplementWorkflow = defineWorkflow({
1633
1896
  from: "repairCiCommand",
1634
1897
  switch: {
1635
1898
  on: "$.route",
1636
- cases: { retry: "trackCi", blocked: "challengeBlockerGuard" },
1899
+ cases: { retry: "trackCi", blocked: "createBlockerClaim" },
1637
1900
  },
1638
1901
  },
1639
1902
  {
@@ -1644,7 +1907,7 @@ export const autoimplementWorkflow = defineWorkflow({
1644
1907
  green: "finalizeDelivery",
1645
1908
  failed: "classifyCi",
1646
1909
  pending: "opportunisticTest",
1647
- unavailable: "challengeBlockerGuard",
1910
+ unavailable: "createBlockerClaim",
1648
1911
  },
1649
1912
  },
1650
1913
  },
@@ -1655,7 +1918,7 @@ export const autoimplementWorkflow = defineWorkflow({
1655
1918
  cases: {
1656
1919
  ok: "inspectCi",
1657
1920
  timed_out: "timeoutFallbackGuard",
1658
- failed: "propagateSupportedFailure",
1921
+ failed: "timeoutFallbackGuard",
1659
1922
  },
1660
1923
  },
1661
1924
  },
@@ -1667,7 +1930,7 @@ export const autoimplementWorkflow = defineWorkflow({
1667
1930
  redesign: "redesign",
1668
1931
  fix: "fix",
1669
1932
  unrelated: "finalizeDelivery",
1670
- blocked: "challengeBlockerGuard",
1933
+ blocked: "createBlockerClaim",
1671
1934
  },
1672
1935
  },
1673
1936
  },
@@ -1678,7 +1941,7 @@ export const autoimplementWorkflow = defineWorkflow({
1678
1941
  cases: {
1679
1942
  ok: "routeFinalizeDeliveryResult",
1680
1943
  timed_out: "timeoutFallbackGuard",
1681
- failed: "propagateSupportedFailure",
1944
+ failed: "timeoutFallbackGuard",
1682
1945
  },
1683
1946
  },
1684
1947
  },
@@ -1686,7 +1949,7 @@ export const autoimplementWorkflow = defineWorkflow({
1686
1949
  from: "routeFinalizeDeliveryResult",
1687
1950
  switch: {
1688
1951
  on: "$.status",
1689
- cases: { completed: "finalize", blocked: "challengeBlockerGuard" },
1952
+ cases: { completed: "finalize", blocked: "createBlockerClaim" },
1690
1953
  },
1691
1954
  },
1692
1955
  ],