Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
13ce5e0
Apply schema-declared placeholder defaults generically in sync.py
sebastientaggart Aug 5, 2026
b66e73d
Fix QA-label opt-out regression and inline-comment parsing in schema …
sebastientaggart Aug 5, 2026
d70f4e6
Merge pull request #207 from LightbridgeLab/feature/194-sync-schema-d…
sebastientaggart Aug 5, 2026
b4de127
Pull back procedural over-specification in skills; add TEST_CMD and s…
sebastientaggart Aug 5, 2026
5f042ef
Merge pull request #209 from LightbridgeLab/feature/206-prune-procedu…
sebastientaggart Aug 5, 2026
d636fe0
Prune /setup and /submit-for-review; fix permission-audit cd false po…
sebastientaggart Aug 5, 2026
3174106
Merge pull request #210 from LightbridgeLab/feature/208-prune-setup-a…
sebastientaggart Aug 5, 2026
f339a83
Add START_APPROVAL_GATE and ISSUE_FULL_STRUCTURE dials to relax /star…
sebastientaggart Aug 5, 2026
c4f0357
Suppress Case B investigation-findings prompt when START_APPROVAL_GAT…
sebastientaggart Aug 5, 2026
439d44d
Merge pull request #211 from LightbridgeLab/feature/200-lite-ceremony…
sebastientaggart Aug 5, 2026
2a9b492
Add exit-code tests for github-agile scripts; fix bump-and-tag exit-c…
sebastientaggart Aug 6, 2026
5fad214
Merge pull request #212 from LightbridgeLab/feature/165-script-exit-c…
sebastientaggart Aug 6, 2026
53807d6
Bump version to 0.8.1
sebastientaggart Aug 6, 2026
a40a8f0
Fix /deploy over-reporting release contents from a stale local prod b…
sebastientaggart Aug 6, 2026
2a9d366
Merge pull request #214 from LightbridgeLab/feature/213-deploy-stale-…
sebastientaggart Aug 6, 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
196 changes: 49 additions & 147 deletions .agents/skills/deploy/SKILL.md

Large diffs are not rendered by default.

135 changes: 18 additions & 117 deletions .agents/skills/setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Ask the user:

> "What level of process does this project need?"
>
> **1. Lightweight** — Fast iteration. AI review is advisory, features merge to main, no QA workflow.
> **1. Lightweight** — Fast iteration. AI review is advisory, features merge to main, no QA workflow, and `/start` skips its approval gate and mandated issue structure.
>
> **2. Standard** — Integration branch with AI-gated review. QA and milestones available but not required.
>
Expand All @@ -171,7 +171,7 @@ Show every change before writing and ask "Apply these values to `.codecannon.yam

| Profile | Values to write | Values left commented out |
|---|---|---|
| **Lightweight** | `BRANCH_PROD`, `REVIEW_GATE: "advisory"` | `BRANCH_DEV`, `BRANCH_TEST`, `DEFAULT_REVIEWERS`, `TICKET_LABELS`, all QA labels |
| **Lightweight** | `BRANCH_PROD`, `REVIEW_GATE: "advisory"`, `START_APPROVAL_GATE: "false"`, `ISSUE_FULL_STRUCTURE: "false"` | `BRANCH_DEV`, `BRANCH_TEST`, `DEFAULT_REVIEWERS`, `TICKET_LABELS`, all QA labels |
| **Standard** | `BRANCH_PROD`, `BRANCH_DEV`, `REVIEW_GATE: "ai"` | `BRANCH_TEST`, QA labels |
| **Governed** | `BRANCH_PROD`, `BRANCH_DEV`, `REVIEW_GATE: "ai"`, `QA_READY_LABEL: "ready-for-qa"`, `QA_PASSED_LABEL: "qa-passed"`, `QA_FAILED_LABEL: "qa-failed"`, and `BRANCH_TEST` if applicable | — |
| **Custom** | Nothing — tell the user to review the file manually | — |
Expand Down Expand Up @@ -237,60 +237,21 @@ git show-ref --quiet --verify refs/remotes/origin/<BRANCH_DEV value>
git show-ref --quiet --verify refs/remotes/origin/<BRANCH_TEST value>
```

Display:

```
Setup looks healthy. Profile: <inferred profile>

BRANCH_PROD: <value>
BRANCH_DEV: <value> (exists in remote: yes/no/not set)
BRANCH_TEST: <value> (exists in remote: yes/no/not set)
REVIEW_GATE: <value>
CHECK_CMD: <value>
MERGE_CMD: <value>
Adapters: <list from config>

