Skip to content

Commit ea2a995

Browse files
authored
Merge pull request #1111 from opsmill/develop
Merge develop into infrahub-develop
2 parents 909732a + 0997944 commit ea2a995

54 files changed

Lines changed: 6151 additions & 395 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
description: Refresh the managed Spec Kit section in coding agent context file(s)
3+
---
4+
5+
6+
<!-- Extension: agent-context -->
7+
<!-- Config: .specify/extensions/agent-context/ -->
8+
# Update Coding Agent Context
9+
10+
Refresh the managed Spec Kit section inside the active coding agent's context/instruction file (e.g. `CLAUDE.md`, `.github/copilot-instructions.md`, `AGENTS.md`).
11+
12+
## Behavior
13+
14+
The script reads the agent-context extension config at
15+
`.specify/extensions/agent-context/agent-context-config.yml` to discover:
16+
17+
- `context_file` — the path of the coding agent context file to manage.
18+
- `context_files` — optional project-relative paths for multiple coding agent context files. When non-empty, the script updates each listed file and the list takes precedence over `context_file`.
19+
- `context_markers.start` / `.end` — the delimiters surrounding the managed section. Defaults to `<!-- SPECKIT START -->` and `<!-- SPECKIT END -->` when the field is missing.
20+
21+
It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (`specs/<feature>/plan.md`).
22+
23+
If `context_files` and `context_file` are empty, the command reports nothing to do and exits successfully. Context file paths must stay project-relative; absolute paths, Windows drive paths, backslash separators, and `..` path segments are rejected.
24+
25+
## Execution
26+
27+
- **Bash**: `.specify/extensions/agent-context/scripts/bash/update-agent-context.sh [plan_path]`
28+
- **PowerShell**: `.specify/extensions/agent-context/scripts/powershell/update-agent-context.ps1 [plan_path]`
29+
30+
When `plan_path` is omitted, the script auto-detects the most recently modified `specs/*/plan.md`.

