# Agkan Run

> Use when starting a development session to pick the highest priority Todo task from agkan, implement it, create a pull request, and mark it done.

- Skill: `gendosu/agkan-run` (Agent Skill)
- Install (CLI): `npx skillmds@latest add gendosu/agkan-run`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gendosu/agkan-run/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: gendosu (https://skillmd.com/u/gendosu)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/gendosu/agkan-run

---


# agkan-run

## Overview

Standard workflow to pick the highest priority ready task from agkan, implement it, create a pull request, and complete it.

This is a loop: after each task completes (including handling any interruptions), re-fetch the task list and continue unless explicitly told to stop.

---

## Workflow

### 0. Fetch Config

```bash
CONFIG=$(agkan config get --json 2>/dev/null || echo '{}')
RUN_MODEL=$(echo "$CONFIG" | jq -r '.config.models.run.model // "sonnet"')
RUN_EFFORT=$(echo "$CONFIG" | jq -r '.config.models.run.effort // "high"')
```

These are the session defaults. A task's own run model / run effort (`model_run` / `effort_run`, set per task) override them in Step 5b.

### 1. Update branch to latest

Before switching to the default branch, check for uncommitted changes:

```bash
git status --porcelain
```

If there are uncommitted changes, stash them first:

```bash
git stash push -m "agkan-run: stash before switching to default branch"
```

Then get the default branch name dynamically and update to latest:

```bash
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@') && \
  [ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef -q '.defaultBranchRef.name' 2>/dev/null) && \
  git checkout "$DEFAULT_BRANCH" && git pull -p
```

### 2. Get ready tasks

```bash
agkan task list --status ready --json
```

### 3. Select the highest priority task

Evaluate tasks in descending order using the following criteria and select the top one:

**Skip tasks with `will-do-later` tag:**
Tasks with the `will-do-later` tag are intentionally postponed tasks. Skip them **unless** they are in `ready` status — a task promoted to `ready` is executable regardless of the tag.

Also skip any task whose ID was recorded as skipped in Step 5b earlier in this session (its run model cannot be launched from this skill).

**Priority (read from the `priority` field in the list JSON response):**
```
Critical > High > Medium > Low
```

**Tags (refer to when priority is the same):**
```
bug > security > improvement > test > performance > refactor > docs
```

**If there are child tasks or blocker tasks**
Prioritize the target child tasks or blocker tasks (same importance and tag criteria apply)

### 4. Check for blockers

```bash
agkan task block list <id> --json
```

If there are incomplete tasks in `blockedBy`, do not select that task. Instead, select a different task or process the blocker task first.

### 5. Update task to in_progress

```bash
agkan task update <id> status in_progress
```

### 5a. Inspect task for existing Branch/PR and run model/effort

Before launching the sub-agent, retrieve the task to get the branch, the task-level run model/effort, and check the body for a `PR:` label:

```bash
TASK=$(agkan task get <id> --json)
```

Extract:
- **Branch**: read from `.task.branch` (first-class column; `null` if not set)
- **PR**: parse the task body for a `PR: <URL>` label
- **Run model**: read from `.task.model_run` (first-class column; `null` if not set)
- **Run effort**: read from `.task.effort_run` (first-class column; `null` if not set)

`model_run` / `effort_run` are the task's "Run model" / "Run effort" (set with `agkan task update <id> --model-run <model> --effort-run <level>` or from the board's detail panel). They are not in `metadata`, and `agkan task list --json` does not include them — only `agkan task get --json` does.

Pass the Branch/PR values to the sub-agent prompt (Step 6) so it can resume work on the existing branch/PR instead of creating new ones. Carry the run model/effort into Step 5b.

### 5b. Resolve the model and effort for this task

A task's own run model / run effort take precedence over the session defaults from Step 0. This is the same precedence `agkan board` applies when it runs a task.

```bash
TASK_MODEL=$(echo "$TASK" | jq -r '.task.model_run // empty')
TASK_EFFORT=$(echo "$TASK" | jq -r '.task.effort_run // empty')
RUN_MODEL_FOR_TASK=${TASK_MODEL:-$RUN_MODEL}
RUN_EFFORT_FOR_TASK=${TASK_EFFORT:-$RUN_EFFORT}
```

