CodeCannon start

Code Cannon: Start a new feature or bugfix

install
source · Clone the upstream repo
git clone https://github.com/LightbridgeLab/CodeCannon
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/LightbridgeLab/CodeCannon "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.gemini/skills/start" ~/.claude/skills/lightbridgelab-codecannon-start-64bf1c && rm -rf "$T"
manifest: .gemini/skills/start/SKILL.md
source content

Gemini CLI: This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in

/submit-for-review
must be done manually using the review-agent prompt in a separate session.


CRITICAL: Order of operations

You must complete Steps 1–4 before writing any code. Do not open any source file with intent to edit until

git branch --show-current
shows a
feature/*
branch.


Determine case

If

$ARGUMENTS
is a number (digits only) → go to Case B: Resume existing issue. Otherwise → go to Case A: New work.


Parsing $ARGUMENTS (Case A only)

Skip this entirely if

$ARGUMENTS
triggered Case B.

The argument string may contain optional inline flags after the description. Parse as follows:

  1. Identify flags — scan for the first token that starts with
    --label
    ,
    -l
    ,
    --milestone
    , or
    -m
    . Everything before it is the description. Everything from the first flag onward is flags.
  2. --label <value>
    /
    -l <value>
    — comma-separated label string (e.g.
    bug
    or
    enhancement,ux
    ). If provided, it bypasses label auto-selection entirely for this invocation — use the value verbatim. Labels containing spaces must be quoted (e.g.
    --label "good first issue"
    ).
  3. --milestone <value>
    /
    -m <value>
    — milestone name or number (e.g.
    Sprint 4
    or
    12
    ). Pass the value as-is; GitHub accepts both names and numbers.
  4. Flags may appear in any order after the description.

Label resolution (three-tier, Case A only):

After parsing flags, determine the active labels in this order:

  1. Per-invocation flag — if
    --label <value>
    was in
    $ARGUMENTS
    , use that value verbatim. Skip all remaining steps.
  2. Pool-based selection — the allowed label pool is:
    bug, documentation, enhancement, chore
    (comma-separated). Select 1–3 labels from this pool that genuinely fit the task description and implementation approach. Do not apply labels mechanically — pick only what fits. If no pool label fits the task, fall through to step 3.
    • If any selected label name contains a space (e.g.
      good first issue
      ), quote the entire
      --label
      value.
  3. No label / creation — if the pool is empty or no pool label fits:
    • Label creation is not allowed in this project. Omit
      --label
      entirely. Proceed silently; do not inform the user.

Milestone resolution (three-tier, Case A only):

After parsing flags, determine the active milestone in this order:

  1. Per-invocation flag — if
    --milestone <value>
    was in
    $ARGUMENTS
    , use that value. Stop.
  2. Auto-detect — if no milestone is resolved yet, query open milestones:
    gh api repos/{owner}/{repo}/milestones --jq '[.[] | select(.state=="open")] | {count: length, milestones: [.[] | {number: .number, title: .title}]}'
    
    Use
    gh repo view --json owner,name
    first if the owner/repo are not already known.
    • 0 results → no milestone; proceed without
      --milestone
      .
    • 1 result → use its title silently. Inform the user inline:
      (milestone: <title>)
      .
    • 2+ results → show the numbered list, ask once: "Multiple open milestones — which should this issue go under? (enter a number or title, or 'none')". Accept milestone number, title, or "none"/"skip". Wait for response before continuing.

Examples:

$ARGUMENTS
DescriptionLabelsMilestone
Add dark mode toggle to settings page
Add dark mode toggle to settings page
auto-selected from poolauto-detected
Add dark mode --label enhancement
Add dark mode
enhancement
(verbatim)
auto-detected
Add dark mode --label enhancement,ux --milestone "Sprint 4"
Add dark mode
enhancement,ux
(verbatim)
Sprint 4

Replace vs append: flags replace auto-selection entirely, they do not append. This avoids silent label duplication and milestone conflicts.


Pre-check: Existing feature branch

Before entering Case A or Case B, check the current branch:

git branch --show-current

If already on a

feature/*
branch and
$ARGUMENTS
is not a number (i.e. this is new work, not a resume):

Say:

"You're already on

feature/<name>
. Would you like to create a GitHub issue linked to this branch and start coding? Or switch to the base branch first? (yes to continue here / no to abort)"

Stop. Wait for the user to respond.

  • Yes → proceed to Case A, but skip Step 4 (branch creation) entirely. The current branch is used as-is. In Step 3, after creating the issue, link it to the existing branch by running:
    gh issue develop <number> --base <base-branch> --name <current-branch-name>
    
    This links the issue to the branch in GitHub without creating or checking out a new branch. If
    gh issue develop
    fails because the branch already exists on the remote, that is fine — the link may already be established. Continue to Step 5.
  • No / abort → stop. Tell the user to switch to the base branch and run
    /start
    again.

If already on a

feature/*
branch and
$ARGUMENTS
is a number → proceed to Case B normally (it handles branch checkout itself).

If on any other branch → proceed to Case A or Case B as determined by the

$ARGUMENTS
check above.


Case A: New work (text description)

Step 1 — Investigate

Read the relevant code. Propose a concrete implementation approach. Be specific about which files change and how.

Step 2 — HUMAN GATE

Say exactly:

"Does this approach sound right? Type

go
to create a GitHub issue and branch, or share any questions/adjustments first."

Stop. Wait for the user to respond.

The friendly text question is required regardless of harness mode. If your harness is currently in a preview / plan / dry-run mode where you cannot passively stop and wait (and must instead invoke the harness's own approval mechanism), still include the text question in your response. The harness's approval UI mediates the wait, but it is not a substitute for the question itself. Users expect to see the consistent text language across all modes; do not silently swap it for the harness's UI.

Intent classification (not keyword matching):

  • Affirmative with no conditions ("go", "yes", "looks good", "let's do it") → continue to Step 3.
  • Affirmative with conditions ("go, but first change X", "yes but can we also...") → treat as discussion. Address the conditions, revise the approach if needed, then re-ask.
  • Questions or pushback ("what about...", "I'm not sure about...", any adjustment) → discuss, revise approach, re-ask.
  • Abandonment ("never mind", "not now", "stop") → stop. Nothing to clean up.

Step 3 — Create GitHub Issue

Create the issue in two steps — this exact sequence is mandatory:

Step 3a — Create a temp directory and write the body file. Run:

mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX

Note the returned path (e.g.

/tmp/CodeCannon/a8f3b2
). Use this path for all temp files in this invocation.

Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create

<tmpdir>/issue_body.md
with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs,
cat
, or
echo
. The file-writing tool bypasses shell parsing entirely.

Step 3b — Run

gh issue create
with
--body-file
pointing to the temp file:

gh issue create \
  --title "<standalone full sentence — must make sense with no context>" \
  --assignee @me \
  [--label "<resolved labels>"] \
  [--milestone "<resolved milestone>"] \
  --body-file <tmpdir>/issue_body.md

IMPORTANT — never pass body content inline in the

gh
command. Do not use
--body
,
--body-file -
, heredocs (
<<EOF
or
<<'EOF'
), or
$(cat ...)
. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags
#
headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then
--body-file <path>
— is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex.

Resolve labels and milestone using the resolution steps in the Parsing section above:

  • Labels: use the value from three-tier label resolution. If non-empty, add
    --label "<value>"
    to the command. If empty (no flag, empty pool, creation not allowed), omit
    --label
    entirely.
  • Milestone: use the value from three-tier milestone resolution. If non-empty, add
    --milestone "<value>"
    to the command. If empty (no flag, no config default, no open milestones), omit
    --milestone
    entirely.

Body structure (required sections, in this order):

## Problem to Fix
<what is broken or missing, written for a non-developer — no code or file paths>

## Why it Matters
<the impact or motivation — who is affected and how>

## General Approach
<high-level direction for the fix, in plain language>

## Complexity
**Verification / QA effort:** <trivial | moderate | significant | extensive>
<one-line justification — what makes verification easy or hard for this specific change>

## Acceptance Criteria
- <specific, verifiable outcome>
- <another outcome>

All five sections are required. Write for a non-developer audience — no code, no file paths. Acceptance Criteria must be concrete and verifiable (not vague goals).

Complexity scale guidance (for agent use only — do not include the scale definition in the issue body):

  • trivial — single obvious check (e.g. color change, label text, toggle visibility)
  • moderate — a few scenarios to verify, minor setup needed (e.g. form validation, a new UI component with a couple of states)
  • significant — many scenarios, data setup, or cross-feature impact (e.g. multi-step workflow, permission changes across roles)
  • extensive — complex data flows, integration testing, or edge cases spanning multiple areas (e.g. data import/export mapping, API contract changes consumed by multiple clients)

Title rules:

  • Fix 'Contact Us' footer link pointing to 404 instead of /contact-us
  • Fix broken link

After the command runs, note the issue number from the output URL (e.g.

https://github.com/.../issues/42
→ issue
42
).

Show the user:

Created issue #<number>: <title>

Then immediately post agent implementation notes as a comment.

Use your file-writing tool (not Bash) to create

<tmpdir>/issue_comment.md
(same temp directory from Step 3a):

## Agent Implementation Notes

<full technical plan: exact files to change, approach, key decisions, edge cases>

Then post it (do NOT use

--body
or heredocs — same rule as Step 3):

gh issue comment <number> --body-file <tmpdir>/issue_comment.md

Step 4 — Create feature branch

Ensure the base branch is up-to-date before branching:

git checkout dev && git pull origin dev

Now create the feature branch:

gh issue develop <number> --base dev --name feature/<number>-<short-descriptive-name> --checkout

--base
is required:
gh issue develop
reads the default base from the GitHub API, not from local working state, so
git checkout dev
on its own does not influence which branch the new feature branch is cut from.

Verify the branch was created:

git branch --show-current

Show the user:

On branch feature/<name>

Do not proceed to Step 5 until this shows a

feature/*
branch.

Step 5 — Write the code

Now write the code. Do NOT commit anything.

When done, say: "The code is ready for review. Please run

make dev
and test locally. Let me know if it looks good, needs changes, or should be scrapped. When you're happy, run
/submit-for-review
to commit, push, and open a PR."

  • User says looks good → run
    /submit-for-review
  • User requests changes → iterate, repeat this message
  • User says scrap it → run
    make abandon

Case B: Resume existing issue (numeric argument)

Step 1 — Load context

gh issue view <number> --comments

Read the full body and all comments. Note: what was done, what remains, branch status.

Step 2 — Summarize and gate

Tell the user:

  • What the issue is about
  • What was previously done (from agent notes if present)
  • What appears to remain

Ask: "Does this match your understanding? Type

go
to start coding, or share any questions/adjustments first."

Intent classification (not keyword matching):

  • Affirmative with no conditions ("go", "yes", "continue", "looks right") → proceed to Step 3.
  • Affirmative with conditions ("go, but first...", "yes but let's also...") → treat as discussion. Address the conditions, then re-ask.
  • Questions or discussion ("what about...", "can we change...", any adjustment) → discuss, then re-ask.
  • Fresh start ("open a new one", "start fresh", "new ticket") → restart as Case A with a new description.
  • Abandonment ("never mind", "not now", "stop") → stop. Nothing to clean up.

Step 3 — Check out branch

Ensure the base branch is up-to-date before branching:

git checkout dev && git pull origin dev

Find and check out the existing branch, or create a new one linked to the issue:

gh issue develop <number> --base dev --name feature/<number>-<short-name> --checkout

--base
is required:
gh issue develop
reads the default base from the GitHub API, not from local working state.

Verify:

git branch --show-current

Post a resumption comment:

gh issue comment <number> --body "Resuming work. <brief note on what's being continued.>"

Step 4 — Write the code

Continue from where work left off. Do NOT commit.

When done, say: "The code is ready for review. Please run

make dev
and test locally. When you're happy, run
/submit-for-review
to commit, push, and open a PR."


Hard rules

  • Do not write or edit any source file before
    git branch --show-current
    shows
    feature/*
    .
  • Do not use
    make branch
    — always use
    gh issue develop
    so the branch is linked to the issue in GitHub.
  • Do not commit during
    /start
    — commits happen in
    /submit-for-review
    .
  • If already on a feature branch when
    /start
    is invoked with new work (Case A), prompt the user to either continue on the current branch (skipping branch creation) or abort. See Pre-check: Existing feature branch above.
  • gh issue create
    must use
    --title
    and
    --body-file
    flags. Never pass body content inline or open an interactive editor.
  • The issue is assigned to
    @me
    at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with
    gh issue edit <number> --remove-assignee @me
    .
  • Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from
    bug, documentation, enhancement, chore
    → omit
    --label
    entirely. Never apply a label outside
    bug, documentation, enhancement, chore
    .
  • Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation.
<!-- generated by CodeCannon/sync.py | skill: start | adapter: gemini | hash: 7d162d14 | DO NOT EDIT — run CodeCannon/sync.py to regenerate -->