Skip to content

feat: per-host SKILL.md generated from shared template (#55)#57

Closed
earino wants to merge 1 commit into
mainfrom
feature/issue-55-templated-skill-md
Closed

feat: per-host SKILL.md generated from shared template (#55)#57
earino wants to merge 1 commit into
mainfrom
feature/issue-55-templated-skill-md

Conversation

@earino

@earino earino commented Apr 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • Closes v0.5: Generate per-host SKILL.md from a template #55. Each AI CLI host now reads a SKILL.md that only mentions its own tool names — no cross-host enumeration. Eliminates the qwen3.6-35b mis-dispatch class observed in samples-issue42/session-ses_235c.md where the model picked Claude Code's general-purpose (listed first in the cross-host bullet) on its OpenCode dispatch and got Unknown agent type rejected before self-correcting to general.
  • SKILL.md.tmpl is the source of truth; tools/gen_skill_md.py emits SKILL-<host>.md per host (claude / codex / gemini / opencode) plus a default SKILL.md (= claude variant) so a clone-without-install user still gets a working file. Template engine is intentionally minimal — {{var}} substitution + {{#if host}}...{{/if}} / {{#unless host}}...{{/unless}} conditional blocks, no Jinja2 dependency, ~120 lines of stdlib Python.
  • install.sh detects the install path (.claude/skills/... → claude, .codex/skills/... → codex, etc.) and copies the matching variant over SKILL.md. Clones to non-canonical paths default to claude.
  • tests/test_skill_md_template_generation.py (16 tests) pin drift detection (--check exits non-zero if regenerated content would differ), per-host shape (each variant references ONLY its own tools; OpenCode keeps its OPENCODE_ENABLE_EXA + parallel-flake notes; Codex keeps its prose-instruction dispatch; Gemini keeps @generalist), and install.sh wiring (case-statement per host, swap references SKILL-$DETECTED_HOST.md, catch-all defaults to claude).
  • Modest size reduction (~3% bytes, ~27 lines per variant) — the issue's 15% estimate over-counted because cross-host enumerations were tighter than expected. The disambiguation win is the real value, and the template exists for the next time we add a host (one row in tools/host_config.py + one branch in install.sh).

Test plan

  • python tools/gen_skill_md.py --check exits 0 in a clean tree.
  • pytest tests/test_skill_md_template_generation.py -v — 16/16 pass.
  • pytest tests/ -q full suite — 476/476 pass (was 460 + 16 new).
  • Per-host spot-check: OpenCode variant has task / general / OPENCODE_ENABLE_EXA / sst/opencode#14195; Claude variant has Task / general-purpose and no general standalone; Codex variant explains the prose-instruction dispatch shape; Gemini variant uses @generalist.
  • install.sh path detection traced manually for each canonical install path (claude / codex / gemini / opencode) plus a non-canonical fallback.
  • End-to-end run on a non-Claude host (deferred — Claude Code variant is the only one most cohort users see at install time; the templating system itself is exercised by the test suite).

🤖 Generated with Claude Code

Each AI CLI host (Claude Code / Codex / Gemini / OpenCode) now reads a
SKILL.md that only mentions its own tool names — no cross-host
enumeration. Removes the qwen3.6-35b mis-dispatch class of failure
where the model picked the first listed value (Claude's
`general-purpose`) on a different host and got rejected.

- SKILL.md.tmpl is the source of truth; tools/gen_skill_md.py emits
  SKILL-<host>.md per host plus a default SKILL.md (= claude variant).
- Template engine is minimal: {{var}} + {{#if host}}/{{#unless host}}.
  No Jinja2 dep, ~120 lines of stdlib Python.
- install.sh detects the install path and swaps in the right variant;
  clones to non-canonical paths default to claude.
- tests/test_skill_md_template_generation.py (16 tests) pin drift,
  per-host shape, and install.sh wiring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@earino

earino commented Apr 27, 2026

Copy link
Copy Markdown
Owner Author

Closing per maintainer call. The right move at v0.5 is simplification (tighten SKILL.md while keeping every prescription) rather than templating-on-top-of-redundancy. The qwen failure modes we shipped fixes for in v0.4.4 were all 'prescriptiveness at ambiguity points,' not 'doc length' — and trimming the 250-line telemetry reference + 150-line debugging playbook + 9 expanded Phase 0 question shapes should help weak-model reliability (more of the load-bearing Phase 0–7 content stays inside OpenCode's tool_output cap). Templating can return as v0.6+ if simplification doesn't suffice. Branch feature/issue-55-templated-skill-md and the SKILL.md.tmpl + tools/gen_skill_md.py + per-host SKILL-<host>.md artifacts are preserved on the branch in case we want them back. New issue with the simplification plan: forthcoming.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v0.5: Generate per-host SKILL.md from a template

1 participant