# skills.md The skill system and the bundled default skills: discovery contract, frontmatter subset, the six shipped skills with their upstream provenance and tai adaptations, install semantics, and maintenance. ## The system Skills are directories containing a `SKILL.md` file with `name` plus `description` frontmatter, optionally with `scripts/`, `references/`, and `assets/` alongside (the open Agent Skills layout). Discovery (`discover_skills`) scans four roots and the most tai-specific one wins a name collision: `~/.claude/skills` and `/.claude/skills` / `/.agents/skills` first (external, read-only interop), then `~/.tai/skills` and `/.tai/skills` (managed). `load_skill` returns the body plus a provenance note plus the absolute paths of the top-level entries under `scripts/`, `references/`, and `assets/` (`skill_extra_files`, not recursive: a nested directory shows up as its own path and the agent descends from there). Descriptions ride the system-prompt catalog truncated to 300 characters; bodies load on demand. Frontmatter is a deliberate subset, not YAML (`parse_skill_front`): one `key: value` per line, double-quoted values have their outer quotes stripped, unknown keys are ignored, and only bare `>` (fold with spaces) and `|` (join with newlines) continue a value onto indented lines. Chomping variants (`>-`, `|-`, `>+`, `|+`) do NOT parse: a `>-` description reads back as the literal string `">-"` and the folded lines are dropped. Shipped skills must use single-line descriptions. Missing skills with a `SKILL_BLUEPRINTS` entry are researched and built on first `load_skill` (`bot-creator`, `api-client`, `web-researcher`, `pdf-forms`, `data-wrangler`, `home-sysadmin`); anything else is an "unknown skill" error listing what exists. ## Bundled skills Six skills ship inside `tai.py` itself (`BUNDLED_SKILLS`, 21 files) so a bare copy installs them anywhere. Upstream provenance per skill lives in `BUNDLED_SKILL_UPSTREAM` and is copied into each installed sidecar. | Skill | Files | Upstream | Status | |---|---|---|---| | `deep-research` | 6 (`SKILL.md`, 4 `references/`, `UPSTREAM.md`) | author's Muse user skill (itself from `wanqingying/debian-railway`, see `UPSTREAM.md`) | adapted | | `seriousdevelopment` | 10 (`SKILL.md`, `CHANGELOG.md`, 8 `assets/templates/`) | author's Muse user skill v1.7.1 | verbatim | | `git` | 2 (`SKILL.md`, `scripts/workspace-recovery.sh`) | Muse's bundled set | adapted | | `plan` | 1 (`SKILL.md`) | Muse's bundled set | adapted | | `requirements-clarification` | 1 (`SKILL.md`) | Muse's bundled set | adapted | | `taste` | 1 (`SKILL.md`) | Muse's bundled set | one word | `seriousdevelopment` is byte-identical to upstream: it carries no host references and no em dashes. Everything else changed only where the host leaks through; the method prose is untouched. ## Adaptation rules Each rule below was applied everywhere its token appeared, and `BundledSkillsTests.test_embedded_content_guards` fails if any of them regresses: | Upstream token | Tai equivalent | Why | |---|---|---| | `read_skill` | `load_skill` | tai's loader is named `load_skill` | | `request_user_input` / `request_user_input_async` (+ `auto_resolution_ms`) | `ask_user` (question plus options, blocks; unavailable to workers and autonomous mode, decide and state the assumption there) | tai's only question tool blocks and has no async form | | subagent / `Task` / `explore` workers, wait-call mechanics | `fork` (task plus timeout up to one hour) / `poll` (up to two minutes per call, loop until done); workers get 12 steps, no questions, nesting depth 2, 8 live max | tai's orchestration primitives and their real caps | | `curl` recipes, `curl` commands | `web_fetch` GET with the same URL and headers | tai forbids curl and wget via shell; every recipe is a plain GET so nothing is lost (`auth_secret` covers the token case) | | `webfetch` / `websearch` | `web_fetch` / `web_search` | tai's tool names | | `/plan`, `/skill plan` | prose request or `load_skill` | tai has no slash-command skill routes | | `>-` folded description | single-line description | the frontmatter subset (above) | | em dash (U+2014) | hyphen | project prose rule, no exceptions | Two judgment calls beyond mechanical mapping: - `git` got an "Authorization in tai" paragraph: its never-commit rule would otherwise veto the user's standing auto-commit rule, so history writes follow the session's approval setting while the recovery snapshot, lock discipline, and named-files rules still apply as written. The `` placeholder became ``, bound to the absolute script path from the bundled-files list. - `deep-research` briefs still hand workers literal URLs even though tai workers could read the skill directory: inline URLs keep briefs self-contained under the 12-step budget. ## Install target `skills` is the twelfth `INSTALL_TARGETS` entry, implemented by `op_skills` on top of `write_bundled_skill` / `remove_bundled_skill`, included in bare `./tai.py --install` and refreshable via the `install` tool or `/install`. All six land in home scope (`~/.tai/skills`); project scope never receives bundled skills. After any non-status action through the tool, the live session re-runs discovery so the skills are usable without a restart. | Action | Semantics | |---|---| | `install` | writes missing skills only; a present `SKILL.md` means "already present", never an overwrite | | `upgrade` | rewrites files that are missing or already equal; differing files are kept untouched and named loudly (`kept modified`) | | `reinstall` | force-rewrites every tracked file, including user edits; user-added extra files still survive | | `uninstall` | removes tracked files that still match (plus orphan sidecars); user-modified and user-added files stay, named loudly, with their sidecar | | `status` | one line: `skills: P/6 bundled present`, plus `missing:` and `modified:` lists when non-empty | The `.installs/.json` sidecar records `source: tai-bundled`, `mode: bundled`, `scope: home`, the `upstream` locator, the `bundled_version` that wrote it, per-file sha8 `files`, and `installed_at`. `load_skill` renders this as `[installed bundled, home scope, from tai-bundled]`. The sidecar is rewritten only when a write leaves zero kept files, so user edits are never re-baselined as pristine behind their back. ## Maintenance The embedded copies ARE the source: fix typos and drift directly in `BUNDLED_SKILLS`, never by re-copying upstream over them (re-copying would silently drop the adaptations above). To pull a new upstream version of one skill: diff upstream against the embedded copy, re-apply the adaptation rules to the new text, re-embed, and confirm the guard test plus a fresh install round-trip. Raw strings keep backslashes byte-exact, so no embedded file may contain a triple-double-quote or end in a backslash; the guard test enforces the quote half.