feat: committer distinguishes recoverable vs unrecoverable failures
CommitterMeta is now a 3-way discriminated union: - committed: success with branch + commitSha - recoverable: coder can fix (hook failures, lint, test, conflicts) - unrecoverable: can't be fixed by code (auth, permissions, disk) Moderator routes recoverable → coder for retry.
This commit is contained in:
@@ -68,7 +68,7 @@ describe("createCommitterRole", () => {
|
|||||||
|
|
||||||
test("returns failed meta when extraction reports failure", async () => {
|
test("returns failed meta when extraction reports failure", async () => {
|
||||||
const failed = {
|
const failed = {
|
||||||
status: "failed" as const,
|
status: "recoverable" as const,
|
||||||
error: "working tree clean; nothing to commit",
|
error: "working tree clean; nothing to commit",
|
||||||
logRef: null as string | null,
|
logRef: null as string | null,
|
||||||
};
|
};
|
||||||
@@ -91,7 +91,7 @@ describe("createCommitterRole", () => {
|
|||||||
|
|
||||||
test("returns failed meta with logRef when extraction includes it", async () => {
|
test("returns failed meta with logRef when extraction includes it", async () => {
|
||||||
const failed = {
|
const failed = {
|
||||||
status: "failed" as const,
|
status: "recoverable" as const,
|
||||||
error: "push rejected",
|
error: "push rejected",
|
||||||
logRef: "LOGREF01",
|
logRef: "LOGREF01",
|
||||||
};
|
};
|
||||||
@@ -125,7 +125,7 @@ describe("createCommitterRole", () => {
|
|||||||
|
|
||||||
const out = await role(makeCtx());
|
const out = await role(makeCtx());
|
||||||
expect(out.meta).toEqual({
|
expect(out.meta).toEqual({
|
||||||
status: "failed",
|
status: "unrecoverable",
|
||||||
error: "committer role threw before structured result",
|
error: "committer role threw before structured result",
|
||||||
logRef: null,
|
logRef: null,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ export const committerMetaSchema = z.discriminatedUnion("status", [
|
|||||||
commitSha: z.string(),
|
commitSha: z.string(),
|
||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
status: z.literal("failed"),
|
status: z.literal("recoverable"),
|
||||||
|
error: z.string(),
|
||||||
|
logRef: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
status: z.literal("unrecoverable"),
|
||||||
error: z.string(),
|
error: z.string(),
|
||||||
logRef: z.string().nullable(),
|
logRef: z.string().nullable(),
|
||||||
}),
|
}),
|
||||||
@@ -54,7 +59,10 @@ Create a branch, commit the changes, and push. Report whether the push succeeded
|
|||||||
|
|
||||||
## On failure
|
## On failure
|
||||||
|
|
||||||
If any git operation fails (hook rejection, push denied, merge conflict, etc.), **do not attempt to fix it yourself**. Your job is to capture the key error output and report it back clearly so other roles in the workflow can address it.`;
|
If any git operation fails, **do not attempt to fix it yourself**. Capture the key error output and classify it:
|
||||||
|
|
||||||
|
- **Recoverable**: failures that a coder can fix (lint/test hook rejection, merge conflict, commit validation errors)
|
||||||
|
- **Unrecoverable**: failures beyond code changes (no push permission, remote not found, authentication denied, disk full)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +91,7 @@ export function createCommitterRole(
|
|||||||
onFail<CommitterMeta>({
|
onFail<CommitterMeta>({
|
||||||
label: "committer",
|
label: "committer",
|
||||||
meta: {
|
meta: {
|
||||||
status: "failed",
|
status: "unrecoverable",
|
||||||
error: "committer role threw before structured result",
|
error: "committer role threw before structured result",
|
||||||
logRef: null,
|
logRef: null,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ export const solveIssueModerator: Moderator<SolveIssueMeta> = (ctx) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (last.role === "committer") {
|
if (last.role === "committer") {
|
||||||
|
if (last.meta.status === "recoverable" && ctx.steps.length < maxRounds - 1) {
|
||||||
|
return "coder";
|
||||||
|
}
|
||||||
return END;
|
return END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user