The sub-agent is launched with the Task tool, whose `model` parameter accepts only the Claude aliases `fable`, `opus`, `sonnet`, and `haiku`. When `model_run` is set to anything else (for example a codex or agy model from the model catalog, such as `gpt-5.6-sol` or `gemini-3.8-flash`), this skill cannot run the task with the model it was configured for. Do not substitute another model. Instead:

1. Report it to the user: `Task #<id>: run model "<model_run>" cannot be launched by the Task tool; run this task from agkan board.`
2. Revert the task: `agkan task update <id> status ready`
3. Record the task ID as skipped for the rest of this session (see Step 3)
4. Go to Step 8

### 6. Implement, create PR, complete

**Use the Task tool (general-purpose sub-agent)** to implement.
Do not use `Skill("agkan-subtask")`; instead, embed the workflow steps directly in the sub-agent prompt.

> **Why embed steps instead of referencing a file path?**
> Sub-agents spawned via the Task tool start with a fresh context. When installed as a plugin, the skill files may reside at a path unknown to the sub-agent (e.g., under a plugin cache directory), so instructing the sub-agent to read a relative or installation-specific path is unreliable. Embedding the workflow steps directly in the prompt makes the instructions path-independent.

Before calling Task(), substitute the placeholders with the values resolved in Step 5b (task-level override, falling back to the Step 0 session defaults):
- Replace `<RUN_MODEL>` with the value of `$RUN_MODEL_FOR_TASK`
- Replace `<RUN_EFFORT>` with the value of `$RUN_EFFORT_FOR_TASK`