Optional config:
DEFAULT_MILESTONE — set / unset
DEFAULT_REVIEWERS — set / unset
TICKET_LABELS — set (N labels) / unset
TICKET_LABEL_CREATION_ALLOWED — set / unset
QA_READY_LABEL — set / unset
PLATFORM_COMPLIANCE_NOTES — set / unset
CONVENTIONS_NOTES — set / unset
SENSITIVE_AREAS_GATE — "true" (default) / "false"
SENSITIVE_AREAS_CATEGORIES — set (custom list) / unset (default 5-category list)
```
Confirm the setup is healthy and show a scannable summary — lay it out however reads clearly. Include the inferred profile, the core workflow values (`BRANCH_PROD`; `BRANCH_DEV` and `BRANCH_TEST`, each with whether it exists in the remote; `REVIEW_GATE`; `START_APPROVAL_GATE` (`"true"` default / `"false"`); `ISSUE_FULL_STRUCTURE` (`"true"` default / `"false"`); `CHECK_CMD`; `MERGE_CMD`; and the configured adapters), and then each optional config value reported as set or unset: `DEFAULT_MILESTONE`, `DEFAULT_REVIEWERS`, `TICKET_LABELS` (with label count when set), `TICKET_LABEL_CREATION_ALLOWED`, the QA labels, `PLATFORM_COMPLIANCE_NOTES`, `CONVENTIONS_NOTES`, `SENSITIVE_AREAS_GATE` (`"true"` default / `"false"`), and `SENSITIVE_AREAS_CATEGORIES` (custom list / default 5-category list).

A value counts as "set" if it is present, uncommented, and non-empty in `.codecannon.yaml`.

---

### Phase 2 — Permission audit

Check whether the agent's permission configuration covers the shell commands Code Cannon skills use. Read `CodeCannon/permissions.yaml` to get the list of required command prefixes.
Check whether the agent's permission configuration covers the shell commands Code Cannon skills use. Read the `commands:` list in `CodeCannon/permissions.yaml` for the required command prefixes. Use **only** the `commands:` key — commands under `validate_only:` (e.g. `cd`) are deliberately never emitted as allow rules, so they must not be reported as missing.

**Claude Code:** Read `.claude/settings.local.json` (if it exists) and `.claude/settings.json` (if it exists). Collect all `Bash(...)` entries from the `permissions.allow` arrays in both files. For each command prefix in `permissions.yaml`, check whether an allow rule covers it (e.g. `Bash(git:*)` or `Bash(git *)` covers the `git` prefix).
**Claude Code:** Read `.claude/settings.local.json` (if it exists) and `.claude/settings.json` (if it exists). Collect all `Bash(...)` entries from the `permissions.allow` arrays in both files. For each prefix in `commands:`, check whether an allow rule covers it (e.g. `Bash(git:*)` or `Bash(git *)` covers `git`).

If all prefixes are covered, display `Agent permissions: all skill commands pre-approved` and continue to Phase 3.

If any prefixes are missing, show:

```
Agent permissions: some skill commands may prompt for approval.

Missing allow rules:
- Bash(cd:*)
- Bash(make:*)
...

To pre-approve these, add them to .claude/settings.local.json (git-ignored)
or .claude/settings.json (shared with team). See docs/index.md for a full example.

This is optional — you can approve commands individually when prompted instead.
```

Do not modify any settings file. This is advisory only.
If any are missing, report them as `Bash(<cmd>:*)` allow rules the user can optionally add to `.claude/settings.local.json` (git-ignored) or `.claude/settings.json` (shared with team) — pointing at `docs/index.md` for a full example — and note that commands can also be approved individually when prompted. Do not modify any settings file. This is advisory only.

**Other agents (Cursor, Codex, Gemini):** Skip this phase silently — Cursor doesn't prompt, and Codex/Gemini permission systems vary. The docs cover these agents separately.

Expand Down Expand Up @@ -319,22 +280,7 @@ Wait for response.
git config --get user.signingkey
```

**If a signing key is found**, show the proposed change and confirm:

```
I'll enable commit and tag signing for this repo:

git config commit.gpgsign true
git config tag.gpgsign true

Signing key: <truncated-key>

Proceed? (yes/no)
```

Wait for confirmation. Write only on yes. If no, skip to Phase 4.

Continue to Phase 4.
**If a signing key is found**, show the proposed change — enabling `commit.gpgsign` and `tag.gpgsign` for this repo, and naming the signing key — then ask "Proceed? (yes/no)". Wait for confirmation. Write only on yes. If no, skip to Phase 4. Otherwise continue to Phase 4.

**If no signing key is found**, detect the signing format:

