refactor(skills): retrofit the corpus to the ADR-0020 context contract #129

Merged
Defame1297 merged 89 commits from refactor/adr0020-skill-retrofit into main 2026-09-01 13:47:47 +00:00
20 changed files with 66 additions and 60 deletions
Showing only changes of commit 14af50bc07 - Show all commits

View File

@@ -8,7 +8,6 @@ description: >
Not branch lifecycle -> `git-branches`.
metadata:
version: "0.1.3"
category: git
source_keys:
- conventional-commits-spec

View File

@@ -9,21 +9,20 @@ description: >
Not submodule pointers -> `git-submodules`.
metadata:
category: git-workflow
category: git
source_keys:
- git-scm-remote-docs
- git-scm-fetch-docs
- git-scm-push-docs
- git-scm-pull-docs
- context7-git-htmldocs
---
## Gotchas
- **`--force-with-lease` alone is not safe** — background processes (IDE plugins, cron jobs) running `git fetch` silently defeat the protection. Combine it with `--force-if-includes`, or pin the explicit `--force-with-lease=<ref>:<sha>` form.
- **Prune does not touch tags by default** — `git fetch --prune` leaves orphaned tags behind. Use `--prune --prune-tags`, or set `fetch.pruneTags true`.
- **Pull defaults shift between Git versions** — older ones default to merge, newer to `--ff-only`. Set `pull.ff only` explicitly rather than trusting the installed default.
- **Set `pull.ff only` explicitly** — do not trust the installed default.
## Step 1 — Clear the force-push gate

View File

@@ -23,6 +23,10 @@ A pull that diverges with no strategy configured fails, and that failure is the
## Config precedence
The installed default varies by Git version — older versions merge on divergence, newer ones
default to `--ff-only` — so an unset `pull.ff` means the same pull behaves differently on different
machines. Set it explicitly.
Highest wins:
1. Command-line flag (`--ff-only` / `--rebase` / `--no-rebase`)

View File

@@ -51,7 +51,7 @@ executing.
## Output format
```
```yaml
operation: <clone|add|init|update|status|sync|set-url|set-branch|absorbgitdirs|deinit|remove>
status: <success|error|partial>
message: <one line; include git's own output on error>

View File

@@ -1,7 +1,6 @@
---
metadata:
source_keys:
- git-scm-submodule-docs
source_keys:
- git-scm-submodule-docs
---
# References

View File

@@ -2,9 +2,9 @@
name: git-workflow
description: >
Use when a human wants to work through local git interactively — commits, branches, history,
submodules, worktrees, or remotes. Not an agent caller needing deterministic execution ->
`git-orchestrate`. Not server-side Gitea work -> `gitea-workflow`.
Use when a human's local git request is general or ambiguous — it routes to the owning
domain skill. Not an unambiguous commit -> `git-commits`. Not an unambiguous branch ->
`git-branches`. Not an agent caller -> `git-orchestrate`. Not Gitea -> `gitea-workflow`.
metadata:
category: git

View File