```
Task(
  subagent_type="general-purpose",
  model="<RUN_MODEL>",
  description="Implement task #<id>",
  prompt="""
Please implement the following task.

Invoke the key-guidelines skill using the Skill tool: Skill("key-guidelines")

## Task Information
- ID: <id>
- Title: <title>
- Body: <body>

## Existing Branch/PR (if any)
- Branch: <existing-branch-name or "none">
- PR: <existing-PR-URL or "none">

If Branch or PR values above are set (not "none"), use them to resume work on the
existing branch and PR rather than creating new ones (as described in Step 2 below).

## Steps

Follow these steps to implement the task:

### 1. Update Task to In Progress

```bash
agkan task update <id> status in_progress
```

### 2. Check for Existing Branch/PR

The "Existing Branch/PR" values above come from the task record. Use them as follows:

**Case A — Branch is not "none":**

Check out the existing branch:

```bash
git fetch origin
git checkout <existing-branch-name>
```

Then check for conflicts with the default branch:

```bash
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
git merge-base --is-ancestor origin/$DEFAULT_BRANCH HEAD
```

If this check fails (exit code non-zero), the branch has diverged and there may be
conflicts. Surface a clear error and stop:

```
ERROR: Branch '<existing-branch-name>' has conflicts with '$DEFAULT_BRANCH'.
Please resolve the conflicts manually before resuming this task.
```

If no conflicts are detected, continue from Step 4 (skip Step 3, as the branch is
already recorded in the task).

**Case B — Branch is "none" (null in the task record):**

Generate a branch name from the task ID and title. Use the following naming convention:

- If the task has a `bug` or `security` tag → prefix `fix/`
- Otherwise → prefix `feat/`
- Format: `<prefix>/<id>-<title-slug>` (e.g., `feat/42-add-login-page`)

```bash
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
git fetch origin
git checkout -b <branch-name> origin/$DEFAULT_BRANCH
```

Then continue to Step 3.

### 3. Write Branch Name to Task

```bash
agkan task update <id> --branch <branch-name>
```

This stores the branch as a first-class column on the task record so subsequent skill
executions can resume work on the correct branch.

### 4. Implementation

Implement according to the task content.

Refer to /key-guidelines during implementation to maintain code quality.

### 5. Commit and Push

Stage files by specifying them explicitly. Do not use `git add -A` as it risks
including unintended files such as `.env` or credentials.

```bash
git add <file1> <file2> ...
git commit -m "<commit message>"
git push -u origin <branch-name>
```

> **Note**: Do not use `git add -A` or `git add .`. Files containing `.env`,
> `credentials.*`, or secrets may be committed unintentionally.

**After push, verify it succeeded before proceeding to Step 6:**

```bash
git ls-remote --heads origin <branch-name>
```

If push failed (empty output or non-zero exit code), record the error in the task
body and do NOT proceed to PR creation. Leave the task as `in_progress`.

**Recovery: If interrupted during Steps 4–7**

If an error, permission denial, or user interruption occurs during implementation
(Step 4), commit/push (Step 5), or PR creation (Step 6):
1. Do NOT update the task status to `review`
2. Record what happened in the task body
3. Leave the task as `in_progress` — complete the remaining steps before re-evaluating

### 6. Create PR

> PR creation after a successful push is required and must not be skipped. This
> step must complete before advancing to Steps 7 and 8. Skip PR creation only when
> an existing `PR:` label was found (Case A below) — do not skip it for any other
> reason, including approaching context limits.

If a `PR:` label was found in the task body (Step 2, Case A), skip PR creation —
the existing PR will be updated automatically when commits are pushed to the branch.

Otherwise, create a new PR. Choose draft or normal based on whether implementation is still remaining at this point:

- **Implementation remaining** — part of the task's work is not yet implemented (e.g., unchecked `- [ ]` items you have not implemented yet, or you are pushing an intermediate state and will continue implementing afterward) → create a **draft** PR:

  ```bash
  gh pr create --draft --title "<title>" --body "<body>"
  ```

- **Implementation complete** — all of the task's work is implemented and pushed → create a normal PR:

  ```bash
  gh pr create --title "<title>" --body "<body>"
  ```

A draft PR stays a draft while the task remains `in_progress`. It is converted back to a normal PR in Step 8 when the task advances to `review`.

### 7. Add PR Information to Task

If a `PR:` label was already present in the task body (Step 2, Case A), skip this step.

Otherwise, record the newly created PR URL:

```bash
# First, retrieve the existing body
agkan task get <id> --json
# Then update by concatenating existing body with PR URL
agkan task update <id> body "<existing body>\n\nPR: <PR URL>"
# Also store as metadata so the board detail panel can display it
agkan task meta set <id> pr <PR URL>
```

### 8. Update Task to Review

Only execute this step if implementation succeeded — specifically, if ALL of the following conditions are met:

**Implementation succeeded** means ALL of the following:
- At least one `git commit` was executed in this session (verify with `git log --oneline -1`)
- Actual code/file changes were committed (not just task management operations)
- `git push` completed without errors
- PR was created or already exists

> **Scope note**: The interruption guard below applies **only to this status
> transition decision** — not to Steps 4–7. If a confirmation or interruption
> occurred during implementation and has since been resolved, complete Steps 5–6
> before evaluating the guard below.

**The following do NOT count as implementation:**
- `agkan task comment add` (comment additions only)
- `agkan task update --body` / `--file` (body/metadata updates only)
- Discussion or planning without code commits

**Before updating to review, verify a commit was made:**

```bash
git log --oneline -1
```

If no commits were made in this session, do NOT update the status to review. Leave the task as `in_progress`.

**If a critical error occurred** (e.g., git push failed, PR creation failed, permission
denied), do NOT update the status to review. Leave the task as `in_progress` and record
the error details in the task body:

```bash
# On error: record what went wrong in the task body (optional but recommended)
agkan task get <id> --json
agkan task update <id> body "<existing body>\n\nError: <error description>"
# Do NOT run: agkan task update <id> status review
```

**If an unresolved interruption remains at this point** (e.g., push or PR creation in Steps 5–6 could not complete, a tool use is still blocked, or the skill is still awaiting user clarification), do NOT update the status to `review`. Leave the task as `in_progress`:

```bash
# When an unresolved interruption prevents completion: do NOT advance to review
# Resolve the interruption, complete Steps 5–6, then re-evaluate
# Do NOT run: agkan task update <id> status review
```

`review` status means implementation is **fully complete** — a PR has been successfully created and is awaiting human review. It does **not** mean "paused waiting for user input".

Whenever the task is left as `in_progress` for any of the reasons above, leave the PR as a draft — do not run `gh pr ready`.

**If only task management operations were performed** (comments, body updates, no commits), do NOT update the status to review. Leave the task as `in_progress`.

**If implementation succeeded** (commits were made and pushed, PR created, no unresolved interruptions), first convert a draft PR back to a normal PR, then update to review.

`review` means the PR is awaiting human review, so it must not remain a draft. If the PR is a draft (opened as a draft in Step 6, or in an earlier session via Case A), mark it ready for review. `<PR URL>` is the URL from Step 6 or from the existing `PR:` label:

```bash
if [ "$(gh pr view <PR URL> --json isDraft -q .isDraft)" = "true" ]; then
  gh pr ready <PR URL>
