@osolmaz/pi-workflows 0.12.1 → 0.13.1
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.
- package/README.md +59 -33
- package/dist/builtins/autodoc.workflow.d.ts +194 -7
- package/dist/builtins/autodoc.workflow.js +156 -30
- package/dist/builtins/autodoc.workflow.js.map +1 -1
- package/dist/builtins/autoimplement-command-batches.d.ts +1 -0
- package/dist/builtins/autoimplement-command-batches.js +29 -31
- package/dist/builtins/autoimplement-command-batches.js.map +1 -1
- package/dist/builtins/autoimplement.workflow.d.ts +1619 -97
- package/dist/builtins/autoimplement.workflow.js +416 -153
- package/dist/builtins/autoimplement.workflow.js.map +1 -1
- package/dist/builtins/autoplan.workflow.d.ts +126 -13
- package/dist/builtins/autoplan.workflow.js +200 -29
- package/dist/builtins/autoplan.workflow.js.map +1 -1
- package/dist/builtins/catalog.js +7 -5
- package/dist/builtins/catalog.js.map +1 -1
- package/dist/builtins/change-verification.workflow.d.ts +110 -0
- package/dist/builtins/change-verification.workflow.js +860 -0
- package/dist/builtins/change-verification.workflow.js.map +1 -0
- package/dist/builtins/index.d.ts +2 -1
- package/dist/builtins/index.js +1 -0
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/monitor.workflow.d.ts +56 -21
- package/dist/builtins/monitor.workflow.js +499 -217
- package/dist/builtins/monitor.workflow.js.map +1 -1
- package/dist/builtins/plain-summary.workflow.d.ts +32 -0
- package/dist/builtins/plain-summary.workflow.js +134 -0
- package/dist/builtins/plain-summary.workflow.js.map +1 -0
- package/dist/builtins/plan-change.workflow.d.ts +527 -26
- package/dist/builtins/plan-change.workflow.js +26 -0
- package/dist/builtins/plan-change.workflow.js.map +1 -1
- package/dist/builtins/sanity-check.workflow.d.ts +45 -3
- package/dist/builtins/sanity-check.workflow.js +45 -7
- package/dist/builtins/sanity-check.workflow.js.map +1 -1
- package/dist/builtins/workspace-preparation.workflow.d.ts +75 -0
- package/dist/builtins/workspace-preparation.workflow.js +498 -0
- package/dist/builtins/workspace-preparation.workflow.js.map +1 -0
- package/dist/controllers/effects.d.ts +3 -2
- package/dist/controllers/effects.js +8 -1
- package/dist/controllers/effects.js.map +1 -1
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/index.js +1 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/manager.d.ts +1 -0
- package/dist/controllers/manager.js +41 -17
- package/dist/controllers/manager.js.map +1 -1
- package/dist/controllers/sqlite.d.ts +107 -85
- package/dist/controllers/sqlite.js +1611 -1486
- package/dist/controllers/sqlite.js.map +1 -1
- package/dist/controllers/store.d.ts +9 -8
- package/dist/controllers/store.js +1 -31
- package/dist/controllers/store.js.map +1 -1
- package/dist/controllers/types.d.ts +3 -0
- package/dist/controllers/workflow-engine-scheduler.d.ts +1 -1
- package/dist/controllers/workflow-engine-scheduler.js +3 -5
- package/dist/controllers/workflow-engine-scheduler.js.map +1 -1
- package/dist/controllers/workflows.d.ts +2 -2
- package/dist/controllers/workflows.js +11 -10
- package/dist/controllers/workflows.js.map +1 -1
- package/dist/extension/controller-host.js +2 -2
- package/dist/extension/controller-host.js.map +1 -1
- package/dist/extension/decision-channels.d.ts +2 -0
- package/dist/extension/decision-channels.js +311 -118
- package/dist/extension/decision-channels.js.map +1 -1
- package/dist/extension/executor.d.ts +9 -2
- package/dist/extension/executor.js +90 -6
- package/dist/extension/executor.js.map +1 -1
- package/dist/extension/herdr-viewer.d.ts +0 -1
- package/dist/extension/herdr-viewer.js +0 -4
- package/dist/extension/herdr-viewer.js.map +1 -1
- package/dist/extension/index.js +156 -117
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/recorder.d.ts +3 -10
- package/dist/extension/recorder.js +13 -22
- package/dist/extension/recorder.js.map +1 -1
- package/dist/extension/step-message.d.ts +7 -2
- package/dist/extension/step-message.js +94 -2
- package/dist/extension/step-message.js.map +1 -1
- package/dist/extension/widget.js +6 -0
- package/dist/extension/widget.js.map +1 -1
- package/dist/host/rpc-executor.d.ts +3 -0
- package/dist/host/rpc-executor.js +2 -0
- package/dist/host/rpc-executor.js.map +1 -1
- package/dist/host/runner.d.ts +3 -6
- package/dist/host/runner.js +83 -32
- package/dist/host/runner.js.map +1 -1
- package/dist/render/graph-render.js +14 -8
- package/dist/render/graph-render.js.map +1 -1
- package/dist/state/database.d.ts +35 -0
- package/dist/state/database.js +287 -0
- package/dist/state/database.js.map +1 -0
- package/dist/state/index.d.ts +4 -0
- package/dist/state/index.js +5 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/json.d.ts +6 -0
- package/dist/state/json.js +38 -0
- package/dist/state/json.js.map +1 -0
- package/dist/state/mutation.d.ts +57 -0
- package/dist/state/mutation.js +255 -0
- package/dist/state/mutation.js.map +1 -0
- package/dist/state/schema.d.ts +6 -0
- package/dist/state/schema.js +473 -0
- package/dist/state/schema.js.map +1 -0
- package/dist/viewer/cli.d.ts +2 -2
- package/dist/viewer/cli.js +142 -122
- package/dist/viewer/cli.js.map +1 -1
- package/dist/viewer/render.d.ts +4 -4
- package/dist/viewer/render.js +2 -17
- package/dist/viewer/render.js.map +1 -1
- package/dist/viewer/session-reducer.d.ts +1 -1
- package/dist/viewer/session-reducer.js +1 -1
- package/dist/viewer/tui.d.ts +3 -3
- package/dist/viewer/tui.js +15 -13
- package/dist/viewer/tui.js.map +1 -1
- package/dist/viewer/watch.d.ts +2 -5
- package/dist/viewer/watch.js +13 -13
- package/dist/viewer/watch.js.map +1 -1
- package/dist/workflows/composition.js +12 -2
- package/dist/workflows/composition.js.map +1 -1
- package/dist/workflows/definition.d.ts +6 -2
- package/dist/workflows/definition.js +17 -0
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/engine.d.ts +6 -6
- package/dist/workflows/engine.js +183 -103
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/errors.d.ts +3 -3
- package/dist/workflows/errors.js +3 -3
- package/dist/workflows/human-decision.d.ts +29 -4
- package/dist/workflows/human-decision.js +547 -283
- package/dist/workflows/human-decision.js.map +1 -1
- package/dist/workflows/index.d.ts +4 -5
- package/dist/workflows/index.js +3 -4
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/schema.js +17 -1
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.d.ts +83 -103
- package/dist/workflows/store.js +902 -951
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +55 -81
- package/docs/CONTROLLERS.md +10 -8
- package/docs/DEFERRED_TURNS.md +2 -2
- package/docs/DESIGN_PHILOSOPHY.md +4 -2
- package/docs/HUMAN_DECISIONS.md +13 -14
- package/docs/MONITOR.md +179 -231
- package/docs/SQLITE_STATE.md +219 -0
- package/docs/WORKFLOW_COMPOSITION.md +27 -19
- package/docs/WORKFLOW_STEP_MESSAGES.md +20 -18
- package/docs/WORKFLOW_UPDATES.md +10 -9
- package/docs/development.md +9 -9
- package/docs/live-replay-protocol.md +28 -37
- package/docs/plans/2026-08-16-workflow-updates-plan.md +1 -1
- package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
- package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +1 -1
- package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +1 -1
- package/docs/plans/2026-08-21-sanity-check-plan.md +30 -16
- package/docs/plans/2026-08-22-goal-finishing-monitor-plan.md +200 -0
- package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +701 -0
- package/docs/plans/2026-08-23-sqlite-state-plan.md +970 -0
- package/docs/plans/2026-08-24-change-scoped-verification-plan.md +419 -0
- package/docs/plans/replayable-run-bundles-implementation-plan.md +2 -2
- package/docs/plans/session-event-replay-implementation-plan.md +1 -1
- package/docs/plans/tui-viewer-implementation-plan.md +1 -1
- package/docs/session-event-journal.md +63 -434
- package/docs/tui-viewer.md +13 -15
- package/docs/workflows.md +111 -62
- package/examples/workflows/plain-summary.workflow.ts +1 -0
- package/herdr-plugin.toml +1 -1
- package/package.json +1 -1
- package/plugins/herdr/viewer.mjs +1 -11
- package/skills/autodoc/SKILL.md +7 -0
- package/skills/autoimplement/SKILL.md +4 -0
- package/skills/autoplan/SKILL.md +5 -4
- package/skills/monitor/SKILL.md +91 -163
- package/skills/pi-workflows/SKILL.md +7 -7
- package/skills/sanity-check/SKILL.md +1 -1
- package/src/builtins/autodoc.workflow.ts +184 -33
- package/src/builtins/autoimplement-command-batches.ts +39 -33
- package/src/builtins/autoimplement.workflow.ts +483 -175
- package/src/builtins/autoplan.workflow.ts +290 -40
- package/src/builtins/catalog.ts +7 -5
- package/src/builtins/change-verification.workflow.ts +1143 -0
- package/src/builtins/index.ts +7 -1
- package/src/builtins/monitor.workflow.ts +667 -250
- package/src/builtins/plain-summary.workflow.ts +185 -0
- package/src/builtins/plan-change.workflow.ts +35 -0
- package/src/builtins/sanity-check.workflow.ts +62 -7
- package/src/builtins/workspace-preparation.workflow.ts +668 -0
- package/src/controllers/effects.ts +7 -0
- package/src/controllers/index.ts +0 -6
- package/src/controllers/manager.ts +72 -32
- package/src/controllers/sqlite.ts +2420 -1948
- package/src/controllers/store.ts +17 -38
- package/src/controllers/types.ts +3 -0
- package/src/controllers/workflow-engine-scheduler.ts +4 -8
- package/src/controllers/workflows.ts +45 -21
- package/src/extension/controller-host.ts +1 -2
- package/src/extension/decision-channels.ts +427 -144
- package/src/extension/executor.ts +106 -6
- package/src/extension/herdr-viewer.ts +0 -5
- package/src/extension/index.ts +180 -132
- package/src/extension/recorder.ts +13 -22
- package/src/extension/step-message.ts +106 -4
- package/src/extension/widget.ts +8 -0
- package/src/host/rpc-executor.ts +4 -0
- package/src/host/runner.ts +93 -41
- package/src/render/graph-render.ts +11 -4
- package/src/state/database.ts +375 -0
- package/src/state/index.ts +29 -0
- package/src/state/json.ts +42 -0
- package/src/state/mutation.ts +435 -0
- package/src/state/schema.ts +475 -0
- package/src/viewer/cli.ts +151 -144
- package/src/viewer/render.ts +12 -24
- package/src/viewer/session-reducer.ts +1 -1
- package/src/viewer/tui.ts +18 -17
- package/src/viewer/watch.ts +13 -17
- package/src/workflows/composition.ts +12 -3
- package/src/workflows/definition.ts +36 -3
- package/src/workflows/engine.ts +212 -116
- package/src/workflows/errors.ts +3 -3
- package/src/workflows/human-decision.ts +795 -340
- package/src/workflows/index.ts +15 -19
- package/src/workflows/schema.ts +19 -1
- package/src/workflows/store.ts +1295 -1163
- package/src/workflows/types.ts +61 -81
- package/dist/workflows/artifacts.d.ts +0 -40
- package/dist/workflows/artifacts.js +0 -155
- package/dist/workflows/artifacts.js.map +0 -1
- package/dist/workflows/migrate-sources.d.ts +0 -42
- package/dist/workflows/migrate-sources.js +0 -133
- package/dist/workflows/migrate-sources.js.map +0 -1
- package/docs/run-bundles.md +0 -481
- package/src/workflows/artifacts.ts +0 -188
- package/src/workflows/migrate-sources.ts +0 -178
|
@@ -27,15 +27,25 @@ import {
|
|
|
27
27
|
type PublishedRepository,
|
|
28
28
|
type VerificationCommandPlan,
|
|
29
29
|
} from "./autoimplement-command-batches.js";
|
|
30
|
+
import changeVerificationWorkflow, {
|
|
31
|
+
type ChangeVerificationInput,
|
|
32
|
+
type VerificationCheck,
|
|
33
|
+
} from "./change-verification.workflow.js";
|
|
30
34
|
import { parsePlanApprovalPolicy, type PlanApprovalPolicy } from "./plan-approval.workflow.js";
|
|
31
35
|
import planChangeWorkflow, { type NormalizedPlanChangeInput } from "./plan-change.workflow.js";
|
|
36
|
+
import workspacePreparationWorkflow, {
|
|
37
|
+
parsePreparedWorkspace,
|
|
38
|
+
type PreparedWorkspace,
|
|
39
|
+
type WorkspaceMode,
|
|
40
|
+
type WorkspacePreparationInput,
|
|
41
|
+
} from "./workspace-preparation.workflow.js";
|
|
32
42
|
|
|
33
43
|
export type AutoimplementInput = {
|
|
34
44
|
task: string;
|
|
35
45
|
plan?: unknown;
|
|
36
46
|
scope?: string;
|
|
37
47
|
constraints?: string[];
|
|
38
|
-
repository
|
|
48
|
+
repository: string;
|
|
39
49
|
baseBranch?: string;
|
|
40
50
|
merge?: boolean;
|
|
41
51
|
documents?: string[];
|
|
@@ -46,6 +56,10 @@ export type AutoimplementInput = {
|
|
|
46
56
|
};
|
|
47
57
|
approval?: PlanApprovalPolicy;
|
|
48
58
|
concurrency?: Partial<AutoimplementConcurrency>;
|
|
59
|
+
workspaceMode?: WorkspaceMode;
|
|
60
|
+
directDefaultBranchAuthorized?: boolean;
|
|
61
|
+
preparedWorkspace?: PreparedWorkspace;
|
|
62
|
+
verificationChecks?: VerificationCheck[];
|
|
49
63
|
};
|
|
50
64
|
|
|
51
65
|
export type ExistingPlanDiscovery = {
|
|
@@ -106,6 +120,16 @@ export type AutoimplementBlocked = {
|
|
|
106
120
|
evidence: unknown;
|
|
107
121
|
};
|
|
108
122
|
|
|
123
|
+
type BlockerStage =
|
|
124
|
+
| "planDiscovery"
|
|
125
|
+
| "documentation"
|
|
126
|
+
| "implementation"
|
|
127
|
+
| "repair"
|
|
128
|
+
| "review"
|
|
129
|
+
| "ci"
|
|
130
|
+
| "delivery"
|
|
131
|
+
| "redesign";
|
|
132
|
+
|
|
109
133
|
type BlockerChallenge = {
|
|
110
134
|
route: "continue" | "blocked";
|
|
111
135
|
blockingNow: boolean;
|
|
@@ -113,10 +137,26 @@ type BlockerChallenge = {
|
|
|
113
137
|
canProceed: boolean;
|
|
114
138
|
reason: string;
|
|
115
139
|
nextAction: string;
|
|
140
|
+
nextStage: BlockerStage | null;
|
|
116
141
|
alternativesChecked: string[];
|
|
117
142
|
evidence: string[];
|
|
118
143
|
};
|
|
119
144
|
|
|
145
|
+
type BlockerClaim = {
|
|
146
|
+
schema: "pi-workflows.blocker-claim.v1";
|
|
147
|
+
sourceNode: string;
|
|
148
|
+
attemptId: string;
|
|
149
|
+
route: string;
|
|
150
|
+
reason: string;
|
|
151
|
+
evidence: unknown;
|
|
152
|
+
failedCommands: unknown[];
|
|
153
|
+
relatedFailures: unknown[];
|
|
154
|
+
unrelatedFailures: unknown[];
|
|
155
|
+
recoveryAttempts: unknown[];
|
|
156
|
+
alternativesChecked: string[];
|
|
157
|
+
authorityFact: string;
|
|
158
|
+
};
|
|
159
|
+
|
|
120
160
|
const MAX_BLOCKER_CHALLENGES = 3;
|
|
121
161
|
const MAX_CHALLENGE_ITEMS = 5;
|
|
122
162
|
const MAX_CHALLENGE_TEXT = 500;
|
|
@@ -133,6 +173,7 @@ const TIMEOUT_FALLBACK_SOURCES = [
|
|
|
133
173
|
"inspectComments",
|
|
134
174
|
"inspectCi",
|
|
135
175
|
"opportunisticTest",
|
|
176
|
+
"finalizeDefaultBranch",
|
|
136
177
|
"finalizeDelivery",
|
|
137
178
|
] as const;
|
|
138
179
|
|
|
@@ -152,6 +193,7 @@ const TIMEOUT_FALLBACK_ROUTES: Record<TimeoutFallbackSource, readonly TimeoutFal
|
|
|
152
193
|
inspectComments: ["retry", "review", "ci", "replan", "blocked"],
|
|
153
194
|
inspectCi: ["retry", "ci", "deliver", "replan", "blocked"],
|
|
154
195
|
opportunisticTest: ["retry", "ci", "deliver", "replan", "blocked"],
|
|
196
|
+
finalizeDefaultBranch: ["retry", "replan", "blocked"],
|
|
155
197
|
finalizeDelivery: ["retry", "deliver", "replan", "blocked"],
|
|
156
198
|
};
|
|
157
199
|
|
|
@@ -175,6 +217,12 @@ function requireString(value: unknown, label: string): string {
|
|
|
175
217
|
return value.trim();
|
|
176
218
|
}
|
|
177
219
|
|
|
220
|
+
function requireAbsolutePath(value: unknown, label: string): string {
|
|
221
|
+
const result = requireString(value, label);
|
|
222
|
+
if (!path.isAbsolute(result)) throw new Error(`${label} must be absolute`);
|
|
223
|
+
return path.resolve(result);
|
|
224
|
+
}
|
|
225
|
+
|
|
178
226
|
function requireStringArray(value: unknown, label: string): string[] {
|
|
179
227
|
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
180
228
|
throw new Error(`${label} must be an array of strings`);
|
|
@@ -202,9 +250,14 @@ function isTimeoutFallbackSource(nodeId: string): nodeId is TimeoutFallbackSourc
|
|
|
202
250
|
function latestTimedOutStep(context: WorkflowNodeContext) {
|
|
203
251
|
for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
|
|
204
252
|
const step = context.state.steps[index];
|
|
205
|
-
if (
|
|
253
|
+
if (
|
|
254
|
+
(step?.outcome === "timed_out" || step?.outcome === "failed") &&
|
|
255
|
+
isTimeoutFallbackSource(step.nodeId)
|
|
256
|
+
) {
|
|
257
|
+
return step;
|
|
258
|
+
}
|
|
206
259
|
}
|
|
207
|
-
throw new Error("No supported
|
|
260
|
+
throw new Error("No supported failed Autoimplement step is available");
|
|
208
261
|
}
|
|
209
262
|
|
|
210
263
|
function latestStepIndex(
|
|
@@ -302,7 +355,7 @@ function timeoutFallbackTarget(context: WorkflowNodeContext): { route: string }
|
|
|
302
355
|
const fallback = context.outputs.timeoutFallback as TimeoutFallbackResult;
|
|
303
356
|
if (fallback.route !== "retry") {
|
|
304
357
|
const routes: Record<Exclude<TimeoutFallbackRoute, "retry">, string> = {
|
|
305
|
-
verify: "
|
|
358
|
+
verify: "selectVerificationPath",
|
|
306
359
|
review: "selectReviewCommands",
|
|
307
360
|
ci: "inspectCi",
|
|
308
361
|
deliver: "finalizeDelivery",
|
|
@@ -321,7 +374,11 @@ function timeoutFallbackGuard(context: WorkflowNodeContext) {
|
|
|
321
374
|
).length;
|
|
322
375
|
if (attempts >= MAX_TIMEOUT_FALLBACKS) {
|
|
323
376
|
const timeouts = context.state.steps
|
|
324
|
-
.filter(
|
|
377
|
+
.filter(
|
|
378
|
+
(step) =>
|
|
379
|
+
(step.outcome === "timed_out" || step.outcome === "failed") &&
|
|
380
|
+
isTimeoutFallbackSource(step.nodeId),
|
|
381
|
+
)
|
|
325
382
|
.map((step) => ({
|
|
326
383
|
nodeId: step.nodeId,
|
|
327
384
|
attemptId: step.attemptId,
|
|
@@ -349,16 +406,6 @@ function timeoutFallbackGuard(context: WorkflowNodeContext) {
|
|
|
349
406
|
};
|
|
350
407
|
}
|
|
351
408
|
|
|
352
|
-
function throwLatestSupportedFailure(context: WorkflowNodeContext): never {
|
|
353
|
-
for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
|
|
354
|
-
const step = context.state.steps[index];
|
|
355
|
-
if (step?.outcome === "failed" && isTimeoutFallbackSource(step.nodeId)) {
|
|
356
|
-
throw new Error(step.error ?? `Autoimplement node failed: ${step.nodeId}`);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
throw new Error("No supported failed Autoimplement step is available");
|
|
360
|
-
}
|
|
361
|
-
|
|
362
409
|
function parseBlockerChallenge(value: unknown): BlockerChallenge {
|
|
363
410
|
const result = requireRecord(value, "blocker challenge");
|
|
364
411
|
if (result.route !== "continue" && result.route !== "blocked") {
|
|
@@ -385,6 +432,20 @@ function parseBlockerChallenge(value: unknown): BlockerChallenge {
|
|
|
385
432
|
`blocker challenge nextAction must be at most ${MAX_CHALLENGE_TEXT} characters`,
|
|
386
433
|
);
|
|
387
434
|
}
|
|
435
|
+
const stages: BlockerStage[] = [
|
|
436
|
+
"planDiscovery",
|
|
437
|
+
"documentation",
|
|
438
|
+
"implementation",
|
|
439
|
+
"repair",
|
|
440
|
+
"review",
|
|
441
|
+
"ci",
|
|
442
|
+
"delivery",
|
|
443
|
+
"redesign",
|
|
444
|
+
];
|
|
445
|
+
const nextStage = result.nextStage === null ? null : result.nextStage;
|
|
446
|
+
if (nextStage !== null && !stages.includes(nextStage as BlockerStage)) {
|
|
447
|
+
throw new Error(`blocker challenge nextStage must be one of ${stages.join(", ")} or null`);
|
|
448
|
+
}
|
|
388
449
|
const alternativesChecked = boundedChallengeItems(
|
|
389
450
|
result.alternativesChecked,
|
|
390
451
|
"blocker challenge alternativesChecked",
|
|
@@ -397,6 +458,7 @@ function parseBlockerChallenge(value: unknown): BlockerChallenge {
|
|
|
397
458
|
outsideAuthority !== true ||
|
|
398
459
|
canProceed !== false ||
|
|
399
460
|
nextAction.length > 0 ||
|
|
461
|
+
nextStage !== null ||
|
|
400
462
|
alternativesChecked.length === 0 ||
|
|
401
463
|
evidence.length === 0
|
|
402
464
|
) {
|
|
@@ -404,8 +466,10 @@ function parseBlockerChallenge(value: unknown): BlockerChallenge {
|
|
|
404
466
|
"blocked challenge requires blockingNow=true, outsideAuthority=true, canProceed=false, an empty nextAction, and concrete alternatives and evidence",
|
|
405
467
|
);
|
|
406
468
|
}
|
|
407
|
-
} else if (canProceed !== true || nextAction.length === 0) {
|
|
408
|
-
throw new Error(
|
|
469
|
+
} else if (canProceed !== true || nextAction.length === 0 || nextStage === null) {
|
|
470
|
+
throw new Error(
|
|
471
|
+
"continue challenge requires canProceed=true, a practical nextAction, and nextStage",
|
|
472
|
+
);
|
|
409
473
|
}
|
|
410
474
|
|
|
411
475
|
return {
|
|
@@ -415,6 +479,7 @@ function parseBlockerChallenge(value: unknown): BlockerChallenge {
|
|
|
415
479
|
canProceed,
|
|
416
480
|
reason,
|
|
417
481
|
nextAction,
|
|
482
|
+
nextStage: nextStage as BlockerStage | null,
|
|
418
483
|
alternativesChecked,
|
|
419
484
|
evidence,
|
|
420
485
|
};
|
|
@@ -463,14 +528,36 @@ function parseInput(value: unknown): AutoimplementInput {
|
|
|
463
528
|
}
|
|
464
529
|
const concurrency = parseAutoimplementConcurrency(input.concurrency);
|
|
465
530
|
const approval = parsePlanApprovalPolicy(input.approval);
|
|
531
|
+
let workspaceMode: WorkspaceMode | undefined;
|
|
532
|
+
if (input.workspaceMode !== undefined) {
|
|
533
|
+
if (
|
|
534
|
+
input.workspaceMode !== "auto" &&
|
|
535
|
+
input.workspaceMode !== "branch" &&
|
|
536
|
+
input.workspaceMode !== "worktree" &&
|
|
537
|
+
input.workspaceMode !== "defaultBranch"
|
|
538
|
+
) {
|
|
539
|
+
throw new Error(
|
|
540
|
+
"autoimplement workspaceMode must be auto, branch, worktree, or defaultBranch",
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
workspaceMode = input.workspaceMode;
|
|
544
|
+
}
|
|
545
|
+
const preparedWorkspace =
|
|
546
|
+
input.preparedWorkspace === undefined
|
|
547
|
+
? undefined
|
|
548
|
+
: parsePreparedWorkspace(input.preparedWorkspace);
|
|
549
|
+
if (input.verificationChecks !== undefined && !Array.isArray(input.verificationChecks)) {
|
|
550
|
+
throw new Error("autoimplement verificationChecks must be an array");
|
|
551
|
+
}
|
|
552
|
+
if (Array.isArray(input.verificationChecks) && input.verificationChecks.length === 0) {
|
|
553
|
+
throw new Error("autoimplement verificationChecks must be non-empty when supplied");
|
|
554
|
+
}
|
|
466
555
|
return {
|
|
467
556
|
task: requireString(input.task, "autoimplement task"),
|
|
468
557
|
...(input.plan !== undefined ? { plan: input.plan } : {}),
|
|
469
558
|
...(input.scope !== undefined ? { scope: requireString(input.scope, "scope") } : {}),
|
|
470
559
|
...(constraints !== undefined ? { constraints: [...constraints] as string[] } : {}),
|
|
471
|
-
|
|
472
|
-
? { repository: requireString(input.repository, "repository") }
|
|
473
|
-
: {}),
|
|
560
|
+
repository: requireAbsolutePath(input.repository, "repository"),
|
|
474
561
|
...(input.baseBranch !== undefined
|
|
475
562
|
? { baseBranch: requireString(input.baseBranch, "baseBranch") }
|
|
476
563
|
: {}),
|
|
@@ -479,6 +566,14 @@ function parseInput(value: unknown): AutoimplementInput {
|
|
|
479
566
|
...(documentation !== undefined ? { documentation } : {}),
|
|
480
567
|
approval,
|
|
481
568
|
concurrency,
|
|
569
|
+
...(workspaceMode === undefined ? {} : { workspaceMode }),
|
|
570
|
+
...(input.directDefaultBranchAuthorized === undefined
|
|
571
|
+
? {}
|
|
572
|
+
: { directDefaultBranchAuthorized: input.directDefaultBranchAuthorized === true }),
|
|
573
|
+
...(preparedWorkspace === undefined ? {} : { preparedWorkspace }),
|
|
574
|
+
...(input.verificationChecks === undefined
|
|
575
|
+
? {}
|
|
576
|
+
: { verificationChecks: input.verificationChecks as VerificationCheck[] }),
|
|
482
577
|
};
|
|
483
578
|
}
|
|
484
579
|
|
|
@@ -619,32 +714,100 @@ function currentPlan(context: WorkflowNodeContext): unknown {
|
|
|
619
714
|
return (context.input as AutoimplementInput).plan;
|
|
620
715
|
}
|
|
621
716
|
|
|
717
|
+
function preparedWorkspace(context: WorkflowNodeContext): PreparedWorkspace {
|
|
718
|
+
const request = context.input as AutoimplementInput;
|
|
719
|
+
if (request.preparedWorkspace !== undefined) return request.preparedWorkspace;
|
|
720
|
+
const result = includedResult(workspacePreparationWorkflow, context.outputs.workspace);
|
|
721
|
+
if (result.exit !== "ready") throw new Error("autoimplement workspace is not ready");
|
|
722
|
+
return result.output;
|
|
723
|
+
}
|
|
724
|
+
|
|
622
725
|
function blockerChallenges(context: WorkflowNodeContext): BlockerChallenge[] {
|
|
623
726
|
return context.state.steps
|
|
624
727
|
.filter((step) => step.nodeId === "challengeBlocker" && step.outcome === "ok")
|
|
625
728
|
.map((step) => step.output as BlockerChallenge);
|
|
626
729
|
}
|
|
627
730
|
|
|
628
|
-
function latestBlockerClaim(context: WorkflowNodeContext):
|
|
629
|
-
const ids = [
|
|
630
|
-
"classifyImplementation",
|
|
631
|
-
"classifyVerification",
|
|
632
|
-
"repairReviewCommand",
|
|
633
|
-
"inspectComments",
|
|
634
|
-
"inspectCi",
|
|
635
|
-
"repairCiCommand",
|
|
636
|
-
"assessTrackedCi",
|
|
637
|
-
"classifyCi",
|
|
638
|
-
"finalizeDelivery",
|
|
639
|
-
"timeoutFallback",
|
|
640
|
-
];
|
|
731
|
+
function latestBlockerClaim(context: WorkflowNodeContext): BlockerClaim {
|
|
641
732
|
for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
|
|
642
733
|
const step = context.state.steps[index];
|
|
643
|
-
if (step &&
|
|
644
|
-
return
|
|
734
|
+
if (step?.nodeId === "createBlockerClaim" && step.outcome === "ok") {
|
|
735
|
+
return step.output as BlockerClaim;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
throw new Error("No durable blocker claim is available to challenge");
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
function unwrapResult(value: unknown): Record<string, unknown> {
|
|
742
|
+
const record = requireRecord(value, "blocker source output");
|
|
743
|
+
const output = record.output;
|
|
744
|
+
return output !== null && typeof output === "object" && !Array.isArray(output)
|
|
745
|
+
? (output as Record<string, unknown>)
|
|
746
|
+
: record;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
function createBlockerClaim(context: WorkflowNodeContext): BlockerClaim {
|
|
750
|
+
const source = [...context.state.steps].reverse().find((step) => {
|
|
751
|
+
if (step.nodeId === "createBlockerClaim") return false;
|
|
752
|
+
if (step.error !== undefined) return true;
|
|
753
|
+
if (step.output === null || typeof step.output !== "object" || Array.isArray(step.output)) {
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
const result = unwrapResult(step.output);
|
|
757
|
+
return (
|
|
758
|
+
typeof result.reason === "string" ||
|
|
759
|
+
typeof result.summary === "string" ||
|
|
760
|
+
typeof result.blocker === "string"
|
|
761
|
+
);
|
|
762
|
+
});
|
|
763
|
+
if (source === undefined) throw new Error("No blocker source step is available");
|
|
764
|
+
const result = unwrapResult(source.output ?? { reason: source.error ?? "Step failed" });
|
|
765
|
+
const reasonValue = result.reason ?? result.summary ?? result.blocker ?? source.error;
|
|
766
|
+
const reason =
|
|
767
|
+
typeof reasonValue === "string" && reasonValue.trim().length > 0
|
|
768
|
+
? reasonValue.trim()
|
|
769
|
+
: `Autoimplement could not continue after ${source.nodeId}.`;
|
|
770
|
+
const commands = result.candidateCommands ?? result.commands;
|
|
771
|
+
const failedCommands =
|
|
772
|
+
commands !== null && typeof commands === "object" && !Array.isArray(commands)
|
|
773
|
+
? (((commands as { items?: unknown }).items as unknown[] | undefined) ?? [])
|
|
774
|
+
: [];
|
|
775
|
+
return {
|
|
776
|
+
schema: "pi-workflows.blocker-claim.v1",
|
|
777
|
+
sourceNode:
|
|
778
|
+
typeof result.sourceNode === "string" && result.sourceNode.length > 0
|
|
779
|
+
? result.sourceNode
|
|
780
|
+
: source.nodeId,
|
|
781
|
+
attemptId: source.attemptId,
|
|
782
|
+
route: typeof result.route === "string" ? result.route : source.outcome,
|
|
783
|
+
reason,
|
|
784
|
+
evidence:
|
|
785
|
+
typeof result.sourceNode === "string"
|
|
786
|
+
? result
|
|
787
|
+
: (result.evidence ?? source.output ?? source.error),
|
|
788
|
+
failedCommands,
|
|
789
|
+
relatedFailures: Array.isArray(result.relatedFailures) ? result.relatedFailures : [],
|
|
790
|
+
unrelatedFailures: Array.isArray(result.unrelatedFailures) ? result.unrelatedFailures : [],
|
|
791
|
+
recoveryAttempts: Array.isArray(result.repairAttempts) ? result.repairAttempts : [],
|
|
792
|
+
alternativesChecked: [],
|
|
793
|
+
authorityFact: `scope=${(context.input as AutoimplementInput).scope ?? "unspecified"}; merge=${(context.input as AutoimplementInput).merge === true}`,
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
function challengeTarget(context: WorkflowNodeContext): { route: string } {
|
|
798
|
+
const challenge = context.outputs.challengeBlocker as BlockerChallenge;
|
|
799
|
+
if (challenge.route === "blocked" || challenge.nextStage === null) return { route: "blocked" };
|
|
800
|
+
if (challenge.nextStage !== "planDiscovery" && currentPlan(context) === undefined) {
|
|
801
|
+
return { route: "planDiscovery" };
|
|
802
|
+
}
|
|
803
|
+
if (["documentation", "implementation", "repair", "redesign"].includes(challenge.nextStage)) {
|
|
804
|
+
try {
|
|
805
|
+
preparedWorkspace(context);
|
|
806
|
+
} catch {
|
|
807
|
+
return { route: "workspace" };
|
|
645
808
|
}
|
|
646
809
|
}
|
|
647
|
-
|
|
810
|
+
return { route: challenge.nextStage };
|
|
648
811
|
}
|
|
649
812
|
|
|
650
813
|
function recentWorkflowAttempts(context: WorkflowNodeContext): unknown[] {
|
|
@@ -690,30 +853,31 @@ function parseVerificationForContext(
|
|
|
690
853
|
context: WorkflowNodeContext,
|
|
691
854
|
): VerificationCommandPlan {
|
|
692
855
|
const plan = parseVerificationCommandPlan(value);
|
|
693
|
-
const
|
|
694
|
-
const reported = Array.isArray(implementation.repositories)
|
|
695
|
-
? implementation.repositories.filter((entry): entry is string => typeof entry === "string")
|
|
696
|
-
: [];
|
|
697
|
-
const request = context.input as AutoimplementInput;
|
|
698
|
-
const roots = new Set(
|
|
699
|
-
(reported.length > 0 ? reported : [request.repository ?? process.cwd()]).map((entry) =>
|
|
700
|
-
path.resolve(entry),
|
|
701
|
-
),
|
|
702
|
-
);
|
|
856
|
+
const root = preparedWorkspace(context).worktreePath ?? preparedWorkspace(context).repository;
|
|
703
857
|
for (const command of plan.commands) {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
throw new Error(
|
|
707
|
-
`verification command cwd was not reported by implementation: ${command.cwd}`,
|
|
708
|
-
);
|
|
858
|
+
if (path.resolve(command.cwd) !== path.resolve(root)) {
|
|
859
|
+
throw new Error(`verification command cwd must match the prepared workspace: ${root}`);
|
|
709
860
|
}
|
|
710
861
|
}
|
|
711
|
-
if (roots.size > 0) {
|
|
712
|
-
throw new Error(`verification plan is missing reported repositories: ${[...roots].join(", ")}`);
|
|
713
|
-
}
|
|
714
862
|
return plan;
|
|
715
863
|
}
|
|
716
864
|
|
|
865
|
+
function parsePublishedForContext(
|
|
866
|
+
value: unknown,
|
|
867
|
+
context: WorkflowNodeContext,
|
|
868
|
+
): PublishedRepositories {
|
|
869
|
+
const result = parsePublishedRepositories(value);
|
|
870
|
+
const workspace = preparedWorkspace(context);
|
|
871
|
+
const expected = path.resolve(workspace.worktreePath ?? workspace.repository);
|
|
872
|
+
if (result.repositories[0]?.repository !== expected) {
|
|
873
|
+
throw new Error(`publication repository must match the prepared workspace: ${expected}`);
|
|
874
|
+
}
|
|
875
|
+
if (result.repositories.some((repository) => repository.repository !== expected)) {
|
|
876
|
+
throw new Error("publication cannot include an unprepared repository");
|
|
877
|
+
}
|
|
878
|
+
return result;
|
|
879
|
+
}
|
|
880
|
+
|
|
717
881
|
function currentPublishedRepositories(context: WorkflowNodeContext): PublishedRepositories {
|
|
718
882
|
return latestOutput<PublishedRepositories>(context, ["verifyP2", "publish"]);
|
|
719
883
|
}
|
|
@@ -1090,7 +1254,15 @@ function ciForOutput(context: WorkflowNodeContext): unknown {
|
|
|
1090
1254
|
}
|
|
1091
1255
|
|
|
1092
1256
|
function latestBlockedReason(context: WorkflowNodeContext): { reason: string; evidence: unknown } {
|
|
1257
|
+
for (let index = context.state.steps.length - 1; index >= 0; index -= 1) {
|
|
1258
|
+
const step = context.state.steps[index];
|
|
1259
|
+
if (step?.nodeId === "createBlockerClaim" && step.outcome === "ok") {
|
|
1260
|
+
const claim = step.output as BlockerClaim;
|
|
1261
|
+
return { reason: claim.reason, evidence: claim };
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1093
1264
|
const candidates = [
|
|
1265
|
+
"createBlockerClaim",
|
|
1094
1266
|
"timeoutFallbackGuard",
|
|
1095
1267
|
"timeoutFallback",
|
|
1096
1268
|
"challengeBlockerGuard",
|
|
@@ -1130,8 +1302,28 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1130
1302
|
presentationPrompt:
|
|
1131
1303
|
"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.",
|
|
1132
1304
|
startAt: "prepare",
|
|
1133
|
-
maxSteps:
|
|
1305
|
+
maxSteps: 320,
|
|
1134
1306
|
includes: {
|
|
1307
|
+
workspace: includeWorkflow(workspacePreparationWorkflow, {
|
|
1308
|
+
input: (context): WorkspacePreparationInput => {
|
|
1309
|
+
const request = context.input as AutoimplementInput;
|
|
1310
|
+
if (request.repository === undefined) {
|
|
1311
|
+
throw new Error("autoimplement workspace preparation requires an absolute repository");
|
|
1312
|
+
}
|
|
1313
|
+
return {
|
|
1314
|
+
repository: request.repository,
|
|
1315
|
+
...(request.baseBranch === undefined ? {} : { baseBranch: request.baseBranch }),
|
|
1316
|
+
...(request.scope === undefined ? {} : { scope: request.scope }),
|
|
1317
|
+
...(request.workspaceMode === undefined ? {} : { workspaceMode: request.workspaceMode }),
|
|
1318
|
+
...(request.directDefaultBranchAuthorized === undefined
|
|
1319
|
+
? {}
|
|
1320
|
+
: { directDefaultBranchAuthorized: request.directDefaultBranchAuthorized }),
|
|
1321
|
+
...(request.preparedWorkspace === undefined
|
|
1322
|
+
? {}
|
|
1323
|
+
: { preparedWorkspace: request.preparedWorkspace }),
|
|
1324
|
+
};
|
|
1325
|
+
},
|
|
1326
|
+
}),
|
|
1135
1327
|
documentation: includeWorkflow(autodocWorkflow, {
|
|
1136
1328
|
input: (context): AutodocInput => {
|
|
1137
1329
|
const request = context.input as AutoimplementInput;
|
|
@@ -1142,12 +1334,51 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1142
1334
|
task: request.task,
|
|
1143
1335
|
plan,
|
|
1144
1336
|
...(request.repository !== undefined ? { repository: request.repository } : {}),
|
|
1337
|
+
...(request.baseBranch !== undefined ? { baseBranch: request.baseBranch } : {}),
|
|
1338
|
+
...(request.scope !== undefined ? { scope: request.scope } : {}),
|
|
1339
|
+
...(request.directDefaultBranchAuthorized === undefined
|
|
1340
|
+
? {}
|
|
1341
|
+
: { directDefaultBranchAuthorized: request.directDefaultBranchAuthorized }),
|
|
1342
|
+
preparedWorkspace: preparedWorkspace(context),
|
|
1343
|
+
...(request.verificationChecks === undefined
|
|
1344
|
+
? {}
|
|
1345
|
+
: { verificationChecks: request.verificationChecks }),
|
|
1145
1346
|
documents:
|
|
1146
1347
|
request.documents ?? request.documentation?.documents ?? discovery?.documents ?? [],
|
|
1147
1348
|
evidence: latestIssue(context),
|
|
1148
1349
|
};
|
|
1149
1350
|
},
|
|
1150
1351
|
}),
|
|
1352
|
+
localVerification: includeWorkflow(changeVerificationWorkflow, {
|
|
1353
|
+
input: (context): ChangeVerificationInput => {
|
|
1354
|
+
const request = context.input as AutoimplementInput;
|
|
1355
|
+
const plan =
|
|
1356
|
+
request.verificationChecks === undefined
|
|
1357
|
+
? latestOutput<VerificationCommandPlan>(context, ["planVerification"])
|
|
1358
|
+
: { commands: [], untested: [] };
|
|
1359
|
+
const implementation = latestOutput<Record<string, unknown>>(context, ["implement"]);
|
|
1360
|
+
return {
|
|
1361
|
+
originatingWorkflow: "autoimplement",
|
|
1362
|
+
qualifiedNode: "autoimplement/localVerification",
|
|
1363
|
+
workspace: preparedWorkspace(context),
|
|
1364
|
+
checks:
|
|
1365
|
+
request.verificationChecks ??
|
|
1366
|
+
plan.commands.map((command) => ({
|
|
1367
|
+
...command,
|
|
1368
|
+
readOnly: true,
|
|
1369
|
+
baseEligible: true,
|
|
1370
|
+
changedFileScope: false,
|
|
1371
|
+
findingFormat: "text" as const,
|
|
1372
|
+
})),
|
|
1373
|
+
changedFiles: Array.isArray(implementation.files)
|
|
1374
|
+
? implementation.files.filter((file): file is string => typeof file === "string")
|
|
1375
|
+
: [],
|
|
1376
|
+
untested: plan.untested,
|
|
1377
|
+
plan: currentPlan(context),
|
|
1378
|
+
maxConcurrency: concurrency(context).verification,
|
|
1379
|
+
};
|
|
1380
|
+
},
|
|
1381
|
+
}),
|
|
1151
1382
|
redesign: includeWorkflow(planChangeWorkflow, {
|
|
1152
1383
|
input: (context): NormalizedPlanChangeInput => {
|
|
1153
1384
|
const request = context.input as AutoimplementInput;
|
|
@@ -1155,7 +1386,14 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1155
1386
|
task: request.task,
|
|
1156
1387
|
...(request.scope !== undefined ? { scope: request.scope } : {}),
|
|
1157
1388
|
...(request.constraints !== undefined ? { constraints: request.constraints } : {}),
|
|
1158
|
-
|
|
1389
|
+
repository: request.repository,
|
|
1390
|
+
preparedWorkspace: preparedWorkspace(context),
|
|
1391
|
+
...(request.directDefaultBranchAuthorized === undefined
|
|
1392
|
+
? {}
|
|
1393
|
+
: { directDefaultBranchAuthorized: request.directDefaultBranchAuthorized }),
|
|
1394
|
+
...(request.verificationChecks === undefined
|
|
1395
|
+
? {}
|
|
1396
|
+
: { verificationChecks: request.verificationChecks }),
|
|
1159
1397
|
documents: request.documents ?? request.documentation?.documents ?? [],
|
|
1160
1398
|
...(currentPlan(context) !== undefined ? { previousPlan: currentPlan(context) } : {}),
|
|
1161
1399
|
newEvidence: latestIssue(context),
|
|
@@ -1178,14 +1416,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1178
1416
|
prepare: compute({
|
|
1179
1417
|
run: ({ input }) => {
|
|
1180
1418
|
const request = input as AutoimplementInput;
|
|
1181
|
-
return {
|
|
1182
|
-
route:
|
|
1183
|
-
request.plan === undefined
|
|
1184
|
-
? "find"
|
|
1185
|
-
: request.documentation?.status === "current"
|
|
1186
|
-
? "ready"
|
|
1187
|
-
: "document",
|
|
1188
|
-
};
|
|
1419
|
+
return { route: request.plan === undefined ? "find" : "workspace" };
|
|
1189
1420
|
},
|
|
1190
1421
|
}),
|
|
1191
1422
|
findPlan: agent({
|
|
@@ -1214,13 +1445,27 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1214
1445
|
return { route: "blocked", reason: discovered.reason, evidence: discovered.evidence };
|
|
1215
1446
|
}
|
|
1216
1447
|
return {
|
|
1217
|
-
route:
|
|
1448
|
+
route: "workspace",
|
|
1218
1449
|
plan: discovered.plan,
|
|
1450
|
+
documentation: discovered.documentation,
|
|
1219
1451
|
reason: discovered.reason,
|
|
1220
1452
|
evidence: discovered.evidence,
|
|
1221
1453
|
};
|
|
1222
1454
|
},
|
|
1223
1455
|
}),
|
|
1456
|
+
routeWorkspace: compute({
|
|
1457
|
+
run: ({ input, outputs }) => {
|
|
1458
|
+
const request = input as AutoimplementInput;
|
|
1459
|
+
const discovered = outputs.findPlan as ExistingPlanDiscovery | undefined;
|
|
1460
|
+
return {
|
|
1461
|
+
route:
|
|
1462
|
+
request.documentation?.status === "current" || discovered?.documentation === "current"
|
|
1463
|
+
? "implement"
|
|
1464
|
+
: "document",
|
|
1465
|
+
workspace: preparedWorkspace({ input, outputs } as WorkflowNodeContext),
|
|
1466
|
+
};
|
|
1467
|
+
},
|
|
1468
|
+
}),
|
|
1224
1469
|
adoptPlan: compute({
|
|
1225
1470
|
run: ({ outputs }) => {
|
|
1226
1471
|
const result = includedResult(planChangeWorkflow, outputs.redesign);
|
|
@@ -1247,10 +1492,10 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1247
1492
|
.filter((step) => step.nodeId === "timeoutFallback" && step.outcome === "ok")
|
|
1248
1493
|
.map((step) => step.output);
|
|
1249
1494
|
return [
|
|
1250
|
-
"A bounded Autoimplement
|
|
1495
|
+
"A bounded Autoimplement step failed or timed out. Choose the safest existing workflow stage to run next instead of ending the run blindly.",
|
|
1251
1496
|
"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.",
|
|
1252
1497
|
"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.",
|
|
1253
|
-
"Do not assume that
|
|
1498
|
+
"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.",
|
|
1254
1499
|
"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.",
|
|
1255
1500
|
"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.",
|
|
1256
1501
|
"Do not skip required implementation, verification, review, CI, authorization, or delivery checks.",
|
|
@@ -1269,9 +1514,6 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1269
1514
|
routeTimeoutFallback: compute({
|
|
1270
1515
|
run: timeoutFallbackTarget,
|
|
1271
1516
|
}),
|
|
1272
|
-
propagateSupportedFailure: compute({
|
|
1273
|
-
run: throwLatestSupportedFailure,
|
|
1274
|
-
}),
|
|
1275
1517
|
routeVerifyP2Result: compute({
|
|
1276
1518
|
run: ({ outputs }) => outputs.verifyP2,
|
|
1277
1519
|
}),
|
|
@@ -1294,6 +1536,8 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1294
1536
|
`Plan: ${JSON.stringify(currentPlan(context))}`,
|
|
1295
1537
|
`Authorized scope: ${request.scope ?? request.repository ?? "the current repository and task"}`,
|
|
1296
1538
|
`Constraints: ${JSON.stringify(request.constraints ?? [])}`,
|
|
1539
|
+
`Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
|
|
1540
|
+
"Use the prepared absolute workspace path for every read, edit, command, and report. Do not fall back to the Pi process working directory.",
|
|
1297
1541
|
"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.",
|
|
1298
1542
|
"Follow repository instructions and use the most elegant long-term production-ready implementation without unnecessary work.",
|
|
1299
1543
|
"If implementation exposes a new design or scope problem, report it precisely instead of forcing the old plan.",
|
|
@@ -1323,6 +1567,17 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1323
1567
|
"implementation assessment",
|
|
1324
1568
|
),
|
|
1325
1569
|
}),
|
|
1570
|
+
createBlockerClaim: compute({
|
|
1571
|
+
run: createBlockerClaim,
|
|
1572
|
+
}),
|
|
1573
|
+
routeBlockerClaim: compute({
|
|
1574
|
+
run: ({ outputs }) => {
|
|
1575
|
+
const claim = outputs.createBlockerClaim as BlockerClaim;
|
|
1576
|
+
return {
|
|
1577
|
+
route: claim.sourceNode === "challengeBlockerGuard" ? "blocked" : "challenge",
|
|
1578
|
+
};
|
|
1579
|
+
},
|
|
1580
|
+
}),
|
|
1326
1581
|
challengeBlockerGuard: compute({
|
|
1327
1582
|
run: (context) => {
|
|
1328
1583
|
const challenges = blockerChallenges(context);
|
|
@@ -1354,7 +1609,8 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1354
1609
|
"A local test failure, stale package, packaging or artifact mismatch, rollback preparation, or deployment procedure is not by itself outside authority.",
|
|
1355
1610
|
"If a safe deployment and rollback path is already authorized, a supported cutover is work to do, not a blocker.",
|
|
1356
1611
|
"Confirm blocked only when the issue blocks progress now, is outside authority, and has no safe practical path forward.",
|
|
1357
|
-
"Return continue with the next practical action
|
|
1612
|
+
"Return continue with the next practical action and its exact nextStage: planDiscovery, documentation, implementation, repair, review, ci, delivery, or redesign.",
|
|
1613
|
+
"Keep text concise, with at most five alternatives and five evidence items.",
|
|
1358
1614
|
`Task: ${request.task}`,
|
|
1359
1615
|
`Approved plan: ${JSON.stringify(currentPlan(context))}`,
|
|
1360
1616
|
`Current result and claimed blocker: ${JSON.stringify(latestBlockerClaim(context))}`,
|
|
@@ -1365,71 +1621,64 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1365
1621
|
`Recent workflow attempts: ${JSON.stringify(recentWorkflowAttempts(context))}`,
|
|
1366
1622
|
].join("\n");
|
|
1367
1623
|
},
|
|
1368
|
-
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"] }`,
|
|
1624
|
+
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"] }`,
|
|
1369
1625
|
validate: parseBlockerChallenge,
|
|
1370
1626
|
}),
|
|
1627
|
+
routeChallenge: compute({ run: challengeTarget }),
|
|
1628
|
+
selectVerificationPath: compute({
|
|
1629
|
+
run: ({ input }) => ({
|
|
1630
|
+
route: (input as AutoimplementInput).verificationChecks === undefined ? "plan" : "verify",
|
|
1631
|
+
}),
|
|
1632
|
+
}),
|
|
1371
1633
|
planVerification: agent({
|
|
1372
1634
|
timeoutMs: 15 * 60_000,
|
|
1373
1635
|
statusDetail: "planning independent verification commands",
|
|
1374
|
-
prompt: () =>
|
|
1636
|
+
prompt: (context) =>
|
|
1375
1637
|
[
|
|
1376
|
-
"Select
|
|
1377
|
-
"Return one
|
|
1638
|
+
"Select all required local verification commands for the implementation.",
|
|
1639
|
+
"Return one or more commands for the prepared repository workspace.",
|
|
1378
1640
|
"Use exact executables and argument arrays without shell wrappers, environment overrides, stdin, Git or GitHub mutations, package publication, deployment, merge, or release commands.",
|
|
1379
|
-
"Use absolute
|
|
1641
|
+
"Use the prepared absolute workspace path as cwd for every command, explicit timeouts no longer than 2700000ms, and maxOutputChars no larger than 1000000.",
|
|
1380
1642
|
"List checks that cannot run locally under untested.",
|
|
1643
|
+
`Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
|
|
1381
1644
|
].join("\n"),
|
|
1382
1645
|
expectedOutput: `{ "commands": [{ "id": "stable-id", "command": "npm", "args": ["run", "check"], "cwd": "/absolute/repository", "timeoutMs": 2700000, "maxOutputChars": 1000000 }], "untested": ["remaining check"] }`,
|
|
1383
1646
|
validate: parseVerificationForContext,
|
|
1384
1647
|
}),
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
},
|
|
1390
|
-
statusDetail: "running independent verification commands",
|
|
1391
|
-
run: async (context) => {
|
|
1392
|
-
const plan = latestOutput<VerificationCommandPlan>(context, ["planVerification"]);
|
|
1393
|
-
return await runAutoimplementBatch(
|
|
1394
|
-
context,
|
|
1395
|
-
"verification",
|
|
1396
|
-
plan.commands,
|
|
1397
|
-
concurrency(context).verification,
|
|
1398
|
-
);
|
|
1399
|
-
},
|
|
1648
|
+
routeVerifiedWorkspace: compute({
|
|
1649
|
+
run: (context) => ({
|
|
1650
|
+
route:
|
|
1651
|
+
preparedWorkspace(context).mode === "defaultBranch" ? "defaultBranch" : "pullRequest",
|
|
1652
|
+
}),
|
|
1400
1653
|
}),
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
statusDetail: "assessing verification",
|
|
1404
|
-
prompt: (context) =>
|
|
1405
|
-
[
|
|
1406
|
-
"Assess the completed local verification commands.",
|
|
1407
|
-
"Set passed true only when every required command succeeded without truncated output.",
|
|
1408
|
-
"Report exact command outcomes, failures, and checks that still need remote verification.",
|
|
1409
|
-
`Command plan: ${JSON.stringify(latestOutput(context, ["planVerification"]))}`,
|
|
1410
|
-
`Command results: ${JSON.stringify(latestOutput(context, ["runVerification"]))}`,
|
|
1411
|
-
].join("\n"),
|
|
1412
|
-
expectedOutput: `{ "passed": true | false, "commands": [{ "command": "exact command", "outcome": "result" }], "failures": ["failure"], "untested": ["remaining check"] }`,
|
|
1413
|
-
validate: (value) => requireRecord(value, "verification result"),
|
|
1654
|
+
routeFinalizeDefaultBranchResult: compute({
|
|
1655
|
+
run: ({ outputs }) => outputs.finalizeDefaultBranch,
|
|
1414
1656
|
}),
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
"
|
|
1422
|
-
"
|
|
1423
|
-
"
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
)
|
|
1657
|
+
finalizeDefaultBranch: agent({
|
|
1658
|
+
timeoutMs: 30 * 60_000,
|
|
1659
|
+
statusDetail: "finalizing default-branch work",
|
|
1660
|
+
prompt: (context) => {
|
|
1661
|
+
const request = context.input as AutoimplementInput;
|
|
1662
|
+
return [
|
|
1663
|
+
"Finalize verified work in the explicitly authorized default-branch workspace.",
|
|
1664
|
+
"Never open a pull request from the default branch to itself.",
|
|
1665
|
+
"Commit and push only when the authorized scope explicitly allows each action. Otherwise leave the verified local change and report it.",
|
|
1666
|
+
"Do not merge, release, or deploy.",
|
|
1667
|
+
`Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
|
|
1668
|
+
`Authorized scope: ${request.scope}`,
|
|
1669
|
+
].join("\n");
|
|
1670
|
+
},
|
|
1671
|
+
expectedOutput: `{ "status": "completed" | "blocked", "committed": true | false, "pushed": true | false, "merged": false, "pr": "none", "reportComment": "summary", "reason": "result" }`,
|
|
1672
|
+
validate: (value) => {
|
|
1673
|
+
const result = requireRecord(value, "default-branch delivery");
|
|
1674
|
+
if (result.status !== "completed" && result.status !== "blocked") {
|
|
1675
|
+
throw new Error("default-branch delivery status must be completed or blocked");
|
|
1676
|
+
}
|
|
1677
|
+
if (result.merged !== false || result.pr !== "none") {
|
|
1678
|
+
throw new Error("default-branch delivery cannot merge or open a pull request to itself");
|
|
1679
|
+
}
|
|
1680
|
+
return result;
|
|
1681
|
+
},
|
|
1433
1682
|
}),
|
|
1434
1683
|
fix: agent({
|
|
1435
1684
|
timeoutMs: 45 * 60_000,
|
|
@@ -1440,6 +1689,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1440
1689
|
"Inspect the current diff and commits first. Continue any partial fix and change only work that is still missing.",
|
|
1441
1690
|
`Issue: ${JSON.stringify(latestIssue(context))}`,
|
|
1442
1691
|
`Current plan: ${JSON.stringify(currentPlan(context))}`,
|
|
1692
|
+
`Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
|
|
1443
1693
|
"Stop after the fix so verification can run again.",
|
|
1444
1694
|
].join("\n"),
|
|
1445
1695
|
expectedOutput: `{ "fixed": "what changed", "files": ["changed file"] }`,
|
|
@@ -1448,8 +1698,8 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1448
1698
|
publish: agent({
|
|
1449
1699
|
timeoutMs: 30 * 60_000,
|
|
1450
1700
|
statusDetail: "committing and pushing",
|
|
1451
|
-
prompt: (
|
|
1452
|
-
const request = input as AutoimplementInput;
|
|
1701
|
+
prompt: (context) => {
|
|
1702
|
+
const request = context.input as AutoimplementInput;
|
|
1453
1703
|
return [
|
|
1454
1704
|
"Commit and push the verified implementation before review.",
|
|
1455
1705
|
"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.",
|
|
@@ -1458,11 +1708,12 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1458
1708
|
"Report every repository that received a pushed pull request with its absolute repository path, branch, base branch, pushed head revision, and PR URL.",
|
|
1459
1709
|
"Include dependencyFingerprint only when a declared dependency result is relevant to review reuse.",
|
|
1460
1710
|
`Requested base branch: ${request.baseBranch ?? "discover each repository default branch"}.`,
|
|
1711
|
+
`Prepared workspace: ${JSON.stringify(preparedWorkspace(context))}`,
|
|
1461
1712
|
"Do not merge yet.",
|
|
1462
1713
|
].join("\n");
|
|
1463
1714
|
},
|
|
1464
1715
|
expectedOutput: `{ "repositories": [{ "repository": "/absolute/repository", "branch": "branch", "baseBranch": "base", "headRevision": "revision", "pr": "URL", "pushed": true, "dependencyFingerprint": "optional digest" }] }`,
|
|
1465
|
-
validate:
|
|
1716
|
+
validate: parsePublishedForContext,
|
|
1466
1717
|
}),
|
|
1467
1718
|
selectReviewCommands: compute({
|
|
1468
1719
|
run: selectReviewCommands,
|
|
@@ -1710,10 +1961,23 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1710
1961
|
task: request.task,
|
|
1711
1962
|
plan: currentPlan(context),
|
|
1712
1963
|
implementation: latestOutput(context, ["implement"]),
|
|
1713
|
-
verification:
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1964
|
+
verification:
|
|
1965
|
+
context.outputs.localVerification === undefined
|
|
1966
|
+
? latestOutput(context, ["verifyP2"])
|
|
1967
|
+
: includedResult(changeVerificationWorkflow, context.outputs.localVerification)
|
|
1968
|
+
.output,
|
|
1969
|
+
reviewRounds:
|
|
1970
|
+
context.outputs.finalizeDefaultBranch === undefined
|
|
1971
|
+
? reviewRoundsForOutput(context)
|
|
1972
|
+
: [],
|
|
1973
|
+
ci:
|
|
1974
|
+
context.outputs.finalizeDefaultBranch === undefined
|
|
1975
|
+
? ciForOutput(context)
|
|
1976
|
+
: {
|
|
1977
|
+
route: "notApplicable",
|
|
1978
|
+
reason: "Direct default-branch work has no pull request.",
|
|
1979
|
+
},
|
|
1980
|
+
delivery: latestOutput(context, ["finalizeDefaultBranch", "finalizeDelivery"]),
|
|
1717
1981
|
} satisfies AutoimplementCompleted;
|
|
1718
1982
|
},
|
|
1719
1983
|
}),
|
|
@@ -1721,33 +1985,41 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1721
1985
|
edges: [
|
|
1722
1986
|
{
|
|
1723
1987
|
from: "prepare",
|
|
1724
|
-
switch: {
|
|
1725
|
-
on: "$.route",
|
|
1726
|
-
cases: { find: "findPlan", document: "documentation", ready: "implement" },
|
|
1727
|
-
},
|
|
1988
|
+
switch: { on: "$.route", cases: { find: "findPlan", workspace: "workspace" } },
|
|
1728
1989
|
},
|
|
1729
1990
|
{
|
|
1730
1991
|
from: "findPlan",
|
|
1731
|
-
switch: {
|
|
1992
|
+
switch: {
|
|
1993
|
+
on: "$.route",
|
|
1994
|
+
cases: { found: "routeFoundPlan", blocked: "createBlockerClaim" },
|
|
1995
|
+
},
|
|
1732
1996
|
},
|
|
1733
1997
|
{
|
|
1734
1998
|
from: "routeFoundPlan",
|
|
1735
1999
|
switch: {
|
|
1736
2000
|
on: "$.route",
|
|
1737
|
-
cases: {
|
|
2001
|
+
cases: { workspace: "workspace", blocked: "createBlockerClaim" },
|
|
1738
2002
|
},
|
|
1739
2003
|
},
|
|
2004
|
+
{ from: "workspace.ready", to: "routeWorkspace" },
|
|
2005
|
+
{ from: "workspace.blocked", to: "createBlockerClaim" },
|
|
2006
|
+
{
|
|
2007
|
+
from: "routeWorkspace",
|
|
2008
|
+
switch: { on: "$.route", cases: { implement: "implement", document: "documentation" } },
|
|
2009
|
+
},
|
|
1740
2010
|
{ from: "redesign.ready", to: "adoptPlan" },
|
|
1741
2011
|
{ from: "redesign.blocked", to: "blocked" },
|
|
1742
2012
|
{ from: "adoptPlan", to: "implement" },
|
|
1743
2013
|
{ from: "documentation.ready", to: "implement" },
|
|
1744
|
-
{ from: "documentation.blocked", to: "
|
|
2014
|
+
{ from: "documentation.blocked", to: "createBlockerClaim" },
|
|
1745
2015
|
{
|
|
1746
2016
|
from: "timeoutFallbackGuard",
|
|
1747
|
-
switch: {
|
|
2017
|
+
switch: {
|
|
2018
|
+
on: "$.route",
|
|
2019
|
+
cases: { recover: "timeoutFallback", blocked: "createBlockerClaim" },
|
|
2020
|
+
},
|
|
1748
2021
|
},
|
|
1749
2022
|
{ from: "timeoutFallback", to: "routeTimeoutFallback" },
|
|
1750
|
-
{ from: "propagateSupportedFailure", to: "blocked" },
|
|
1751
2023
|
{
|
|
1752
2024
|
from: "routeTimeoutFallback",
|
|
1753
2025
|
switch: {
|
|
@@ -1755,7 +2027,6 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1755
2027
|
cases: {
|
|
1756
2028
|
implement: "implement",
|
|
1757
2029
|
planVerification: "planVerification",
|
|
1758
|
-
verify: "verify",
|
|
1759
2030
|
fix: "fix",
|
|
1760
2031
|
publish: "publish",
|
|
1761
2032
|
addressP2: "addressP2",
|
|
@@ -1763,10 +2034,11 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1763
2034
|
inspectComments: "inspectComments",
|
|
1764
2035
|
inspectCi: "inspectCi",
|
|
1765
2036
|
opportunisticTest: "opportunisticTest",
|
|
2037
|
+
finalizeDefaultBranch: "finalizeDefaultBranch",
|
|
1766
2038
|
finalizeDelivery: "finalizeDelivery",
|
|
1767
2039
|
selectReviewCommands: "selectReviewCommands",
|
|
1768
2040
|
redesign: "redesign",
|
|
1769
|
-
blocked: "
|
|
2041
|
+
blocked: "createBlockerClaim",
|
|
1770
2042
|
},
|
|
1771
2043
|
},
|
|
1772
2044
|
},
|
|
@@ -1777,7 +2049,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1777
2049
|
cases: {
|
|
1778
2050
|
ok: "classifyImplementation",
|
|
1779
2051
|
timed_out: "timeoutFallbackGuard",
|
|
1780
|
-
failed: "
|
|
2052
|
+
failed: "timeoutFallbackGuard",
|
|
1781
2053
|
},
|
|
1782
2054
|
},
|
|
1783
2055
|
},
|
|
@@ -1786,64 +2058,100 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1786
2058
|
switch: {
|
|
1787
2059
|
on: "$.route",
|
|
1788
2060
|
cases: {
|
|
1789
|
-
verify: "
|
|
2061
|
+
verify: "selectVerificationPath",
|
|
1790
2062
|
redesign: "redesign",
|
|
1791
2063
|
fix: "fix",
|
|
1792
|
-
blocked: "
|
|
2064
|
+
blocked: "createBlockerClaim",
|
|
1793
2065
|
},
|
|
1794
2066
|
},
|
|
1795
2067
|
},
|
|
2068
|
+
{ from: "createBlockerClaim", to: "routeBlockerClaim" },
|
|
2069
|
+
{
|
|
2070
|
+
from: "routeBlockerClaim",
|
|
2071
|
+
switch: {
|
|
2072
|
+
on: "$.route",
|
|
2073
|
+
cases: { challenge: "challengeBlockerGuard", blocked: "blocked" },
|
|
2074
|
+
},
|
|
2075
|
+
},
|
|
1796
2076
|
{
|
|
1797
2077
|
from: "challengeBlockerGuard",
|
|
1798
|
-
switch: {
|
|
2078
|
+
switch: {
|
|
2079
|
+
on: "$.route",
|
|
2080
|
+
cases: { challenge: "challengeBlocker", blocked: "createBlockerClaim" },
|
|
2081
|
+
},
|
|
1799
2082
|
},
|
|
1800
2083
|
{
|
|
1801
2084
|
from: "challengeBlocker",
|
|
1802
|
-
switch: { on: "$.route", cases: { continue: "
|
|
2085
|
+
switch: { on: "$.route", cases: { continue: "routeChallenge", blocked: "blocked" } },
|
|
1803
2086
|
},
|
|
1804
2087
|
{
|
|
1805
|
-
from: "
|
|
2088
|
+
from: "routeChallenge",
|
|
1806
2089
|
switch: {
|
|
1807
|
-
on: "
|
|
2090
|
+
on: "$.route",
|
|
1808
2091
|
cases: {
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
2092
|
+
planDiscovery: "findPlan",
|
|
2093
|
+
workspace: "workspace",
|
|
2094
|
+
documentation: "documentation",
|
|
2095
|
+
implementation: "implement",
|
|
2096
|
+
repair: "fix",
|
|
2097
|
+
review: "selectReviewCommands",
|
|
2098
|
+
ci: "inspectCi",
|
|
2099
|
+
delivery: "finalizeDelivery",
|
|
2100
|
+
redesign: "redesign",
|
|
2101
|
+
blocked: "blocked",
|
|
1812
2102
|
},
|
|
1813
2103
|
},
|
|
1814
2104
|
},
|
|
1815
|
-
{ from: "runVerification", to: "verify" },
|
|
1816
2105
|
{
|
|
1817
|
-
from: "
|
|
2106
|
+
from: "selectVerificationPath",
|
|
2107
|
+
switch: { on: "$.route", cases: { plan: "planVerification", verify: "localVerification" } },
|
|
2108
|
+
},
|
|
2109
|
+
{
|
|
2110
|
+
from: "planVerification",
|
|
1818
2111
|
switch: {
|
|
1819
2112
|
on: "$result.outcome",
|
|
1820
2113
|
cases: {
|
|
1821
|
-
ok: "
|
|
2114
|
+
ok: "localVerification",
|
|
1822
2115
|
timed_out: "timeoutFallbackGuard",
|
|
1823
|
-
failed: "
|
|
2116
|
+
failed: "timeoutFallbackGuard",
|
|
1824
2117
|
},
|
|
1825
2118
|
},
|
|
1826
2119
|
},
|
|
2120
|
+
{ from: "localVerification.ready", to: "routeVerifiedWorkspace" },
|
|
2121
|
+
{ from: "localVerification.blocked", to: "createBlockerClaim" },
|
|
1827
2122
|
{
|
|
1828
|
-
from: "
|
|
2123
|
+
from: "routeVerifiedWorkspace",
|
|
1829
2124
|
switch: {
|
|
1830
2125
|
on: "$.route",
|
|
2126
|
+
cases: { pullRequest: "publish", defaultBranch: "finalizeDefaultBranch" },
|
|
2127
|
+
},
|
|
2128
|
+
},
|
|
2129
|
+
{
|
|
2130
|
+
from: "finalizeDefaultBranch",
|
|
2131
|
+
switch: {
|
|
2132
|
+
on: "$result.outcome",
|
|
1831
2133
|
cases: {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
blocked: "challengeBlockerGuard",
|
|
2134
|
+
ok: "routeFinalizeDefaultBranchResult",
|
|
2135
|
+
timed_out: "timeoutFallbackGuard",
|
|
2136
|
+
failed: "timeoutFallbackGuard",
|
|
1836
2137
|
},
|
|
1837
2138
|
},
|
|
1838
2139
|
},
|
|
2140
|
+
{
|
|
2141
|
+
from: "routeFinalizeDefaultBranchResult",
|
|
2142
|
+
switch: {
|
|
2143
|
+
on: "$.status",
|
|
2144
|
+
cases: { completed: "finalize", blocked: "createBlockerClaim" },
|
|
2145
|
+
},
|
|
2146
|
+
},
|
|
1839
2147
|
{
|
|
1840
2148
|
from: "fix",
|
|
1841
2149
|
switch: {
|
|
1842
2150
|
on: "$result.outcome",
|
|
1843
2151
|
cases: {
|
|
1844
|
-
ok: "
|
|
2152
|
+
ok: "selectVerificationPath",
|
|
1845
2153
|
timed_out: "timeoutFallbackGuard",
|
|
1846
|
-
failed: "
|
|
2154
|
+
failed: "timeoutFallbackGuard",
|
|
1847
2155
|
},
|
|
1848
2156
|
},
|
|
1849
2157
|
},
|
|
@@ -1854,7 +2162,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1854
2162
|
cases: {
|
|
1855
2163
|
ok: "selectReviewCommands",
|
|
1856
2164
|
timed_out: "timeoutFallbackGuard",
|
|
1857
|
-
failed: "
|
|
2165
|
+
failed: "timeoutFallbackGuard",
|
|
1858
2166
|
},
|
|
1859
2167
|
},
|
|
1860
2168
|
},
|
|
@@ -1870,7 +2178,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1870
2178
|
from: "repairReviewCommand",
|
|
1871
2179
|
switch: {
|
|
1872
2180
|
on: "$.route",
|
|
1873
|
-
cases: { retry: "runReview", blocked: "
|
|
2181
|
+
cases: { retry: "runReview", blocked: "createBlockerClaim" },
|
|
1874
2182
|
},
|
|
1875
2183
|
},
|
|
1876
2184
|
{
|
|
@@ -1896,7 +2204,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1896
2204
|
cases: {
|
|
1897
2205
|
ok: "verifyP2",
|
|
1898
2206
|
timed_out: "timeoutFallbackGuard",
|
|
1899
|
-
failed: "
|
|
2207
|
+
failed: "timeoutFallbackGuard",
|
|
1900
2208
|
},
|
|
1901
2209
|
},
|
|
1902
2210
|
},
|
|
@@ -1907,7 +2215,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1907
2215
|
cases: {
|
|
1908
2216
|
ok: "routeVerifyP2Result",
|
|
1909
2217
|
timed_out: "timeoutFallbackGuard",
|
|
1910
|
-
failed: "
|
|
2218
|
+
failed: "timeoutFallbackGuard",
|
|
1911
2219
|
},
|
|
1912
2220
|
},
|
|
1913
2221
|
},
|
|
@@ -1922,7 +2230,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1922
2230
|
cases: {
|
|
1923
2231
|
ok: "routeInspectCommentsResult",
|
|
1924
2232
|
timed_out: "timeoutFallbackGuard",
|
|
1925
|
-
failed: "
|
|
2233
|
+
failed: "timeoutFallbackGuard",
|
|
1926
2234
|
},
|
|
1927
2235
|
},
|
|
1928
2236
|
},
|
|
@@ -1934,7 +2242,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1934
2242
|
redesign: "redesign",
|
|
1935
2243
|
fix: "fix",
|
|
1936
2244
|
ci: "inspectCi",
|
|
1937
|
-
blocked: "
|
|
2245
|
+
blocked: "createBlockerClaim",
|
|
1938
2246
|
},
|
|
1939
2247
|
},
|
|
1940
2248
|
},
|
|
@@ -1945,7 +2253,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1945
2253
|
cases: {
|
|
1946
2254
|
ok: "routeInspectCiResult",
|
|
1947
2255
|
timed_out: "timeoutFallbackGuard",
|
|
1948
|
-
failed: "
|
|
2256
|
+
failed: "timeoutFallbackGuard",
|
|
1949
2257
|
},
|
|
1950
2258
|
},
|
|
1951
2259
|
},
|
|
@@ -1957,7 +2265,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1957
2265
|
green: "finalizeDelivery",
|
|
1958
2266
|
failed: "classifyCi",
|
|
1959
2267
|
pending: "trackCi",
|
|
1960
|
-
unavailable: "
|
|
2268
|
+
unavailable: "createBlockerClaim",
|
|
1961
2269
|
},
|
|
1962
2270
|
},
|
|
1963
2271
|
},
|
|
@@ -1969,7 +2277,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1969
2277
|
from: "repairCiCommand",
|
|
1970
2278
|
switch: {
|
|
1971
2279
|
on: "$.route",
|
|
1972
|
-
cases: { retry: "trackCi", blocked: "
|
|
2280
|
+
cases: { retry: "trackCi", blocked: "createBlockerClaim" },
|
|
1973
2281
|
},
|
|
1974
2282
|
},
|
|
1975
2283
|
{
|
|
@@ -1980,7 +2288,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1980
2288
|
green: "finalizeDelivery",
|
|
1981
2289
|
failed: "classifyCi",
|
|
1982
2290
|
pending: "opportunisticTest",
|
|
1983
|
-
unavailable: "
|
|
2291
|
+
unavailable: "createBlockerClaim",
|
|
1984
2292
|
},
|
|
1985
2293
|
},
|
|
1986
2294
|
},
|
|
@@ -1991,7 +2299,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
1991
2299
|
cases: {
|
|
1992
2300
|
ok: "inspectCi",
|
|
1993
2301
|
timed_out: "timeoutFallbackGuard",
|
|
1994
|
-
failed: "
|
|
2302
|
+
failed: "timeoutFallbackGuard",
|
|
1995
2303
|
},
|
|
1996
2304
|
},
|
|
1997
2305
|
},
|
|
@@ -2003,7 +2311,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
2003
2311
|
redesign: "redesign",
|
|
2004
2312
|
fix: "fix",
|
|
2005
2313
|
unrelated: "finalizeDelivery",
|
|
2006
|
-
blocked: "
|
|
2314
|
+
blocked: "createBlockerClaim",
|
|
2007
2315
|
},
|
|
2008
2316
|
},
|
|
2009
2317
|
},
|
|
@@ -2014,7 +2322,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
2014
2322
|
cases: {
|
|
2015
2323
|
ok: "routeFinalizeDeliveryResult",
|
|
2016
2324
|
timed_out: "timeoutFallbackGuard",
|
|
2017
|
-
failed: "
|
|
2325
|
+
failed: "timeoutFallbackGuard",
|
|
2018
2326
|
},
|
|
2019
2327
|
},
|
|
2020
2328
|
},
|
|
@@ -2022,7 +2330,7 @@ export const autoimplementWorkflow = defineWorkflow({
|
|
|
2022
2330
|
from: "routeFinalizeDeliveryResult",
|
|
2023
2331
|
switch: {
|
|
2024
2332
|
on: "$.status",
|
|
2025
|
-
cases: { completed: "finalize", blocked: "
|
|
2333
|
+
cases: { completed: "finalize", blocked: "createBlockerClaim" },
|
|
2026
2334
|
},
|
|
2027
2335
|
},
|
|
2028
2336
|
],
|