Expand All @@ -345,19 +291,7 @@ git config --get gpg.format
- If `ssh` → suggest: `git config user.signingkey ~/.ssh/id_ed25519.pub` (adjust path to the user's key). Ask the user for their SSH public key path.
- If `gpg` or unset → suggest: run `gpg --list-secret-keys --keyid-format=long` to find a key ID. Ask the user for their GPG key ID.

Once the user provides a key value, show the proposed changes and confirm:

```
I'll configure signing for this repo:

git config user.signingkey <provided-key>
git config commit.gpgsign true
git config tag.gpgsign true

Proceed? (yes/no)
```

Wait for confirmation. Write only on yes. If no, skip to Phase 4.
Once the user provides a key value, show the proposed changes — setting `user.signingkey` to the provided key and enabling `commit.gpgsign` and `tag.gpgsign` — then ask "Proceed? (yes/no)". Wait for confirmation. Write only on yes. If no, skip to Phase 4.

If the user has no signing key and doesn't know how to create one, point them to GitHub's signing key documentation and stop: "Set up a signing key first, then run `/setup` again to enable commit signing."

Expand All @@ -371,26 +305,13 @@ Run:
gh label list --limit 100 --json name,color,description
```

If zero labels are found, treat this as a greenfield repository and offer a starter label baseline before asking about `TICKET_LABELS`.

Show this recommendation:

```
No labels were found. For new projects, a practical baseline is:
- bug
- enhancement
- chore
- documentation
- ready-for-qa
- qa-passed
- qa-failed
```

Ask: **"Create any missing labels from this baseline now? (yes/no)"**

Wait for response.
If zero labels are found, treat this as a greenfield repository. Present the starter baseline — `bug`, `enhancement`, `chore`, `documentation`, `ready-for-qa`, `qa-passed`, `qa-failed` — and ask: **"Create any missing labels from this baseline now? (yes/no)"**

- **yes** → run `python3 CodeCannon/skills/github-agile/scripts/label-create.py bug enhancement chore documentation ready-for-qa qa-passed qa-failed`. The script applies sensible color/description defaults from a baked-in table and warns-and-continues on any name that already exists.
- **yes** → run the label-create script with exactly those seven names:
```bash
python3 CodeCannon/skills/github-agile/scripts/label-create.py bug enhancement chore documentation ready-for-qa qa-passed qa-failed
```
The script applies sensible color/description defaults from a baked-in table and warns-and-continues on any name that already exists.
- **no / skip / anything else** → continue without creating labels.

#### Configured-label audit
Expand All @@ -408,39 +329,19 @@ The script reads `.codecannon.yaml`, collects the names referenced by `TICKET_LA
- **yes** → run `python3 CodeCannon/skills/github-agile/scripts/label-create.py <name1> <name2> ...` with the missing names from the audit output.
- **no / skip** → continue, but at the end of Phase 4 print a one-line summary: "Skipped creating: \<list\>. `/submit-for-review` will warn and continue if it needs to apply a missing label; `/qa` and `/start` may degrade similarly."

After this step (or if labels were non-zero initially), run `gh label list --limit 100 --json name,color,description` again.
After this step (or if labels were non-zero initially), re-run the same `gh label list` fetch to pick up any labels just created.

If `TICKET_LABELS` is unset or fewer than 5 labels exist, add a note: "`/start` works best with a clear issue-label pool (`TICKET_LABELS`), and `/qa` needs explicit QA lifecycle labels (`ready-for-qa`, `qa-passed`, `qa-failed`). Consider a lightweight priority scheme (e.g. `priority:high`, `priority:medium`, `priority:low`) if the team needs triage support. If the team runs planned iterations, set `DEFAULT_MILESTONE` in Phase 5; otherwise leave it unset so `/start` auto-detects."

Display the results as a numbered list:

```
Available labels (N found):
1. bug — Something isn't working
2. enhancement — New feature or request
3. good first issue — Good for newcomers
...
```

Ask: **"Write these label names to `.codecannon.yaml` as TICKET_LABELS? (yes / no / list specific numbers)"**
Display the available labels as a numbered list (name — description, with the count found) so the user can pick by number, then ask: **"Write these label names to `.codecannon.yaml` as TICKET_LABELS? (yes / no / list specific numbers)"**

Wait for the user's response.

- **yes** → use all labels
- **numbers** (e.g. `1,3,5`) → use only those labels
- **no / skip / anything else** → skip this phase, continue to Phase 5

Show the exact change before writing:

```
I'll update .codecannon.yaml with:

TICKET_LABELS: "bug,enhancement,..."

Proceed? (yes/no)
```

Wait for confirmation. Write only on yes.
Show the exact change before writing — the `TICKET_LABELS` line as it will appear in `.codecannon.yaml` — and ask "Proceed? (yes/no)". Wait for confirmation. Write only on yes.

---

Expand Down Expand Up @@ -491,4 +392,4 @@ Add a note: `/start` can be used to create well-formed GitHub issues without wri
- Never fetch more than 100 labels in a single command. `gh label list --limit 100` is the ceiling.
- Do not skip any human gate in Phase 3, Phase 4, or Phase 5 — each write requires confirmation.
- If the user skips a config value, do not ask again. Move on.
<!-- generated by CodeCannon/sync.py | skill: setup | adapter: codex | hash: 7a86a83a | DO NOT EDIT — run CodeCannon/sync.py to regenerate -->
<!-- generated by CodeCannon/sync.py | skill: setup | adapter: codex | hash: 76399bb0 | DO NOT EDIT — run CodeCannon/sync.py to regenerate -->
40 changes: 22 additions & 18 deletions .agents/skills/start/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ Otherwise → go to **Case A: New work**.

> **Execution order:** Resolve labels and milestones **now**, before entering Case A Step 1. If milestone auto-detection requires a user prompt (2+ open milestones), that prompt happens here — not later during issue creation. By the time you reach Step 2's human gate, all metadata must already be resolved so that Step 3 can proceed without re-prompting.

The argument string may contain optional inline flags after the description. Parse as follows:
The description may be followed by optional flags — `--label`/`-l` and `--milestone`/`-m`, in any order. Separate the description from the flags yourself; the flags carry these meanings:

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 <value>` / `-l <value>`** — a comma-separated label string used **verbatim**, bypassing label auto-selection entirely for this invocation. Quote values containing spaces (e.g. `--label "good first issue"`).
- **`--milestone <value>` / `-m <value>`** — a milestone name or number (GitHub accepts both names and numbers).

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

Expand All @@ -57,14 +55,6 @@ After parsing flags, determine the active milestone in this order:
- **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` | Description | Labels | Milestone |
|---|---|---|---|
| `Add dark mode toggle to settings page` | `Add dark mode toggle to settings page` | auto-selected from pool | auto-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.

---
Expand Down Expand Up @@ -102,9 +92,9 @@ If on any other branch → proceed to Case A or Case B as determined by the `$AR

### Step 1 — Investigate

Read the relevant code. Propose a concrete implementation approach. Be specific about which files change and how.
Read the relevant code using your harness's native file-reading and search tools (read, grep/glob, and the like) rather than shell pipelines — hand-rolled `find … | xargs`, `grep ; awk`, or redirection shapes trigger permission prompts that cannot be permanently allowed. Then propose a concrete implementation approach, specific about which files change and how.

### Step 2 — HUMAN GATE
### Step 2 — Approach checkpoint

Say exactly:

Expand Down Expand Up @@ -222,7 +212,14 @@ Show the user: `On branch feature/<name>`

### Step 5 — Write the code

Now write the code. Do NOT commit anything.
Write the code using your harness's native editing tools. Do NOT commit anything.
To exercise your work as you go, run the project's configured test command rather than hand-rolling a test invocation — a hand-built `python3 -m unittest … > /tmp/…` or similar redirection shape triggers permission prompts that a configured command avoids:

```bash
make test
```

If it fails because the target does not exist, tell the user rather than improvising a replacement.

When done, say: **"When you've verified locally, reply `yes` to submit, or say what to change."**

Expand Down Expand Up @@ -317,7 +314,14 @@ git branch --show-current

### Step 5 — Write the code

Continue from where work left off. Do NOT commit.
Continue from where work left off, using your harness's native editing tools. Do NOT commit.
To exercise your work as you go, run the project's configured test command rather than hand-rolling a test invocation — a hand-built `python3 -m unittest … > /tmp/…` or similar redirection shape triggers permission prompts that a configured command avoids:

```bash
make test
```

If it fails because the target does not exist, tell the user rather than improvising a replacement.

When done, say: **"When you've verified locally, reply `yes` to submit, or say what to change."**

Expand All @@ -336,4 +340,4 @@ When done, say: **"When you've verified locally, reply `yes` to submit, or say w
- 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: codex | hash: e41e83ae | DO NOT EDIT — run CodeCannon/sync.py to regenerate -->
<!-- generated by CodeCannon/sync.py | skill: start | adapter: codex | hash: d6959f1c | DO NOT EDIT — run CodeCannon/sync.py to regenerate -->
Loading
Loading