feat(skills): extract ironclaw_skills crate and integrate with v2 engine

Extract the skills system into a standalone `ironclaw_skills` crate
(following the ironclaw_safety pattern) and wire it into the v2 engine
for deterministic skill selection, CodeAct code injection, and
confidence tracking.

**ironclaw_skills crate** (94 tests):
- Core types: SkillManifest, ActivationCriteria, LoadedSkill, SkillTrust
- V2 types: V2SkillMetadata, CodeSnippet, SkillMetrics, V2SkillSource
- Deterministic 4-phase selector (gating→scoring→budget→attenuation)
- apply_confidence_factor() for extracted skill scoring
- SKILL.md parser, validation/escaping, gating, registry, catalog
- Feature-gated: catalog (reqwest), registry (filesystem)

**Engine integration** (14 new tests):
- DocType::Skill with retrieval weight 0.45
- SkillSelector bridges MemoryDoc→LoadedSkill for shared scoring
- SkillTracker for usage/version/rollback confidence tracking
- System prompt injection via <skill> XML blocks
- CodeAct snippet injection via Monty NameLookup
- Skill extraction mission replaces playbook extraction
- ThreadManager.set_skill_selector() for runtime wiring

**Bridge + migration**:
- skill_migration.rs: v1 SKILL.md → v2 MemoryDoc (idempotent)
- init_engine() migrates v1 skills, builds SkillSelector
- src/skills/mod.rs → re-export shim

**E2E test** (tests/engine_v2_skill_codeact.rs):
- Full CodeAct loop: skill selected → LLM returns Python code →
  Monty executes http() → mock returns canned GitHub JSON →
  FINAL() terminates → thread completes with canned data
- GitHub SKILL.md in skills/github/ as reference implementation

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
2026-03-27 16:24:07 -07:00
co-authored by Claude Opus 4.6
parent a4f5c56d06
commit 8e2349d12e
33 changed files with 2780 additions and 575 deletions
+103
View File
@@ -0,0 +1,103 @@
---
name: github
version: "1.0.0"
description: GitHub API integration via HTTP tool with automatic credential injection
activation:
keywords:
- "github"
- "issues"
- "pull request"
- "repository"
- "commit"
- "branch"
exclude_keywords:
- "gitlab"
- "bitbucket"
patterns:
- "(?i)(list|show|get|fetch|open|close|create|file|merge)\\s.*(issue|PR|pull request|repo)"
- "(?i)github\\.com"
tags:
- "git"
- "code-review"
- "devops"
max_context_tokens: 2000
---
# GitHub API Skill
You have access to the GitHub REST API via the `http` tool. Credentials are automatically injected — **never construct Authorization headers manually**. When the URL host is `api.github.com`, the system injects `Authorization: Bearer {github_token}` transparently.
## API Patterns
All endpoints use `https://api.github.com` as the base URL. Common headers are injected automatically.
### Issues
**List issues:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}/issues?state=open&sort=created&direction=desc&per_page=30")
```
**Get single issue:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}/issues/{number}")
```
**Create issue:**
```
http(method="POST", url="https://api.github.com/repos/{owner}/{repo}/issues", body={"title": "...", "body": "...", "labels": ["bug"]})
```
**Add comment:**
```
http(method="POST", url="https://api.github.com/repos/{owner}/{repo}/issues/{number}/comments", body={"body": "..."})
```
### Pull Requests
**List PRs:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}/pulls?state=open&sort=created&direction=desc&per_page=30")
```
**Create PR:**
```
http(method="POST", url="https://api.github.com/repos/{owner}/{repo}/pulls", body={"title": "...", "body": "...", "head": "feature-branch", "base": "main", "draft": true})
```
**Get PR diff:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}/pulls/{number}", headers=[{"name": "Accept", "value": "application/vnd.github.v3.diff"}])
```
### Repository
**Get repo info:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}")
```
**List branches:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}/branches")
```
**List recent commits:**
```
http(method="GET", url="https://api.github.com/repos/{owner}/{repo}/commits?per_page=10")
```
## Response Handling
- GitHub returns JSON. Parse the response to extract relevant fields.
- For list endpoints, check the `Link` header for pagination.
- Rate limit: 5000 req/hour authenticated. Check `X-RateLimit-Remaining` header if doing bulk operations.
- Errors return `{"message": "..."}` — always check for error responses.
## Common Mistakes
- Do NOT add an `Authorization` header — it is injected automatically by the credential system.
- Always use HTTPS URLs (HTTP is blocked by the security layer).
- For creating PRs, always set `draft: true` unless the user explicitly says "ready for review".
- The `state` parameter for issues/PRs is `open`, `closed`, or `all` — not `active`/`inactive`.
- Use `per_page` to control result count (max 100). Default is 30.