feat(skills): vendor the outsource skill (explore/review/write)#4
feat(skills): vendor the outsource skill (explore/review/write)#4OriNachum wants to merge 1 commit into
Conversation
Cite-don't-import copy of the canonical outsource skill from guildmaster: hand a scoped repo task to convertible (a different engine/mind) for a diverse second opinion — outsource review|explore|write. Portable wrapper; resolves the convertible CLI from PATH. Patch bump per version-check rule. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review Summary by QodoVendor outsource skill with explore/review/write verbs
WalkthroughsDescription• Vendors canonical outsource skill from guildmaster into .claude/skills/outsource/ • Implements three verbs: explore (read-only investigation), review (independent diff opinion), write (implementation delegation) • Portable shell wrapper resolves convertible CLI from PATH with fallback to local dev mode • Fixes 8 markdownlint violations (MD041, MD032) and bumps version 0.1.0 → 0.1.1 Diagramflowchart LR
User["User invokes outsource.sh"] -->|explore| ReadOnly1["Throwaway worktree at HEAD"]
User -->|review| ReadOnly2["Throwaway worktree at HEAD"]
User -->|write| InPlace["In-place drive branch"]
ReadOnly1 -->|render_prompt| Explore["explore.md template"]
ReadOnly2 -->|render_prompt| Review["review.md template"]
InPlace -->|render_prompt| Write["write.md template"]
Explore -->|convertible drive| Result1["TaskResult JSON"]
Review -->|convertible drive| Result2["TaskResult JSON"]
Write -->|convertible drive| Result3["TaskResult JSON"]
Result1 -->|print_result| Output1["Summary + findings"]
Result2 -->|print_result| Output2["Summary + review"]
Result3 -->|print_result| Output3["Summary + branch/PR"]
File Changes1. .claude/skills/outsource/scripts/outsource.sh
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
28 rules 1. outsource.sh depends on external convertible
|
|
| # ── resolve the convertible CLI (installed, then local-dev fallback) ───────── | ||
| CONVERTIBLE=() | ||
| resolve_convertible() { | ||
| if command -v convertible >/dev/null 2>&1; then | ||
| CONVERTIBLE=(convertible) # installed tool — the normal case | ||
| return 0 | ||
| fi | ||
| # Local-dev fallback: inside the convertible checkout, run via uv. | ||
| local dir="$PWD" | ||
| while [[ -n "$dir" ]] && [[ "$dir" != "/" ]]; do | ||
| if [[ -f "$dir/pyproject.toml" ]] \ | ||
| && grep -q '^name = "convertible-cli"' "$dir/pyproject.toml" 2>/dev/null; then | ||
| if command -v uv >/dev/null 2>&1; then | ||
| CONVERTIBLE=(uv run convertible) | ||
| return 0 | ||
| fi | ||
| break | ||
| fi | ||
| dir=$(dirname "$dir") | ||
| done | ||
| cat >&2 <<'EOF' | ||
| error: convertible CLI not found. | ||
| hint: install it with `uv tool install convertible-cli` (or `pipx install convertible-cli`), | ||
| or run from inside the convertible checkout with `uv` available. | ||
| https://github.com/agentculture/convertible | ||
| EOF | ||
| return 1 |
There was a problem hiding this comment.
1. outsource.sh depends on external convertible 📘 Rule violation ⚙ Maintainability
The new skill entrypoint relies on an external convertible CLI from PATH (or an external convertible checkout via uv run), rather than a vendored in-repo dependency. This violates the requirement that skill scripts not depend on resources outside the repository, reducing portability and increasing supply-chain risk.
Agent Prompt
## Issue description
`.claude/skills/outsource/scripts/outsource.sh` resolves and executes `convertible` from the system (`PATH`) and even supports running from an external `convertible` checkout. Compliance requires skill scripts to avoid dependencies on paths/resources outside this repository.
## Issue Context
The script currently:
- Executes `convertible` if found on `PATH`.
- Falls back to `uv run convertible` when it detects it is inside a separate `convertible` repository checkout.
This makes the skill non-self-contained and dependent on external installations/repos.
## Fix Focus Areas
- .claude/skills/outsource/scripts/outsource.sh[22-48]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| The change under review is the committed diff on this branch versus its base | ||
| (`$BASE`). Start by running, read-only: | ||
|
|
||
| git diff $BASE...HEAD --stat | ||
| git diff $BASE...HEAD | ||
|
|
There was a problem hiding this comment.
2. Base value command injection 🐞 Bug ⛨ Security
--base is substituted into the review prompt’s suggested git diff $BASE...HEAD commands without quoting or validation, so a crafted base containing shell metacharacters can turn a “read-only” step into arbitrary command execution by the outsourced model.
Agent Prompt
## Issue description
The `review` prompt instructs the outsourced agent to run `git diff $BASE...HEAD`, and `outsource.sh` allows arbitrary `--base` values. If `--base` contains shell metacharacters (e.g., `main; <cmd>`), the prompt becomes an injection vector when the outsourced agent executes the command.
## Issue Context
This is not executed by `outsource.sh` directly, but it is explicitly executed by the outsourced agent via its command-running tool, so prompt text must be treated as a command construction surface.
## Fix
Do both:
1) **Validate** `--base` in `outsource.sh` to a safe git-revision charset (reject whitespace and shell metacharacters).
2) **Quote** the revision range in the prompt template to avoid accidental word-splitting/injection.
Examples:
- In `outsource.sh`, after parsing flags:
- `[[ "$BASE" =~ ^[A-Za-z0-9._/-]+$ ]] || { echo "error: unsafe --base value" >&2; exit 2; }`
- In `review.md`, change to something like:
- `git diff "${BASE}...HEAD" --stat`
- `git diff "${BASE}...HEAD"`
(or `git diff --stat "$BASE"...HEAD` if you prefer two args)
## Fix Focus Areas
- .claude/skills/outsource/scripts/outsource.sh[115-165]
- .claude/skills/outsource/prompts/review.md[10-15]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Summary
outsourceskill (explore / review / write) from guildmaster into lecodeur's.claude/skills/outsource/.markdownlint-cli2.yamlWhat the outsource skill does
Hands a scoped repo task to
convertible— a different engine/mind — for a diverse second opinion:outsource explore <topic>— fresh-eyes read-only investigationoutsource review [focus]— independent diff review versus branch baseoutsource write <task>— implement the smallest correct changeThe portable shell wrapper resolves the
convertibleCLI from PATH.Test plan
CI passes (lint, tests, version-check)
.claude/skills/outsource/SKILL.mdfrontmattername: outsourceis presentmarkdownlint-cli2 ".claude/skills/outsource/**/*.md"reports 0 errorsCompanion align-issue filed on this repo
lecodeur (Claude)