.agents/skills/commit/SKILL.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
name: commit
3+
description: >-
4+
Stages and commits the current changes onto a safe working branch, enforcing branch discipline
5+
and optionally pushing upstream. TRIGGER when: the user wants to commit, save, or check in the
6+
current changes. DO NOT TRIGGER when: opening a pull request → pr.
7+
argument-hint: Optional `push` to push the branch upstream after committing.
8+
compatibility: Requires a Git working tree.
9+
metadata:
10+
version: 0.1.0
11+
author: OpsMill
12+
---
13+
14+
# Commit Changes
15+
16+
## Introduction
17+
18+
Stage and commit the current changes onto a safe working branch. This skill enforces branch discipline: when the current branch is unsafe to commit to (the canonical rules live in **step 2** below), it proposes a new `fix/`, `feat/`, `docs/`, etc. branch and switches to it after approval. It works equally well for brand-new work and for additional commits on an existing feature branch. If the user passes `push`, the branch is pushed upstream after the commit.
19+
20+
## Arguments
21+
22+
<arguments> $ARGUMENTS </arguments>
23+
24+
**Supported arguments:**
25+
26+
- `push` — After committing, push the branch upstream (`git push -u origin <branch>` on first push, otherwise `git push`).
27+
28+
## Main Tasks
29+
30+
### 1. Assess Current State
31+
32+
1. Run `git status` to see staged, unstaged, and untracked files.
33+
2. Run `git branch --show-current` to identify the current branch.
34+
3. Run `git diff --stat` and `git diff --cached --stat` to summarise the change footprint.
35+
4. If there are no changes to commit (working tree clean, nothing staged) — STOP and tell the user there's nothing to commit. Do not create an empty commit.
36+
5. If a merge, rebase, or cherry-pick is in progress (`git status` reports it, or `.git/MERGE_HEAD` / `.git/rebase-*` / `.git/CHERRY_PICK_HEAD` exist) — STOP and surface it to the user rather than committing into the middle of that operation.
37+
38+
### 2. Branch Safety — Never Commit to a Protected or Placeholder Branch
39+
40+
A branch is **unsafe to commit to** if any of the following hold:
41+
42+
- It is the repository's default branch (resolve with `git symbolic-ref refs/remotes/origin/HEAD --short 2>/dev/null | sed 's@^origin/@@'`, falling back to `git remote show origin | sed -n 's/ *HEAD branch: //p'`).
43+
- It is a long-standing integration branch by name: `main`, `master`, `stable`, `develop`, `dev`, `trunk`.
44+
- It is a release branch: matches `release/*`, `release-*`, or is otherwise clearly named `release-something` (e.g. `release-2026.05`, `releases/v3`).
45+
- It is a placeholder / scratch branch generated by the harness or a worktree — specifically the auto-generated **`adjective-animal`** pattern (e.g. `wary-cuckoo`, `lumbar-gorilla`, `wacky-otter`, `silent-fox`), where the second word is an animal. These exist only to host a session and should not be committed to directly. Be careful **not** to over-match: legitimate two-word branches like `dark-mode`, `rate-limit`, `cache-layer`, or `user-auth` are real feature branches, not scratch branches. When a name is ambiguous (two hyphenated words but not clearly `adjective-animal`), do not assert it is unsafe — instead ask the user "this looks like it might be a generated scratch branch — is it, or is it a real branch you want to commit to?" and proceed on their answer.
46+
47+
If the current branch is unsafe by any of those rules:
48+
49+
1. Do NOT commit on the current branch.
50+
2. Analyse the changes (diffs from step 1) to understand whether the work is a bug fix or new/extended behaviour.
51+
3. Propose a branch name using the conventional prefix that matches the change:
52+
- **Bug fix**`fix/<short-description>` (e.g. `fix/graphql-codegen-missing-types`).
53+
- **New feature or enhancement**`feat/<short-description>` (e.g. `feat/add-commit-skill`).
54+
- **Docs-only, chore, refactor, etc.** → mirror the conventional-commit type: `docs/<…>`, `chore/<…>`, `refactor/<…>`.
55+
- Use a concise kebab-case slug. If the repo has a visible naming convention in `git branch -a` or in `AGENTS.md` / `CONTRIBUTING.md`, follow that instead.
56+
4. Present the proposed branch name to the user and wait for explicit approval (the user may suggest a different name).
57+
5. After approval, create and switch to the branch: `git checkout -b <branch-name>`. The uncommitted changes carry across automatically.
58+
59+
If the current branch is already a real feature branch (i.e. not in any of the unsafe categories above), continue on it. Do not create a new branch unless the user explicitly asks for one.
60+
61+
### 3. Stage Changes
62+
63+
1. Review what will be staged. Prefer adding files explicitly by path rather than `git add -A` or `git add .`, especially when untracked files are present — this avoids accidentally committing secrets (`.env`, credentials, key files) or large/generated artefacts.
64+
2. If staged changes already exist (the user pre-staged), respect that staging and only add additional files when it's clearly intended.
65+
3. Warn the user and require explicit confirmation before staging any file that looks sensitive (`.env*`, `*secret*`, `*credential*`, `*.key`, `*.pem`) or generated/large (`node_modules/`, build artefacts, `dist/`, `__pycache__/`, lockfiles changed unexpectedly).
66+
67+
### 4. Draft the Commit Message
68+
69+
Follow the repo's conventional-commit style (visible in `git log`):
70+
71+
- Use a type prefix: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:`, `ci:`, etc.
72+
- Optional scope in parentheses: `feat(backend): ...`, `fix(e2e): ...`.
73+
- Subject line under ~72 characters, imperative mood, no trailing period.
74+
- Focus on the *why* — what changed in terms of behaviour or capability, not a file list.
75+
- For multi-area changes, add a short body explaining the motivation.
76+
- Respect any repo or harness commit-trailer convention (e.g. a `Co-Authored-By` trailer the harness expects to append). Don't strip trailers that are already part of the project's workflow.
77+
- **Never write a session-link trailer into the commit — strip it if the harness added one.** Some harnesses append a line pointing at the private agent session, e.g. `Claude-Session: https://claude.ai/code/session_…` (or any trailer carrying a URL to an agent, chat, or coding session). These leak an internal, usually unshareable URL into the project's permanent — often public — git history, and they reference session state no future reader can open, so they're pure noise at best and a disclosure at worst. This is the one exception to "don't strip trailers" above: if the harness has inserted such a line, remove it before committing, and never author one yourself. Legitimate project trailers (`Co-Authored-By`, `Signed-off-by`, `Reviewed-by`, etc.) still stay.
78+
79+
Inspect the most recent ~20 commits with `git log --oneline -20` and mirror the style you see (scope conventions, capitalisation, whether bodies are used). Generic examples:
80+
81+
- `fix: correct off-by-one in pagination cursor`
82+
- `docs: archive completed specs and extract durable knowledge`
83+
- `feat: add commit skill for safe branch discipline`
84+
85+
Present the proposed commit message to the user before committing. Adjust based on feedback.
86+
87+
### 5. Create the Commit
88+
89+
1. Run `git commit -m "<message>"`. For multi-line messages, use a HEREDOC:
90+
91+
```bash
92+
git commit -m "$(cat <<'EOF'
93+
<subject>
94+
95+
<body>
96+
EOF
97+
)"
98+
```
99+
100+
2. Do NOT pass `--no-verify` — let pre-commit hooks run. If a hook fails:
101+
- Read the hook output carefully.
102+
- Fix the underlying issue (formatting, lint, etc.) rather than bypassing.
103+
- Re-stage the fixed files and create a NEW commit so each fix stays traceable. (Don't reach for `--amend` to absorb hook fixes — only amend a commit you deliberately intend to rewrite.)
104+
3. Run `git status` after the commit to confirm a clean tree and verify success.
105+
4. Run `git log -1 --stat` so the user can see what landed.
106+
107+
### 6. Push Upstream (only when `push` argument is provided)
108+
109+
**Skip this phase entirely if `push` was NOT passed.**
110+
111+
When `push` IS provided:
112+
113+
1. Re-verify the branch is not unsafe per the rules in step 2 (defence in depth, though step 2 should have prevented this).
114+
2. Check whether the branch already tracks a remote:
115+
- `git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null`
116+
3. If no upstream exists: `git push -u origin <branch-name>`.
117+
4. If an upstream exists: `git push`.
118+
5. **Never use `--force` or `--force-with-lease`** unless the user explicitly asks for it. Regular `git push` will fail if the remote has diverged — surface that error to the user instead of overwriting.
119+
6. Report the push result and, if a remote URL is configured (`git config --get remote.origin.url`), the branch URL the user can open.
120+
121+
## Quality gates
122+
123+
Per `../quality-gates/gates/gate-model.md`. `commit` is **Tier 1** (mutates a branch, does not ship).
124+
125+
| Gate | Trigger | Tier | Primitives | Pass criteria | On-fail |
126+
|---|---|---|---|---|---|
127+
| Branch-safety | before commit | T1 | P1 | Paste `git rev-parse --abbrev-ref HEAD` proving HEAD is not a protected/release/scratch branch. | STOP; create a feature branch first |
128+
129+
## Notes
130+
131+
**Branch Safety:**
132+
133+
- The canonical list of unsafe branches lives in **step 2** — that is the single source of truth; don't re-derive it from memory.
134+
- If asked to override the rule, refuse and explain — the user can switch branches themselves first if they truly intend to commit there (in which case this skill no longer applies).
135+
136+
**This is a discipline skill — hold the line under pressure.** Refusing to commit to a protected branch is the whole point, and the excuses below will appear. None of them change where the commit should land:
137+
138+
| Excuse / pressure | Reality |
139+
|-------------------|---------|
140+
| "It's urgent / it's an emergency, just commit to main." | Urgency doesn't change where the commit lands. A `feat/`/`fix/` branch takes seconds and is just as fast to merge. |
141+
| "Just this once, skip the branch." | There is no "just once" — the rule exists precisely for the tempting one-off. Propose a branch. |
142+
| "It's a tiny change, the branch is overkill." | Size is irrelevant to branch safety; a one-line fix on `main` is still a direct commit to a protected branch. |
143+
| "The hook is failing, just use `--no-verify`." | Fix the violation instead. Bypassing the hook defeats its purpose. |
144+
| "The remote diverged, just `--force`." | Never force-push unless the user explicitly asks. Surface the divergence instead. |
145+
146+
Red-flags self-check — if you catch yourself thinking any of these, STOP and re-read step 2:
147+
148+
- "This branch is *probably* fine to commit to."
149+
- "I'll commit here and sort the branch out later."
150+
- "The user clearly wants this on `main`, so the rule doesn't apply."
151+
152+
**Secret Hygiene:**
153+
154+
- Prefer explicit `git add <path>` over wholesale `git add -A`.
155+
- Warn before staging anything that looks like a secret or credential.
156+
- A session-link trailer (`Claude-Session:` / any agent-session URL) is a disclosure too — strip it from the commit message before committing, per step 4.
157+
158+
**Hook Discipline:**
159+
160+
- Pre-commit hooks exist for good reasons. Fix violations rather than bypassing with `--no-verify`.
161+
162+
**Idempotency:**
163+
164+
- Safe to invoke repeatedly. With no changes to commit, the skill exits cleanly without creating an empty commit.
165+
166+
## Expected Outcome
167+
168+
- All staged/unstaged changes that the user wanted to capture are committed on a safe working branch.
169+
- The branch is named meaningfully (existing real feature branch preserved, or a new `fix/<…>` / `feat/<…>` / `docs/<…>` / etc. name approved by the user).
170+
- The commit message follows the repo's existing conventional-commit style.
171+
- If `push` was provided, the branch is pushed upstream.
172+
- Every branch deemed unsafe in step 2 is left untouched in all cases.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
name: creating-issues
3+
description: >-
4+
Turns a single feature idea, improvement, or bug into ONE well-structured GitHub issue. TRIGGER
5+
when: the user wants to file/open/create an issue, turn a feature idea or improvement into a
6+
ticket, or capture something missing or broken as a ticket. DO NOT TRIGGER when: breaking work
7+
into multiple issues or planning a body of work → a planning skill; writing a full Product
8+
Requirements Document → creating-prd; the idea is still fuzzy and unhardened → grilling-ideas
9+
first.
10+
argument-hint: Feature, improvement, or bug to turn into a GitHub issue
11+
compatibility: Requires GitHub access (gh CLI authenticated, or an equivalent GitHub MCP/API tool) and write access to the target repository.
12+
metadata:
13+
version: 0.1.0
14+
author: OpsMill
15+
---
16+
17+
# Create GitHub Issue
18+
19+
## User Input
20+
21+
```text
22+
$ARGUMENTS
23+
```
24+
25+
Treat `$ARGUMENTS` as the thing to file. If empty, ask the user what they want to capture before starting.
26+
27+
## What this does
28+
29+
Turn a feature idea, improvement, or bug into a single well-structured GitHub issue that matches the repository's own conventions. Keep it small and centred on **the need** — what is missing or broken, who it affects, and why it matters. **Do not propose a solution and do not write acceptance criteria for features** — leave the "how" to whoever picks the issue up. Always show the draft and get explicit approval before creating anything.
30+
31+
## Core principle
32+
33+
An issue states the need, not the answer. The person (or agent) who implements it decides the approach. For a feature or improvement that means no design, no task breakdown, no acceptance criteria — just a clear problem and its context. For a bug, the "need" is the misbehaviour itself, so reproduction details belong in the issue.
34+
35+
## Workflow
36+
37+
### 1. Learn the repository's conventions
38+
39+
Probe whatever context the repo actually provides — don't assume a fixed layout:
40+
41+
- [ ] Read context docs if present: `AGENTS.md`, `CLAUDE.md`, `CONTEXT.md`, `README`, or a `dev/` directory.
42+
- [ ] Check for issue templates in `.github/ISSUE_TEMPLATE/` and honour them if they exist.
43+
- [ ] List the repo's labels (`gh label list`) and a few recent issues (`gh issue list`) to match title style, labels, and tone.
44+
45+
If the repo provides an issue template, honour its structure as-is — the fields are there deliberately. The only thing to hold back is *prescribing a solution*: fill the template's sections with the need and context, not with a design.
46+
47+
### 2. Classify
48+
49+
Decide whether this is a **feature / improvement** or a **bug**. When unsure, ask the user.
50+
51+
### 3. Draft (need-focused)
52+
53+
**Feature / improvement** — keep it lean:
54+
55+
```markdown
56+
## Need
57+
58+
[What's missing or could be better, who it affects, and why it matters now.]
59+
60+
## Context
61+
62+
[Only what's needed to understand the need: relevant area of the product, links to related discussion, constraints. No design.]
63+
64+
## References
65+
66+
- Related issue: #[number]
67+
- Documentation / discussion: [url]
68+
```
69+
70+
**Bug** — capture the misbehaviour:
71+
72+
```markdown
73+
## What happens
74+
75+
[Observed behaviour.]
76+
77+
## What should happen
78+
79+
[Expected behaviour.]
80+
81+
## Steps to reproduce
82+
83+
1. ...
84+
2. ...
85+
86+
## Environment
87+
88+
[Version, OS, configuration, or other relevant context.]
89+
90+
## References
91+
92+
- Related issue: #[number]
93+
- Logs / screenshots: [link or `<details>` block]
94+
```
95+
96+
Draft a clear, searchable title using the repo's convention (e.g. `feat:`, `fix:`, or whatever recent issues use), and pick labels from the repo's existing set.
97+
98+
### 4. Get approval, then create
99+
100+
**By default, present the full draft (title, labels, body) to the user and wait for explicit approval before creating the issue** — even when you have permission to create it directly. The gate exists to stop *silent* creation from mere permission; it is not meant to override a direct instruction.
101+
102+
If the user has explicitly told you to file it without review (e.g. "just file it, don't ask"), honour that — but still echo the final title, labels, and body in your reply before (or as) you create it, so there's a record of what went out.
103+
104+
Create the issue with the available tooling, for example:
105+
106+
```bash
107+
gh issue create --title "[TITLE]" --body "[BODY]" --label "[LABELS]"
108+
```
109+
110+
`--label` takes a comma-separated list (`--label 'bug,enhancement'`) — a space-separated value is treated as a single label name.
111+
112+
Or the equivalent GitHub MCP call. Return the issue URL.
113+
114+
## Quality gates
115+
116+
Per `../quality-gates/gates/gate-model.md`. `creating-issues` is **Tier 0**; the existing
117+
user-approval step IS the independent judgment (R4) — no subagent is added.
118+
119+
| Gate | Trigger | Tier | Primitives | Pass criteria | On-fail |
120+
|---|---|---|---|---|---|
121+
| Draft-shown | before `gh issue create` | T0 | P1 + human approval | The full draft is shown and the user approves. | revise per feedback |
122+
123+
## Guardrails
124+
125+
- Prefer clarity over completeness — a short, sharp issue beats a padded one.
126+
- Resist scope creep: one need per issue. If the input contains several, surface that and ask whether to split.
127+
- Don't invent labels, milestones, or assignees that don't exist in the repo.
128+
- Don't smuggle a solution into the "Need" or "Context" — if you catch yourself describing *how*, cut it.

0 commit comments

Comments
 (0)