# Vendored skills

agtag vendors skills from sibling repos in the AgentCulture mesh under
the "cite, don't import" pattern: each skill is copied into
`.claude/skills/<name>/`, may be adapted locally, and does not auto-update
when its upstream changes. Each row records the upstream source of record
and the kind of local divergence (if any).

| Skill | Upstream | Local divergence |
|-------|----------|------------------|
| `cicd` | `agentculture/steward` (`.claude/skills/cicd/`) | identifier-only adapted: SKILL.md prose names agtag as the consumer. Skill is now a thin delegate to `agex pr` (>=0.1); the two steward extensions (`status`, `await`) and `pr-reply.sh` / `portability-lint.sh` / `_resolve-nick.sh` are vendored verbatim — `_resolve-nick.sh` resolves to `agtag` from `culture.yaml`. `STEWARD_*` env var names retained for re-sync stability. Local fix in `pr-status.sh` SonarCloud section: curl/JSON guards (`sonar_get` helper) re-added so a SonarCloud outage no longer aborts `workflow.sh await` under `set -euo pipefail`; filed upstream pending steward re-add. |
| `communicate` | `agentculture/steward` (`.claude/skills/communicate/`) | SKILL.md inverts upstream framing: agtag IS the CLI, so `agtag issue post` / `reply` / `fetch` are invoked directly. Signing nick resolves from this repo's `culture.yaml` (`agents[0].suffix` → `agtag`), falling back to the repo basename; pass `agtag --as NICK` at the call site to override. `fetch-issues.sh` is kept (it wraps `agtag issue fetch` with range/list expansion that the single-issue CLI doesn't have) and now places `set -euo pipefail` immediately after the shebang (local fix, filed upstream). `mesh-message.sh` and the broadcast template are verbatim. **Not vendored:** `post-issue.sh` and `post-comment.sh` — they would be `agtag → bash → agtag` circularity in this repo. |
| `version-bump` | `agentculture/steward` (`.claude/skills/version-bump/`) | identifier-only: SKILL.md `steward/__init__.py` reference replaced with `agtag/__init__.py`; `scripts/bump.py` is generic on package name (reads `pyproject.toml`) and copied verbatim. |
| `run-tests` | `agentculture/steward` (`.claude/skills/run-tests/`) | none — `scripts/test.sh` reads `[tool.coverage.run]` from `pyproject.toml`, fully package-agnostic. |
| `pypi-maintainer` | `agentculture/steward` (`.claude/skills/pypi-maintainer/`) | none — `scripts/switch-source.sh` takes the package name as its first argument; copied verbatim. |

## Re-sync policy

Upstream changes do not auto-propagate. Steward broadcasts a migration
brief via `steward announce-skill-update` (this is how
[#1](https://github.com/agentculture/agtag/issues/1) and
[#2](https://github.com/agentculture/agtag/issues/2) arrived). To re-sync
a skill from upstream:

1. Branch off `main` (e.g. `skill/<name>-resync`).
2. `cp -R ../steward/.claude/skills/<name> .claude/skills/`
   (overwriting). The `git rm` step in the brief does not apply if the
   skill name is unchanged.
3. Re-apply the local divergence listed above.
4. `chmod +x .claude/skills/<name>/scripts/*.sh` and run `bash -n` on
   each to catch syntax breaks before committing.
5. Sweep for stale literals:
   `grep -rn 'steward (Claude)' .claude/skills/<name>/scripts/`.
6. Update this ledger if the divergence shape changed.

## Adding a new vendored skill

When vendoring a new skill from an upstream repo, add a row to the
table above with the divergence list (or "none"), and ask the upstream
maintainer to add agtag to their `docs/skill-sources.md` "Downstream
copies" column so future broadcasts find this repo automatically.