@@ -28,7 +28,7 @@ metadata:
| Create on a new branch | `git worktree add -b <branch> <path>` |
| Create on the branch named after the path basename | `git worktree add <path>` — checks that branch out if it exists, else creates it from HEAD |
| Create and reset an existing branch to HEAD — discards its commits | `git worktree add -B <branch> <path>` |
| Create a local branch tracking a remote one | `git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** when `<branch>` has no local copy (gate below) |
| Create a local branch tracking a remote one | `git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** under the conditions in `references/worktrees.md` |
| Throwaway experiment, no branch | `git worktree add -d <path>` — detached HEAD |
| **Never** `git worktree add <path> <remote>/<branch>` | That ref resolves, so the shortcut never fires and you get **a detached HEAD, no branch, no upstream**. Commits there go unreachable once HEAD moves, and `git push` needs an explicit refspec. Use the tracking row above |
| List | `git worktree list -v`, or `--porcelain -z` to parse |
@@ -40,15 +40,14 @@ metadata:
If the operation needs anything the table does not carry — the full `add` flag
table, orphan branches, sparse-checkout, locking for removable media, remote
disambiguation across several remotes, worktree config keys, or the worked
emergency-fix and PR-review patterns — read `references/worktrees.md`.
disambiguation across several remotes, how to name a worktree unambiguously,
worktree config keys, or the worked emergency-fix and PR-review patterns — read
`references/worktrees.md`.
Gates:
- **`move`, `remove` — the main worktree cannot be moved or removed.** Only linked worktrees, the ones `git worktree add` created, are candidates.
- **`add`, `move`, `remove` — escalate force flags one step at a time.** `-f` overrides a safeguard such as an unclean tree; `move` and `remove` need `-ff` on top of that when the worktree is locked. Confirm with the user before either — both discard state.
- **`lock`, `move`, `remove`, `repair` — identify a worktree by full path, unique basename, or unique partial path.** An ambiguous name errors rather than picking; `git worktree list` shows the usable identifiers.
- **`add` — the bare-name tracking shortcut needs exactly one remote.** `git worktree add <path> <branch>` sets up tracking only when `<branch>` is absent locally, no `-b`/`-B`/`-d` is given, and exactly one remote carries the name. With several, it fires only if `checkout.defaultRemote` names one. When the remote is ambiguous or unknown, use `--track -b`.
- **`add` — lock at creation, not after.** `git worktree add --lock` is atomic, where add-then-`lock` leaves a window in which the worktree is unprotected.
## Step 2 — Report

View File