fi
```

Then update the status:

```bash
agkan task update <id> status review
```

Confirm the update succeeded:

```bash
agkan task get <id> --json
```

Verify that the status is `review`. If it is still `in_progress`, retry the update
command.

## Important Notes

- Do not mark task as done before PR is merged (mark as done after PR review and merge)
- The condition for moving a task to `review` (commit made, no critical error, no unresolved interruption) is defined in full in Step 8 above — see that step for the exact rule; it is not repeated here

## Effort
Thoroughness level for this session: <RUN_EFFORT>
- low: Implement quickly with minimal exploration; prefer direct solutions
- medium: Balance thoroughness with speed; standard implementation quality
- high: Be thorough; explore edge cases, add tests, review carefully
- xhigh: Recommended default for coding/agentic work; maximize correctness and edge-case coverage
- max: Reserve for the highest-stakes or most complex tasks
"""
)
```

### 7. Verify task status after sub-agent completes

After the sub-agent completes, check whether the task has been moved out of `in_progress`:

```bash
agkan task get <id> --json
```

If the status is still `in_progress`, determine whether the sub-agent encountered a critical error (git push failure, PR creation failure, permission error). Check the task body for any recorded error messages.

- **If a critical error occurred**: Do NOT update to `review`. Leave the task as `in_progress` so the issue can be resolved manually.
- **If only task management operations were performed** (comment additions, body updates, discussion — no actual commits): Do NOT update to `review`. Leave the task as `in_progress`.
- **If implementation succeeded** (at least one `git commit` was made and pushed, PR created) but the sub-agent forgot to update the status, verify with `git log --oneline -1` on the task's branch and update manually only if a commit exists:

```bash
# Verify a commit was actually made before marking review
git log --oneline -1
# Only if a commit is confirmed:
agkan task update <id> status review
```

**The following do NOT qualify as implementation success:**
- `agkan task comment add` (comment additions only)
- `agkan task update --body` / `--file` (body/metadata updates only)
- Discussion or planning without code commits

### 8. Handle interruptions, then ALWAYS re-fetch and continue

**After confirming the task status**, there may be interruptions before you can proceed:

#### Interruption types and how to handle them

| Interruption | How to handle | Then... |
|---|---|---|
| IDE diagnostic (linter, type error, etc.) | Fix the issue immediately | **Resume step 8** |
| User question about the current task | Answer, then fix if needed | **Resume step 8** |
| User explicitly says "stop" / "exit" | Stop the workflow | End session |

**IDE diagnostics (e.g., `<new-diagnostics>` in system-reminder) are part of the current task's implementation — not a reason to end the workflow.** Fix them and continue.

**After handling any interruption, always ask yourself:**
> "Am I in the middle of an agkan-run workflow? If yes, go back to step 8."

Re-fetch the task list to pick up any newly added ready tasks:

```bash
agkan task list --status ready --json
```

If there are no termination instructions from the user and ready tasks exist (including newly added ones), select the next task and repeat from step 3 of the workflow.

If no ready tasks remain, end the session.

---

## Loop Structure

The workflow above (Steps 0–8) is a loop: fetch tasks → select → implement → verify →
handle interruptions → re-fetch → repeat until no ready tasks remain or the user says
stop. If a diagnostic appears or the user asks a question after the sub-agent
completes, handle it and then resume from Step 8 (re-fetch the task list) rather than
ending the session.

> **Model differences:** Fable 5 = has a known early-stopping behavior at the end of long
> sessions, ending with a stated intent but no tool call, so this reminder (go back to Step 8
> and re-fetch) is kept. Opus 5 does not need this kind of reminder (strong completion tendency,
> early stopping is rare).

---

## Priority Determination Flow

```
Todo task list
    ↓
Sort by priority (Critical → High → Medium → Low)
    ↓
Multiple tasks with same priority?
   Yes → Sort by tag priority (bug → security → ... → docs)
   No  → Select top task
    ↓
Select 1 task and start work
```

---

## Tag Priority List

See the canonical definition in `agkan/SKILL.md` (Tag Priority section).

---

## Notes

- Always select only 1 task (do not start multiple tasks simultaneously)
- If no tasks exist, end the session
- Do not mark task as done before PR merge (mark as done after PR review and merge)
- See Step 8 (`review` status transition) and Loop Structure (handling interruptions) above for the exact rules — not repeated here

