Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
60ce454
Fix deploy-prod tag clobber and add validate to make dev
sebastientaggart Apr 9, 2026
3722b45
Merge pull request #90 from LightbridgeLab/feature/deploy-prod-tag-force
sebastientaggart Apr 10, 2026
b9ef018
Add Verification / QA effort complexity indicator to issue body template
sebastientaggart Apr 10, 2026
306ac8f
Merge pull request #92 from LightbridgeLab/feature/complexity-indicator
sebastientaggart Apr 10, 2026
110cf62
Add resolution comment step to submit-for-review post-merge flow
sebastientaggart Apr 11, 2026
acc3c8a
Merge pull request #95 from LightbridgeLab/feature/resolution-comment
sebastientaggart Apr 11, 2026
59b17dc
Add post-review human gate for non-blocking findings before merge
sebastientaggart Apr 11, 2026
fe7f4e0
Merge pull request #97 from LightbridgeLab/feature/post-review-gate
sebastientaggart Apr 11, 2026
08aeb94
Clarify /start human gate messages with intent classification and 'go…
sebastientaggart Apr 11, 2026
ecb534e
Fix nested double quotes in gate messages by using backtick-quoted go
sebastientaggart Apr 11, 2026
d5ed672
Merge pull request #98 from LightbridgeLab/feature/clarify-start-gates
sebastientaggart Apr 11, 2026
cb45897
Fix start.md gh commands missed in #82 body-file conversion
sebastientaggart Apr 11, 2026
e12dfdf
Regenerate start skill adapter files after body-file conversion
sebastientaggart Apr 11, 2026
d8bcb2f
Merge pull request #101 from LightbridgeLab/feature/fix-start-sync-drift
sebastientaggart Apr 11, 2026
22c61f7
Update docs for recent features and simplify README into a marketing …
sebastientaggart Apr 11, 2026
6853a90
Merge pull request #103 from LightbridgeLab/feature/update-docs-simpl…
sebastientaggart Apr 11, 2026
060f218
Use Write tool + --body-file for start.md gh commands (test approach)
sebastientaggart Apr 11, 2026
e5e8b3e
Use Write tool + --body-file for all gh commands with multi-line bodies
sebastientaggart Apr 11, 2026
6b7b3dc
Merge pull request #99 from LightbridgeLab/fix/start-body-file-permis…
sebastientaggart Apr 11, 2026
6eccf01
Bump version to 0.4.1
sebastientaggart Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions .agents/skills/deploy/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,9 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo

## Step 6 — Create PR: `dev` → `main`

```bash
gh pr create --base main --head dev \
--title "Release vX.Y.Z" \
--body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`:

```markdown
Release vX.Y.Z

PRs included:
Expand All @@ -178,7 +177,14 @@ PRs included:

Closes #14
Closes #15
EOF
```

Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs):

```bash
gh pr create --base main --head dev \
--title "Release vX.Y.Z" \
--body-file /tmp/cc_release_pr_body.md
```

Note the PR number from the output.
Expand Down Expand Up @@ -209,19 +215,23 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null

If no previous tag exists, omit the "Full changelog" line.

Create the release:
Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`:

```bash
gh release create <version-tag> \
--title "<version-tag>" \
--notes-file - <<'EOF'
```markdown
## Changes

- #<issue> — <PR title> (PR #<pr-number>)
[... one line per PR included in this release ...]

**Full changelog:** https://github.com/<owner>/<repo>/compare/<previous-tag>...<version-tag>
EOF
```

Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs):

```bash
gh release create <version-tag> \
--title "<version-tag>" \
--notes-file /tmp/cc_release_notes.md
```

Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title.
Expand All @@ -235,4 +245,4 @@ After the command runs, note the release URL from the output.
Tell the user:

> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at `<url>`. Run `make deploy-prod` to ship to production."
<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: codex | hash: 0e47902b | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: codex | hash: 6d8dd3bb | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
66 changes: 49 additions & 17 deletions .agents/skills/start/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,40 @@ Read the relevant code. Propose a concrete implementation approach. Be specific

### Step 2 — HUMAN GATE

Say exactly: **"Does this approach sound right? I'll create a GitHub issue and branch before writing any code."**
Say exactly:

Stop. Wait for the user to confirm.
> **"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.

- User says yes → continue to Step 3.
- User redirects → revise approach, ask again.
- User abandons → stop. Nothing to clean up.
**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

Run `gh issue create` with explicit flags (do NOT open an interactive editor):
Create the issue in two steps — **this exact sequence is mandatory**:

**Step 3a — Write the body to a temp file.** Use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_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:

