Skip to content

Commit 1733e58

Browse files
committed
feat(agent): require conflict check before submitting PR for review
Worker agents must now check `gh pr view --json mergeable` and resolve any merge conflicts before calling `task review`. Replaces `ak wait pr` with `gh pr checks --watch` in the system prompt for consistency.
1 parent a79c3bf commit 1733e58

3 files changed

Lines changed: 20 additions & 13 deletions

File tree

packages/cli/src/agent/systemPrompt.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ const DEV_LIFECYCLE = `\
5555
1. **Claim** — \`ak task claim <task-id>\` to confirm you are starting work.
5656
2. **Work** — Implement the change. Log progress: \`ak create note --task <task-id> "message"\`.
5757
3. **PR** — Push your branch, create a PR with \`gh pr create\`.
58-
4. **Wait for CI** — Run \`ak wait pr <pr-number>\` to wait until all CI checks pass. If checks fail, fix the issues, push again, and re-run the wait.
59-
5. **Deliver** — Once CI is green, submit: \`ak task review <task-id> --pr-url <url>\`. **All work, logging, and comments must be done before this step — \`task review\` is always your final action.**`;
58+
4. **Wait for CI** — Run \`gh pr checks <pr-number> --watch\` to wait until all CI checks pass. If checks fail, fix the issues, push again, and re-run the wait.
59+
5. **Check for conflicts** — Run \`gh pr view <pr-number> --json mergeable\`. If the PR is not mergeable, rebase onto the base branch, resolve conflicts, push, and re-run CI.
60+
6. **Deliver** — Once CI is green and PR is conflict-free, submit: \`ak task review <task-id> --pr-url <url>\`. **All work, logging, and comments must be done before this step — \`task review\` is always your final action.**`;
6061

6162
const OPS_LIFECYCLE = `\
6263
1. **Claim** — \`ak task claim <task-id>\` to confirm you are starting work.

skills/agent-kanban/SKILL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ You are an agent. Use the `ak` CLI to work on tasks. Your identity is initialize
1515
3. **Local test** → run the project's test suite and type check before pushing. Fix all failures locally. Skip only if tests cannot run locally.
1616
4. **PR** → push branch, `gh pr create`
1717
5. **Wait for CI**`gh pr checks <pr-number> --watch` — fix failures, push, re-check until green
18-
6. **Submit for review** once CI passes → `ak task review <id> --pr-url <url>`
18+
6. **Check for merge conflicts**`gh pr view <pr-number> --json mergeable` — if `mergeable` is not `MERGEABLE`, rebase onto the base branch, resolve conflicts, push, and re-run CI before proceeding
19+
7. **Submit for review** once CI passes and PR is conflict-free → `ak task review <id> --pr-url <url>`
1920

2021
## Commands
2122

@@ -101,6 +102,7 @@ ak create task --board <id> --title "Title" \
101102
- **If claim fails, stop immediately** — do not write any code or make any changes. Report the error and wait.
102103
- **Never call `task complete`** — only humans complete tasks.
103104
- **Test before pushing** — run the project's test suite and type check locally. All tests must pass before `git push`. Skip only if tests cannot run locally. Do not rely on CI to catch failures you could have caught locally.
105+
- **No conflicts before review** — before submitting `task review`, check `gh pr view --json mergeable`. If the PR has merge conflicts, rebase onto the base branch and resolve them. Never submit a conflicted PR for review.
104106
- Always create a PR and submit via `task review --pr-url` when your work produces code changes.
105107
- Log progress frequently — humans monitor the board.
106108
- **Every commit MUST include an `Agent-Profile` trailer** linking to this agent's profile page.

tests/systemPrompt.test.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ describe("generateSystemPrompt — dev board", () => {
3434
expect(prompt).not.toContain("ak task log");
3535
});
3636

37-
it("contains ak wait pr in the dev lifecycle", () => {
37+
it("contains gh pr checks in the dev lifecycle", () => {
3838
const prompt = generateSystemPrompt(makeAgent(), "dev");
39-
expect(prompt).toContain("ak wait pr");
39+
expect(prompt).toContain("gh pr checks");
40+
});
41+
42+
it("contains conflict check step in the dev lifecycle", () => {
43+
const prompt = generateSystemPrompt(makeAgent(), "dev");
44+
expect(prompt).toContain("Check for conflicts");
4045
});
4146

4247
it("dev lifecycle has a PR step (gh pr create)", () => {
@@ -52,15 +57,14 @@ describe("generateSystemPrompt — dev board", () => {
5257
it("dev lifecycle has 5 numbered steps", () => {
5358
const prompt = generateSystemPrompt(makeAgent(), "dev");
5459
// Steps 1–5 must all appear in the lifecycle constant
55-
for (let i = 1; i <= 5; i++) {
60+
for (let i = 1; i <= 6; i++) {
5661
expect(prompt).toContain(`${i}.`);
5762
}
5863
});
5964

60-
it("dev lifecycle does NOT have a 6th numbered lifecycle step", () => {
65+
it("dev lifecycle does NOT have a 7th numbered lifecycle step", () => {
6166
const prompt = generateSystemPrompt(makeAgent(), "dev");
62-
// The lifecycle constant ends at step 5 — step 6 is not a lifecycle step
63-
expect(prompt).not.toMatch(/^6\.\s+\*\*/m);
67+
expect(prompt).not.toMatch(/^7\.\s+\*\*/m);
6468
});
6569

6670
it("includes agent identity with correct id", () => {
@@ -103,9 +107,9 @@ describe("generateSystemPrompt — dev board", () => {
103107
expect(prompt).toMatch(/4\.\s+\*\*Wait for CI\*\*/);
104108
});
105109

106-
it("Deliver step is step 5", () => {
110+
it("Deliver step is step 6", () => {
107111
const prompt = generateSystemPrompt(makeAgent(), "dev");
108-
expect(prompt).toMatch(/5\.\s+\*\*Deliver\*\*/);
112+
expect(prompt).toMatch(/6\.\s+\*\*Deliver\*\*/);
109113
});
110114

111115
it("Handoff is described in its own section, not as a numbered lifecycle step", () => {
@@ -129,9 +133,9 @@ describe("generateSystemPrompt — ops board", () => {
129133
expect(prompt).not.toContain("ak task log");
130134
});
131135

132-
it("does NOT contain ak wait pr (ops has no PR step)", () => {
136+
it("does NOT contain gh pr checks (ops has no PR step)", () => {
133137
const prompt = generateSystemPrompt(makeAgent(), "ops");
134-
expect(prompt).not.toContain("ak wait pr");
138+
expect(prompt).not.toContain("gh pr checks");
135139
});
136140

137141
it("does NOT contain gh pr create (ops has no PR step)", () => {

0 commit comments

Comments
 (0)