This skill is the third factory. Two repo templates were fixed when the
buildah->buildctl migration went through, and this one kept handing out
the broken step for weeks afterwards -- because it is what gets consulted
when adding CI to an EXISTING repo, which the templates never touch.
Pasting an implementation is the actual defect. The estate now has one
(mathias/infra ci-templates/build-image.sh) with byte-identical copies
held in place by a drift gate, so the skill teaches the four adoption
steps and the input list instead of a block to copy.
Step 1 of those four -- registering in adopters.txt -- is called out
explicitly, because a copy nobody registered works today and falls
silently behind on the next canonical change. That is the failure this
whole issue exists to end.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011PL5XcG68SvQqz3vGVbWbf
This skill was the source of the buildah build step that infra#241 has
spent a sprint removing from nine repos: rootless buildah cannot run in
the containerized gitea-runner (drop ALL capabilities,
allowPrivilegeEscalation false, no OCI runtime), and the failure is
latent -- warm base-image layers hide it until the first cold pull.
Two templates were migrated for exactly this reason (stop new repos
inheriting the trap); this skill is the third factory and was still
handing out the broken pattern.
Also drops the `sudo k3s ctr` smoke test it recommended: written for the
Arch host runner, impossible in a pod (`sudo: command not found`). The
deploy job's rollout verification covers the same ground.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011PL5XcG68SvQqz3vGVbWbf
Skills move to skills/<name>/SKILL.md and the repo gains both manifests, so
it is now a marketplace hosting exactly one plugin whose root is the repo
root (source: "."). Claude Code installs it from git; no symlinks involved.
Why: install.sh wired the library into every consuming repo as an ABSOLUTE
symlink to $CHECKOUT_DIR. The checkout moved three times, most recently when
local-dev@1966d5a dropped the embedded .skills/ copy, and nothing migrated
the links — 243 dangling links across 12 repos, hidden from git by the
**/.claude/skills/ ignore rule. Worse, ~/dev spans two path roots
(/Users/mathias on the iCloud-shared Macs, /home/mathias on koala), so an
absolute link stored there is broken on one side by construction. Re-running
the installer cannot fix that; only removing the mechanism can.
install.sh keeps the harnesses with no plugin system and drops from 42 links
per harness to one directory link, via the convergent ~/.agents/skills
convention that Pi and OpenCode both read:
~/.agents/skills -> $CHECKOUT_DIR/skills
~/.config/crush/skills -> ~/.agents/skills
~/.config/opencode/skills -> ~/.agents/skills
wire_claude_repo is deleted outright rather than gated behind a flag — on a
mixed-root fleet it cannot be made correct. Antigravity and Vibe targets go
too; both unused. CHECKOUT_DIR keeps its host-local default deliberately:
pointing it into ~/dev would put a git working tree inside iCloud with two
concurrent writers.
Taskfile drops five near-identical wiring loops (they had already drifted)
and delegates to install.sh. `task check` gains frontmatter validation, a
stray-root-entry gate, and manifest/tag version parity — the loose
secret-hygiene.md sat unloadable for months because nothing checked layout.
Verified: claude plugin validate . passes clean; a probe skill loaded as
skills:zzprobe through --plugin-dir; task check green at 42 skills.
Refs: #23
Bump-Type: minor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m