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

Retrofits all 39 skills to ADR-0020's description/body context contract, then fixes what six rounds of independent review found in that retrofit — including four ways the hot gate itself failed open.

Closes #99, #107, #108, #110, #111, #114, #115, #120.

## The retrofit (waves 1-5)

| | Start | Now |
|---|---|---|
| Description FAILs (>400 chars) | 26 | **0** |
| Body FAILs (>900 words, body-only) | 9 | **0** |
| Dangling routing targets | 2 | **0** |
| `Kyberforge.CompositionNote` | 10 | **0** |
| Preload tax | 21,005 chars | **~10,500** |

Under the 12,000-char success criterion. Per-wave detail is on #99.

## The review fixes

**The gate failed open four ways, three of them found after the retrofit shipped.** An unrecognised follower token made a dangling target vanish. A skill directory with no `SKILL.md` resolved as a valid target, so a commit could be green locally and red in a fresh clone — three existing fixtures were relying on that, one of which made the install-leak A/B pass vacuously. Then the free-standing `/name` sweep turned out to be gated on the sentence carrying a boundary marker, so route notation in any other sentence was invisible — not an ERROR, not a SUGGESTION, not an INFO — which left the documented "`/name` always blocks" promise false from a second direction. All four fixed and pinned.

**Two checks were silently not running.** `validate-provenance.sh` checks 7-8 were dead across nine skills. Waking them exposed a deeper problem: they assume `Research doc:` names a source index, but 30 of 121 entries point at topic content documents, so every new check-7 INFO was a false positive and check 8 was saved from a false-FAIL flood only by an *unannounced* skip. Checks 7/8 are now scoped to source indexes and every skip announces itself (#121).

**The retrofit's own anti-goal, four times.** ADR-0020 warns that a blunt gate gets satisfied by deleting content rather than relocating it. `diagnose` and `skill-audit` relocated prose and then read it unconditionally; `prototype` and `vale-config` deleted rules outright that survived nowhere. All four addressed.

## Verification

- `bash tests/run-tests.sh --strict` — 24 suites, 0 skipped, 0 failed
- `bash tests/run-bats.sh` — 325 tests, 0 failures
- `pre-commit run --all-files` — 17/17
- `pre-commit run --hook-stage pre-push --all-files` — 16/16, with `apm marketplace check` and `apm pack --check-clean` run against the remote, not skipped
- `scripts/skill-size-check.sh` over all 39 skills — rc 0, 0 ERROR/FAIL, SUGGESTION-only
- Preload tax measured at **10,498 chars**, max description 390 — both inside budget
- Every new test proven non-vacuous by a deliberate mutation of the behaviour it covers

**Per-commit sync, stated accurately:** the ten commits from the latest review round each pass `check-plugin-content-sync` in isolation, verified by checking each out in a detached worktree with a clean between. The earlier gitea window (`dfacf05..bedbd1d`, nine commits) does **not** — its mirror was regenerated in one batch at `bbc7300`. An earlier revision of this description claimed the property held for every commit; it does not, and a bisect through that window lands on a red commit. **Squash-merge** to collapse it, or accept that this range is not bisectable.

## Version bump

Six plugins and the catalog take a **patch**, not a minor. The branch is **89 commits — 40 `fix` / 30 `refactor` / 12 `docs` / 5 `chore` / 2 `test` — zero `feat`, zero `!`, zero `BREAKING CHANGE`** — and adds no skill, agent, command or hook. (Two earlier revisions of this section cited a stale histogram, most recently 78 commits; the figures above are measured at HEAD.) Both rules this repo ships (`forge/references/version-bump.md`, landing in this PR, and `git-commits/references/conventional-commits-spec.md`) make that a patch, and the catalog set is unchanged at 7 entries.

Not settled by that: four published files were removed from the installed tree, three moved, and `caveman` gained `disable-model-invocation`, retiring its old triggers. Under a strict reading those are major-class and currently ship under `refactor:` with no marker. Whether the deployed skill surface is a public contract is written down nowhere — worth deciding, but it outlives this PR.

## Deliberately not in scope

#112 (cherry-pick ownership, now resolved in favour of `git-commits`), #113 (`rtk git` normalisation), #116 (research fan-out), #101 (audit-skill merge), #122 (non-spec skill-root files), #123 (no PRD producer) stay open. #117 is the one worth reading: the contract's remedy is to move prose into `references/`, which is exactly where neither the size gate nor Vale looks — and the blind spot is wider than #117 currently records, since there is no root `.vale.ini` at all, so every ADR, `CONTEXT.md` and `README.md` is unlinted too.

That blind spot let this branch carry two `level: error` `Kyberforge.SentenceOpenerThereIs` violations into `references/` files it created — `provider-adapter-author/references/provider-matrix.md:31` and `agent-audit/references/finding-criteria.md:95`. Both are reworded in `afadaae`, confirmed by routing each file through the audit's own `vale-wrap.sh` (1 error each before, 0 after). Five further occurrences sit in `references/` files already on `main`; those are the pre-existing corpus and stay with #117, which is the real fix.

Also unfixed and not this PR's: `apm install` appends a duplicate `SessionStart` entry to `.claude/settings.json`, so a fresh clone cannot get pre-push green without an edit AGENTS.md warns against. Reproduces identically on `main`.

Co-authored-by: Defame1297 <gitea@rkdr.net>
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/129
Co-authored-by: Claude Code AI - Gitea MCP <claude@noreply.git.dev.rkdr.net>
Co-committed-by: Claude Code AI - Gitea MCP <claude@noreply.git.dev.rkdr.net>
This commit was merged in pull request #129.
This commit is contained in:
Claude Code AI - Gitea MCP
2026-09-01 13:47:46 +00:00
committed by Defame1297
parent 0e91a3ae66
commit 598a7c326a
420 changed files with 15303 additions and 4740 deletions

View File

@@ -2,12 +2,10 @@
name: git-workflow
description: >
Use when a human user wants to perform git workflows interactively — commits, branch management,
history inspection, submodules, worktrees, or remotes. Provides a friendly, conversational
interface with clarification prompts ("Which branch base?"), progress updates, inline help,
best practices guidance, and confirmation dialogs for destructive operations. Guides users
through complex git patterns even if they don't mention every detail. Do not use when the
caller is an agent—agents should invoke git-orchestrate directly for deterministic, composable execution.
Use when a human's local git request is general or ambiguous — it routes to the owning
domain skill: `git-commits`, `git-branches`, `git-history`, `git-remotes`, `git-submodules`
or `git-worktrees`. An unambiguous request goes straight to its domain skill instead. Not an
agent caller -> `git-orchestrate`. Not Gitea -> `gitea-workflow`.
metadata:
category: git
@@ -21,45 +19,61 @@ metadata:
## Gotchas
- This skill is specifically for **human interaction**. If the caller is an agent, invoke `git-orchestrate` directly instead—this skill adds UI overhead agents don't need.
- Session context from previous git operations (branch names, commit strategy) persists during a single multi-step user request, then clears. Users don't need to re-provide decisions within one workflow.
- Destructive operations require explicit confirmation: force-push, branch deletion, rebase with history loss, force-checkout. Users must confirm interactively; the skill never proceeds without their approval on destructive ops.
- Run git commands through `rtk git <command>` rather than bare `git <command>` for parent-repo operations — this is a mandated org wrapper, not an optional style choice. Drop into a submodule's own directory for submodule-specific commands (see `git-submodules`).
- Session context built during one multi-step request — branch names, the chosen base, the commit
strategy — persists for that request and then clears. Do not re-ask the user for a decision they
already gave you earlier in the same workflow.
- Run parent-repo commands through `rtk git <command>`, never bare `git <command>`. This is a
mandated org wrapper, not a style preference. Submodule-specific commands run from inside the
submodule's own directory instead.
### Hard rules
## Domains
These are non-negotiable regardless of what the user asks for — surface them proactively rather than waiting for the user to hit them (`org-git-conventions`; sub-skills invoked directly by humans, like this one, carry their own local copy of these rules for readers who won't chain through `git-orchestrate`, so state them plainly rather than assuming the user already knows them):
Route to the domain that owns the operation, and in sequence when a request spans two — a rebase
that ends in a force-push is `git-commits`, then `git-remotes`. An unambiguous request should have
gone straight to the domain skill; this one exists for the ones that did not.
- Never skip hooks with `--no-verify` — hooks are the automated QA gate, and bypassing them breaks the pipeline for everyone downstream.
- Never force-push `main` or `master`.
- Keep commits atomic — each commit should represent one logical, independently reviewable and reversible change.
- Every commit must leave the repository in a working state (buildable/testable where practical).
- Commit messages explain **why**, not **what** — the diff already documents what changed.
- Never commit secrets, credentials, or environment-specific config.
- Use Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `test:`, etc.).
- Reference related issues, ADRs, or design documents using Git trailers when applicable.
| The request is about | Domain |
|---|---|
| Writing, amending, squashing, or cherry-picking a commit, and its message | `git-commits` |
| Rebasing onto a new base, or undoing a commit with `reset` | `git-commits` |
| Creating, switching, deleting, renaming, tracking, or merging a local branch | `git-branches` |
| Stashing work in progress to move between branches | `git-branches` |
| When a change landed, which commit broke something, what to revert or backport | `git-history` |
| Anything touching a remote — remote config, fetch, push, pull — even unnamed | `git-remotes` |
| A nested repository pinned inside this one by a recorded commit | `git-submodules` |
| Several branches checked out at once, in separate directories, without stashing | `git-worktrees` |
If a user's request conflicts with a hard rule (e.g. "force-push main to fix this"), explain the rule and propose a safe alternative instead of complying.
`git-orchestrate` executes whatever this resolves to (step 5); the table only decides which domain
owns the request.
## Workflow
When a user wants to perform git workflows:
1. **Parse the user's intent** — extract the high-level task (commit, create branch, rebase, inspect history, etc.) and any explicit options they mentioned.
2. **Build session context** — gather repo state, current branch, any prior decisions in this workflow (branch intent for commit messages, base branch for rebasing, etc.).
3. **Invoke git-orchestrate agent** — call it with:
- `operation`: the git operation (e.g., "commit", "create-branch", "rebase")
- `parameters`: user-provided or inferred options
- `context`: decisions and repo state from prior steps in this workflow
- `confirm`: `true` if a destructive op and the user confirmed, otherwise omit
4. **Handle the response** — if orchestrator succeeds, present results in plain language with progress updates and explanations. If it fails, show the error reason and suggest recovery actions.
5. **Clarification prompts** — if the orchestrator needs more information (e.g., "Which branch should this be based on?"), prompt the user conversationally and loop back with the user's input.
6. **Confirmation gates** — before executing any destructive op (force-push, branch deletion, rebase, force-checkout), show what will happen and ask "Proceed?" If the user declines, cancel gracefully.
1. **Parse intent** — extract the operation and, from the table above, the domain that owns it,
plus any options the user named.
2. **Check the hard rules** — if the request creates, amends, or rewrites a commit, pushes, or
touches hooks, config, or credentials, read `references/hard-rules.md`. Raise the relevant rule
before acting, not after.
3. **Read the repo** — current branch, working-tree state, and which branching model the repo
follows (the orchestrator reads `branching_pattern` from plugin config; infer from branch names
if absent); the last of those decides which tips are worth offering.
4. **Gate destructive operations** — before force-push, branch deletion, rebase, or
force-checkout, show what will happen and ask "Proceed?". Cancel gracefully if the user
declines. Never supply the confirmation on the user's behalf. Some operations are refusals, not
confirmations: never offer "Proceed?" for a force-push of `main` or `master`.
5. **Invoke the `git-orchestrate` agent** with `operation`, `parameters` (user-provided or
inferred), `context` (step 3 plus the session context), and `confirm: true` only for a
destructive op the user approved in step 4.
6. **Clarify when the orchestrator asks for more** — put its question to the user in plain
language ("Which branch should this be based on?") and loop back to step 5 with the answer.
7. **Report the outcome** — on success, the result and what changed, in plain language; on
failure, the error reason and a recovery action.
## Interaction style
- **Conversational**: Use natural language, not technical jargon. "Let me rebase your changes onto main" not "Running git rebase --interactive main".
- **Pedagogical**: Explain what each step does and why. "I'm squashing your last 3 commits into one clean commit" not just "Squashing commits".
- **Guided**: Offer inline help. When users mention ambiguous steps, suggest best practices. Match the tip to the repo's branching model: for Gitflow-style repos, "Tip: Feature branches branch off `develop`, not `main` — `main` only tracks released code." For trunk-based/GitHub Flow repos, "Tip: Short-lived feature branches off `main` keep merges small and reviewable."
- **Transparent**: Show progress. "Creating branch feature/user-auth..." then "✓ Branch created. Ready to commit." Humans benefit from seeing workflow state.
- **Safe**: Always confirm before destructive ops. Never silently rewrite history or force-push without explicit user approval.
The caller is a human, so the interaction is the point. Explain each step and why it happens ("I'm
squashing your last 3 commits into one clean commit" beats "Squashing commits"), show progress as
you go, and prefer natural language to raw command lines.
Match tips to the repo's branching model rather than offering generic advice: on a Gitflow repo,
feature branches come off `develop` and `main` tracks only released code; on a trunk-based or
GitHub Flow repo, short-lived branches off `main` keep merges small and reviewable.