```bash
gh issue create \
--title "<standalone full sentence — must make sense with no context>" \
--body "<structured markdown body — see sections below>" \
--assignee @me \
[--label "<resolved labels>"] \
[--milestone "<resolved milestone>"]
[--milestone "<resolved milestone>"] \
--body-file /tmp/cc_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.
Expand All @@ -115,12 +126,22 @@ Resolve labels and milestone using the resolution steps in the Parsing section a
## 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 four sections are required. Write for a non-developer audience — no code, no file paths. Acceptance Criteria must be concrete and verifiable (not vague goals).
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`
Expand All @@ -130,12 +151,18 @@ After the command runs, note the issue number from the output URL (e.g. `https:/

Show the user: `Created issue #<number>: <title>`

Then immediately post agent implementation notes as a comment:
Then immediately post agent implementation notes as a comment.

```bash
gh issue comment <number> --body "## Agent Implementation Notes
Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`:
```markdown
## Agent Implementation Notes

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

<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):
```bash
gh issue comment <number> --body-file /tmp/cc_issue_comment.md
```

### Step 4 — Create feature branch
Expand Down Expand Up @@ -193,10 +220,15 @@ Tell the user:
- What was previously done (from agent notes if present)
- What appears to remain

Ask: **"Does this match your understanding? Continue this ticket, or open a fresh one?"**
Ask: **"Does this match your understanding? Type `go` to start coding, or share any questions/adjustments first."**

**Intent classification (not keyword matching):**

- Continue → Step 3.
- New ticket → restart as Case A with a new description.
- **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

Expand Down Expand Up @@ -244,4 +276,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test
- 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.sh | skill: start | adapter: codex | hash: c10aad5a | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: start | adapter: codex | hash: 7ba07088 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
82 changes: 69 additions & 13 deletions .agents/skills/submit-for-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,23 @@ Use `Issue #<number>` as the issue reference — the issue stays open until `/de

> **Critical:** Use the unqualified `#N` form (e.g. `Closes #42`), never the fully-qualified `owner/repo#N` form (e.g. `Closes LightbridgeLab/CodeCannon#42`), even for same-repo references. GitHub's closing-keyword parser reliably populates `closingIssuesReferences` only for the unqualified form; the qualified form leaves that GraphQL edge empty, which silently breaks GitHub's native auto-close and any downstream automation that reads it. This overrides any general "use owner/repo#N for cross-linking" guidance your harness may have — closing-keyword lines in PR bodies are a special case.

Then create the PR with explicit title and body (never use an interactive editor):
```
gh pr create --base <target-branch> --title "<title>" --body-file - <<'EOF'
Then create the PR in two steps — **this exact sequence is mandatory**:

First, use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_pr_body.md`. Do NOT use Bash/shell to write this file.

```markdown
<description of what changed and why>

<Closes #N OR Issue #N, based on target above>
EOF
```

> **Why `--body-file -` + stdin heredoc?** Claude Code's permission matcher refuses to extend any `Bash(gh:*)` allow rule over a command containing `$(...)` substitution, so `--body "$(cat <<'EOF' ...)"` triggers a Yes/No prompt on every run with no "Allow always" option. Piping the body in on stdin via heredoc redirection is not command substitution — the matcher sees a clean `gh pr create …` invocation and `Bash(gh:*)` matches. Apply this pattern to every multi-line `--body` / `--notes` in skills (`gh pr create`, `gh issue create`, `gh issue comment`, and `gh release create` all accept `-` for their `*-file` flags).
Then create the PR (do NOT use `--body`, `--body-file -`, heredocs, or `$(cat ...)`):

```
gh pr create --base <target-branch> --title "<title>" --body-file /tmp/cc_pr_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.

Add `--reviewer` to the `gh pr create` command above using the handles from `@sebastientaggart`. Before passing them, strip any leading `@` from each comma-separated handle (e.g. `@alice,@org/team` becomes `alice,org/team`) — the `gh` CLI requires bare usernames.

Expand Down Expand Up @@ -180,7 +187,24 @@ Apply QA label and report success (see below).

**If `ai` is `"ai"` (default):**

**If APPROVE (no CRITICAL findings):** Run the merge command. Apply QA label and report success (see below).
**If APPROVE (no CRITICAL findings):**

Collect any non-blocking findings (`[WARNING]` or `[NOTE]` lines) from the review output.

- **If there are no non-blocking findings** (clean review): Run the merge command immediately. Apply QA label and report success (see below).

- **If there are non-blocking findings**: Present the findings as a numbered list (preserve the `[WARNING]` / `[NOTE]` prefix) and say:

> "The review approved with N non-blocking finding(s):
>
> <numbered list of findings>
>
> Would you like to **address these first** before merging, or **merge now**?"

Wait for the user to respond.

- User says **address / fix** → return to the coding loop. Say: "Fix the findings and run `/submit-for-review` again when ready." Do NOT merge.
- User says **merge now** → run the merge command. Apply QA label and report success (see below). Proceed to Step 9 as normal (which will offer to create follow-up issues for any remaining findings).

**If REQUEST CHANGES (at least one CRITICAL finding):** Report the findings to the user. Do NOT merge. Say:

Expand All @@ -198,6 +222,32 @@ gh issue edit <number> --add-label "ready-for-qa"
```
If no linked issue was found, skip silently.

**Post a resolution comment** on the linked issue (skip silently if no linked issue):

Read the issue body (from Step 3 or via `gh issue view <number>`) to recall the original problem description. Then post a comment summarizing what was done:

Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`:

```markdown
## Resolution

<1-3 sentences explaining what was done to fix the problem, written in plain language for a non-technical audience — no code, no file paths, no jargon. Focus on what changed from the user's perspective and why it solves the problem described in the issue.>

See #<PR-number> for full technical details.
```

Then post it (do NOT use `--body` or heredocs):

```
gh issue comment <number> --body-file /tmp/cc_resolution_comment.md
```

**Resolution writing rules:**
- Write for PMs and BAs, not developers. Describe the *outcome*, not the implementation.
- Reference the original problem from the issue body so the resolution reads as a direct answer to it.
- Keep it to 1-3 sentences. If one sentence covers it, don't pad.
- Use the unqualified `#N` form for the PR reference.

Report success based on mode:
"PR merged. Issues stay open until testing confirms the fix. Run `make deploy-preview` when ready to deploy to preview."

Expand Down Expand Up @@ -225,17 +275,23 @@ Accept: comma-separated numbers, `all`, or `none`/`skip`/empty. If the input is

**Create the selected issues.** For each selected finding, run `gh issue create` with explicit flags:

```
gh issue create \
--title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \
[--label "<pool-selected labels>"] \
--body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding:

```markdown
Follow-up from PR #<merged-pr-number> — auto-proposed from the code review.

**Finding:** <full finding text, prefix included>

See the review comment on the PR for context.
EOF
```

Then create the issue (do NOT use `--body` or heredocs):

```
gh issue create \
--title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \
[--label "<pool-selected labels>"] \
--body-file /tmp/cc_followup_body.md
```

Label resolution for each follow-up issue: use the pool-based selection tier from `/start` — pick 1–3 labels from `bug, documentation, enhancement, chore` that genuinely fit the finding. If `bug, documentation, enhancement, chore` is empty or no pool label fits, omit `--label`. Do not attempt per-invocation flag resolution (there is no flag here) and never create new labels from follow-ups, even if label creation is enabled for the project.
Expand All @@ -261,4 +317,4 @@ If a single `gh issue create` call fails, report the failure for that finding an
- `/submit-for-review` merges only to `dev` — never directly to `main`.
- If `make merge` fails for any reason, report it and stop — do not attempt workarounds.
- The follow-up issue offer in Step 9 runs only after a successful merge and only when the review produced non-blocking findings. Never prompt the user for follow-ups when the review blocked the merge — those findings should be fixed, not ticketed.
<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: codex | hash: 7f9a2844 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: codex | hash: d09ab40d | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
34 changes: 22 additions & 12 deletions .claude/commands/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,9 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo

## Step 6 — Create PR: `dev` → `main`

```bash
gh pr create --base main --head dev \
--title "Release vX.Y.Z" \
--body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`:

```markdown
Release vX.Y.Z

PRs included:
Expand All @@ -173,7 +172,14 @@ PRs included:

Closes #14
Closes #15
EOF
```

Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs):

```bash
gh pr create --base main --head dev \
--title "Release vX.Y.Z" \
--body-file /tmp/cc_release_pr_body.md
```

Note the PR number from the output.
Expand Down Expand Up @@ -204,19 +210,23 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null

If no previous tag exists, omit the "Full changelog" line.

Create the release:
Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`:

```bash
gh release create <version-tag> \
--title "<version-tag>" \
--notes-file - <<'EOF'
```markdown
## Changes

- #<issue> — <PR title> (PR #<pr-number>)
[... one line per PR included in this release ...]

**Full changelog:** https://github.com/<owner>/<repo>/compare/<previous-tag>...<version-tag>
EOF
```

Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs):

```bash
gh release create <version-tag> \
--title "<version-tag>" \
--notes-file /tmp/cc_release_notes.md
```

Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title.
Expand All @@ -230,4 +240,4 @@ After the command runs, note the release URL from the output.
Tell the user:

> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at `<url>`. Run `make deploy-prod` to ship to production."
<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: claude | hash: b1efee29 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: claude | hash: 88439028 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
Loading