@@ -4,6 +4,8 @@ source_keys:
- git-scm-worktree-docs
---
# Git worktrees
## Shared vs. per-worktree state
All worktrees share one object store, one config, and most refs under `refs/`. Each worktree keeps
@@ -12,6 +14,12 @@ its own `HEAD`, index, and per-worktree metadata (`ORIG_HEAD`, `MERGE_HEAD`, `re
worktree** exists per repo — the one `git init` or `git clone` produced — and it cannot be removed
or moved. Every other worktree is a **linked worktree** created by `git worktree add`.
## Identifying a worktree
`lock`, `move`, `remove` and `repair` accept a full path, a unique basename, or a unique partial
path. An ambiguous name errors rather than picking one; `git worktree list` shows the identifiers
that are usable.
## `add` forms
```bash
@@ -85,10 +93,11 @@ git worktree unlock <path> # when reconnected
git worktree add --track -b <branch> <path> <remote>/<branch> # explicit: no guessing at all
git worktree add <path> <branch> # shortcut: needs one clear remote
```
The shortcut fires only when `<branch>` is not found locally, none of `-b`/`-B`/`--detach` were
given, and a tracking branch of that name exists in exactly one remote. When several remotes carry
the name, `checkout.defaultRemote` picks one for disambiguation purposes; with no such setting the
shortcut has no single remote to resolve against and does not apply.
**The bare-name shortcut needs exactly one remote.** It fires only when `<branch>` is not found
locally, none of `-b`/`-B`/`--detach` were given, and a tracking branch of that name exists in
exactly one remote. When several remotes carry the name, `checkout.defaultRemote` picks one for
disambiguation purposes; with no such setting the shortcut has no single remote to resolve against
and does not apply. When the remote is ambiguous or unknown, use the explicit `--track -b` form.
`--guess-remote` covers the *other* spelling — `git worktree add <path>` with no `<commit-ish>` at
all. It bases the new branch on the remote-tracking branch matching `$(basename <path>)` when

View File

@@ -20,7 +20,7 @@ allowed-tools: Bash Read
- The `SKIP` env var takes exact hook `id` values, comma-separated with no spaces: `SKIP=check-yaml,gitleaks git commit -m "msg"`. A space after a comma silently skips nothing instead of erroring.
- Never bypass a failing hook with `git commit --no-verify` (or `-n`). Hooks are the automated QA gate, so a bypassed commit pushes the failure downstream where it costs more — diagnose it instead.
- `- files were modified by this hook` is not a bug. A fixer hook (`trailing-whitespace`, `end-of-file-fixer`, `pretty-format-json --autofix`) rewrote a staged file, so the staged snapshot is stale and the commit is blocked on purpose. The fix is to re-stage and re-run the same commit: `git add -u && git commit`. Do NOT reach for `pre-commit install -f` here — that flag overwrites hook files in `.git/hooks/` and has nothing to do with re-staging.
- `- files were modified by this hook` is not a bug. A fixer hook rewrote a staged file, so the staged snapshot is stale and the commit is blocked on purpose. Re-stage and re-run the same commit: `git add -u && git commit`. Do NOT reach for `pre-commit install -f` here — it overwrites `.git/hooks/` and has nothing to do with re-staging.
## Gate — `pre-commit clean`
@@ -47,8 +47,6 @@ Determine intent from the user's request, then execute the matching operation. W
| "clean", "wipe cache", "rebuild from scratch" | `pre-commit clean` — read `references/clean.md` |
| "hooks aren't running", "hook never fires", "why did a hook fail", a hook failure whose cause is unclear | Diagnose — read `references/failure-patterns.md` |
If the intent is ambiguous, default to `pre-commit run --all-files`.
## Run
Default to `pre-commit run --all-files`; never silently narrow to staged files. Run `pre-commit run` (staged only) or `pre-commit run <hook-id>` (one named hook) when the user asks for it.

View File

@@ -6,16 +6,12 @@ source_keys:
# Wiping the pre-commit cache
Reached from `SKILL.md`'s Route table when the user asks to clean the cache or rebuild environments from scratch. Self-contained.
Reached from `SKILL.md`'s Route table when the user asks to clean the cache or rebuild environments from scratch. The confirmation gate on `pre-commit clean` stays in `SKILL.md`, because it must fire on every path that reaches this command, not only this one.
## Gate — confirm first
## Gate
`pre-commit clean` wipes the whole cache at `~/.cache/pre-commit`, forcing every hook environment to be re-downloaded on the next run. Require explicit confirmation before executing it:
> "This will wipe the entire pre-commit cache. All hook environments will be re-downloaded on next run. Proceed?"
`pre-commit clean` runs only after the confirmation gate in `SKILL.md` clears — that gate, its exact wording, and the `pre-commit gc` alternative live there and are not restated here.
```bash
pre-commit clean
```
Prefer `pre-commit gc` when the goal is only to reclaim disk — it drops unused environments and leaves the ones in use intact, so it needs no confirmation.

View File

@@ -8,7 +8,6 @@ description: >
Not branch lifecycle -> `git-branches`.
metadata:
version: "0.1.3"
category: git
source_keys:
- conventional-commits-spec

View File

@@ -9,21 +9,20 @@ description: >
Not submodule pointers -> `git-submodules`.
metadata:
category: git-workflow
category: git
source_keys:
- git-scm-remote-docs
- git-scm-fetch-docs
- git-scm-push-docs
- git-scm-pull-docs
- context7-git-htmldocs
---
## Gotchas
- **`--force-with-lease` alone is not safe** — background processes (IDE plugins, cron jobs) running `git fetch` silently defeat the protection. Combine it with `--force-if-includes`, or pin the explicit `--force-with-lease=<ref>:<sha>` form.
- **Prune does not touch tags by default** — `git fetch --prune` leaves orphaned tags behind. Use `--prune --prune-tags`, or set `fetch.pruneTags true`.
- **Pull defaults shift between Git versions** — older ones default to merge, newer to `--ff-only`. Set `pull.ff only` explicitly rather than trusting the installed default.
- **Set `pull.ff only` explicitly** — do not trust the installed default.
## Step 1 — Clear the force-push gate

View File

@@ -23,6 +23,10 @@ A pull that diverges with no strategy configured fails, and that failure is the
## Config precedence
The installed default varies by Git version — older versions merge on divergence, newer ones
default to `--ff-only` — so an unset `pull.ff` means the same pull behaves differently on different
machines. Set it explicitly.
Highest wins:
1. Command-line flag (`--ff-only` / `--rebase` / `--no-rebase`)

View File

@@ -51,7 +51,7 @@ executing.
## Output format
```
```yaml
operation: <clone|add|init|update|status|sync|set-url|set-branch|absorbgitdirs|deinit|remove>
status: <success|error|partial>
message: <one line; include git's own output on error>

View File

@@ -1,7 +1,6 @@
---
metadata:
source_keys:
- git-scm-submodule-docs
source_keys:
- git-scm-submodule-docs
---
# References

View File

@@ -2,9 +2,9 @@
name: git-workflow
description: >
Use when a human wants to work through local git interactively — commits, branches, history,
submodules, worktrees, or remotes. Not an agent caller needing deterministic execution ->
`git-orchestrate`. Not server-side Gitea work -> `gitea-workflow`.
Use when a human's local git request is general or ambiguous — it routes to the owning
domain skill. Not an unambiguous commit -> `git-commits`. Not an unambiguous branch ->
`git-branches`. Not an agent caller -> `git-orchestrate`. Not Gitea -> `gitea-workflow`.
metadata:
category: git

View File

@@ -28,7 +28,7 @@ metadata:
| Create on a new branch | `git worktree add -b <branch> <path>` |
| Create on the branch named after the path basename | `git worktree add <path>` — checks that branch out if it exists, else creates it from HEAD |
| Create and reset an existing branch to HEAD — discards its commits | `git worktree add -B <branch> <path>` |
| Create a local branch tracking a remote one | `git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** when `<branch>` has no local copy (gate below) |
| Create a local branch tracking a remote one | `git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** under the conditions in `references/worktrees.md` |
| Throwaway experiment, no branch | `git worktree add -d <path>` — detached HEAD |
| **Never** `git worktree add <path> <remote>/<branch>` | That ref resolves, so the shortcut never fires and you get **a detached HEAD, no branch, no upstream**. Commits there go unreachable once HEAD moves, and `git push` needs an explicit refspec. Use the tracking row above |
| List | `git worktree list -v`, or `--porcelain -z` to parse |
@@ -40,15 +40,14 @@ metadata:
If the operation needs anything the table does not carry — the full `add` flag
table, orphan branches, sparse-checkout, locking for removable media, remote
disambiguation across several remotes, worktree config keys, or the worked
emergency-fix and PR-review patterns — read `references/worktrees.md`.
disambiguation across several remotes, how to name a worktree unambiguously,
worktree config keys, or the worked emergency-fix and PR-review patterns — read
`references/worktrees.md`.
Gates:
- **`move`, `remove` — the main worktree cannot be moved or removed.** Only linked worktrees, the ones `git worktree add` created, are candidates.
- **`add`, `move`, `remove` — escalate force flags one step at a time.** `-f` overrides a safeguard such as an unclean tree; `move` and `remove` need `-ff` on top of that when the worktree is locked. Confirm with the user before either — both discard state.
- **`lock`, `move`, `remove`, `repair` — identify a worktree by full path, unique basename, or unique partial path.** An ambiguous name errors rather than picking; `git worktree list` shows the usable identifiers.
- **`add` — the bare-name tracking shortcut needs exactly one remote.** `git worktree add <path> <branch>` sets up tracking only when `<branch>` is absent locally, no `-b`/`-B`/`-d` is given, and exactly one remote carries the name. With several, it fires only if `checkout.defaultRemote` names one. When the remote is ambiguous or unknown, use `--track -b`.
- **`add` — lock at creation, not after.** `git worktree add --lock` is atomic, where add-then-`lock` leaves a window in which the worktree is unprotected.
## Step 2 — Report

View File

@@ -4,6 +4,8 @@ source_keys:
- git-scm-worktree-docs
---
# Git worktrees
## Shared vs. per-worktree state
All worktrees share one object store, one config, and most refs under `refs/`. Each worktree keeps
@@ -12,6 +14,12 @@ its own `HEAD`, index, and per-worktree metadata (`ORIG_HEAD`, `MERGE_HEAD`, `re
worktree** exists per repo — the one `git init` or `git clone` produced — and it cannot be removed
or moved. Every other worktree is a **linked worktree** created by `git worktree add`.
## Identifying a worktree
`lock`, `move`, `remove` and `repair` accept a full path, a unique basename, or a unique partial
path. An ambiguous name errors rather than picking one; `git worktree list` shows the identifiers
that are usable.
## `add` forms
```bash
@@ -85,10 +93,11 @@ git worktree unlock <path> # when reconnected
git worktree add --track -b <branch> <path> <remote>/<branch> # explicit: no guessing at all
git worktree add <path> <branch> # shortcut: needs one clear remote
```
The shortcut fires only when `<branch>` is not found locally, none of `-b`/`-B`/`--detach` were
given, and a tracking branch of that name exists in exactly one remote. When several remotes carry
the name, `checkout.defaultRemote` picks one for disambiguation purposes; with no such setting the
shortcut has no single remote to resolve against and does not apply.
**The bare-name shortcut needs exactly one remote.** It fires only when `<branch>` is not found
locally, none of `-b`/`-B`/`--detach` were given, and a tracking branch of that name exists in
exactly one remote. When several remotes carry the name, `checkout.defaultRemote` picks one for
disambiguation purposes; with no such setting the shortcut has no single remote to resolve against
and does not apply. When the remote is ambiguous or unknown, use the explicit `--track -b` form.
`--guess-remote` covers the *other* spelling — `git worktree add <path>` with no `<commit-ish>` at
all. It bases the new branch on the remote-tracking branch matching `$(basename <path>)` when

View File

@@ -20,7 +20,7 @@ allowed-tools: Bash Read
- The `SKIP` env var takes exact hook `id` values, comma-separated with no spaces: `SKIP=check-yaml,gitleaks git commit -m "msg"`. A space after a comma silently skips nothing instead of erroring.
- Never bypass a failing hook with `git commit --no-verify` (or `-n`). Hooks are the automated QA gate, so a bypassed commit pushes the failure downstream where it costs more — diagnose it instead.
- `- files were modified by this hook` is not a bug. A fixer hook (`trailing-whitespace`, `end-of-file-fixer`, `pretty-format-json --autofix`) rewrote a staged file, so the staged snapshot is stale and the commit is blocked on purpose. The fix is to re-stage and re-run the same commit: `git add -u && git commit`. Do NOT reach for `pre-commit install -f` here — that flag overwrites hook files in `.git/hooks/` and has nothing to do with re-staging.
- `- files were modified by this hook` is not a bug. A fixer hook rewrote a staged file, so the staged snapshot is stale and the commit is blocked on purpose. Re-stage and re-run the same commit: `git add -u && git commit`. Do NOT reach for `pre-commit install -f` here — it overwrites `.git/hooks/` and has nothing to do with re-staging.
## Gate — `pre-commit clean`
@@ -47,8 +47,6 @@ Determine intent from the user's request, then execute the matching operation. W
| "clean", "wipe cache", "rebuild from scratch" | `pre-commit clean` — read `references/clean.md` |
| "hooks aren't running", "hook never fires", "why did a hook fail", a hook failure whose cause is unclear | Diagnose — read `references/failure-patterns.md` |
If the intent is ambiguous, default to `pre-commit run --all-files`.
## Run
Default to `pre-commit run --all-files`; never silently narrow to staged files. Run `pre-commit run` (staged only) or `pre-commit run <hook-id>` (one named hook) when the user asks for it.

View File

@@ -6,16 +6,12 @@ source_keys:
# Wiping the pre-commit cache
Reached from `SKILL.md`'s Route table when the user asks to clean the cache or rebuild environments from scratch. Self-contained.
Reached from `SKILL.md`'s Route table when the user asks to clean the cache or rebuild environments from scratch. The confirmation gate on `pre-commit clean` stays in `SKILL.md`, because it must fire on every path that reaches this command, not only this one.
## Gate — confirm first
## Gate
`pre-commit clean` wipes the whole cache at `~/.cache/pre-commit`, forcing every hook environment to be re-downloaded on the next run. Require explicit confirmation before executing it:
> "This will wipe the entire pre-commit cache. All hook environments will be re-downloaded on next run. Proceed?"
`pre-commit clean` runs only after the confirmation gate in `SKILL.md` clears — that gate, its exact wording, and the `pre-commit gc` alternative live there and are not restated here.
```bash
pre-commit clean
```
Prefer `pre-commit gc` when the goal is only to reclaim disk — it drops unused environments and leaves the ones in use intact, so it needs no confirmation.