Files
goclaw/docs/16-skill-publishing.md
T
Viet Tran 037d18f711 docs: comprehensive audit and update of all documentation (#231)
* feat(ui): improve kanban UX, fix dialog scroll, remove delegation page

- Kanban: reorder columns (blocked after pending), show blocked-by info
  on cards, clickable blocker links in task detail, framer-motion card
  animation between columns
- Dialogs: standardize scroll pattern across all modals — header fixed,
  scrollbar flush with outer edge via negative margin trick
- Remove delegation page, types, events, i18n, routes, and all references
- Fix activity_logs NULL jsonb scan error (COALESCE)
- Board header: show text labels on action buttons (desktop)

* docs: comprehensive audit and update of all documentation

- Update Go 1.25 → 1.26, PostgreSQL 15+ → 18 across all docs
- Add 10 missing internal modules to CLAUDE.md project structure
- Expand provider docs from 2 to 6 packages (Anthropic, OpenAI, DashScope, Claude CLI, ACP, Codex)
- Add 8 missing store interfaces to data model docs (22 total)
- Update bootstrap files from 7 to 13 templates
- Expand tool inventory from ~35 to 60+ tools with media/KG/credential categories
- Fix Team Task Board: add blocked status, 3 missing actions, V2 versioning, delegate restrictions
- Remove all references to removed features: handoff, delegate_search, evaluate_loop, agent_links
- Fix lane defaults (2/4/1 → 30/50/100/30), ghost file references, models.list → providers.models
- Add SecureCLI, snapshot worker, cost calculation, pairing security docs
- Comprehensive changelog catch-up
- Trim docs/03-tools-system.md to 800-line limit
2026-03-16 22:51:57 +07:00

12 KiB

16 - Skill Publishing System

How agents create, register, and manage skills programmatically through the publish_skill builtin tool, working in tandem with the skill-creator core skill.


1. Overview

The skill publishing system bridges the gap between skill creation (filesystem) and skill management (database). It consists of two components:

Component Type Purpose
skill-creator Core skill (bundled) Guides agents through skill design, implementation, testing, and optimization
publish_skill Builtin tool Registers a skill directory in the database, copies files to managed store, auto-grants to creating agent

Without publish_skill, skills created by agents exist only on the filesystem and are invisible to the database-backed skill management system (no search, no grants, no UI visibility).


2. End-to-End Flow

Agent receives request to create a skill
    │
    ▼
┌─────────────────────────────────────┐
│  1. skill-creator skill activated   │
│     Agent reads SKILL.md guidance   │
│     Creates files via write_file:   │
│       skills/my-skill/SKILL.md      │
│       skills/my-skill/scripts/      │
│       skills/my-skill/references/   │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  2. publish_skill tool called       │
│     publish_skill(path: "skills/    │
│       my-skill")                    │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────────┐
│  3. Tool executes:                                  │
│     a. Validate SKILL.md + parse frontmatter        │
│     b. Derive slug, validate format                 │
│     c. Check system skill conflict                  │
│     d. Compute SHA-256 hash                         │
│     e. Copy dir → skills-store/{slug}/{version}/    │
│     f. INSERT/UPSERT into skills table              │
│     g. Auto-grant to calling agent                  │
│     h. Scan + report missing dependencies           │
│     i. Bump loader cache version                    │
│     j. Generate embedding (async)                   │
└──────────────┬──────────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  4. Result returned to agent:       │
│     - Skill ID, slug, version       │
│     - Grant confirmation            │
│     - Dep warnings (if any)         │
└─────────────────────────────────────┘

3. publish_skill Tool

Parameters

Parameter Type Required Default Description
path string yes - Path to skill directory containing SKILL.md (absolute or relative to workspace)

Activation Conditions

The tool is registered at gateway startup when:

  1. pgStores.Skills is available (PostgreSQL skill store initialized)
  2. PGSkillStore has at least one managed directory (skills-store/)
  3. Skills loader is initialized

The tool appears in every agent's tool set — no per-agent configuration needed. Can be toggled via the builtin tools admin UI.

Context Values Used

Context Key Source Purpose
store.UserIDFromContext(ctx) WS connect / HTTP header Skill owner + grant source
store.AgentIDFromContext(ctx) Agent loop Agent to auto-grant access to
ToolWorkspaceFromCtx(ctx) Tool registry Resolve relative paths

SKILL.md Frontmatter Requirements

---
name: my-skill-name          # REQUIRED — display name
description: What it does     # Recommended — used for search + auto-activation
slug: my-skill-name           # Optional — derived from name if absent
---
  • name is mandatory; tool returns error if missing
  • slug auto-derived via Slugify(name) if not specified
  • Slug must match ^[a-z0-9][a-z0-9-]*[a-z0-9]$

4. Core Logic Details

4.1 Slug Validation

name: "My Awesome Skill"
  → Slugify → "my-awesome-skill"
  → SlugRegexp check → ✓ valid

Rejects: leading/trailing hyphens, uppercase, special chars, spaces.

4.2 System Skill Conflict Check

Prevents overwriting bundled skills (pdf, xlsx, docx, pptx, skill-creator, etc.):

if t.skills.IsSystemSkill(slug) {
    return ErrorResult("slug conflicts with a system skill")
}

4.3 Versioned Storage

Skills are stored in versioned directories. Re-publishing the same slug increments the version:

skills-store/
├── my-skill/
│   ├── 1/
│   │   ├── SKILL.md
│   │   └── scripts/
│   └── 2/          ← re-publish creates new version
│       ├── SKILL.md
│       └── scripts/

GetNextVersion(slug) queries MAX(version) from the skills table (includes archived skills).

4.4 Database Upsert

Uses CreateSkillManaged() with ON CONFLICT(slug) DO UPDATE:

  • New slug → INSERT with visibility = 'private'
  • Existing slug → UPDATE name, description, version, file_path, file_hash
  • Archived skill re-published → status reset to 'active'
  • Embedding generated asynchronously after insert/update

4.5 Auto-Grant

When the calling agent has a valid AgentID in context:

GrantToAgent(ctx, skillID, agentID, version, userID)

This also auto-promotes skill visibility from privateinternal, making it accessible via ListAccessible() for the granted agent.

4.6 Dependency Scanning

After publishing, the tool runs static analysis on the skill's scripts/ directory:

  1. ScanSkillDeps — detects required binaries, Python imports, Node packages
  2. CheckSkillDeps — verifies each dependency is available on the system
  3. If missing deps found:
    • Stored in deps JSONB column via StoreMissingDeps()
    • Warning returned to agent with specific missing packages
    • Agent is guided to install via exec (pip/npm) or inform the user

Unlike the HTTP upload handler, the tool does not archive the skill on missing deps — it warns and lets the agent decide.

4.7 Directory Copy Security

Check Action
.. in relative path Skip (prevent traversal)
Symlinks Skip (prevent escape)
System artifacts Skip (.DS_Store, __MACOSX, Thumbs.db, etc.)
Total dir size > 20 MB Reject with error

5. skill-creator Skill

Activation Triggers

The skill-creator is a bundled system skill with a "pushy" description that triggers on:

  • Creating new skills or extending agent capabilities
  • Skill scripts, references, benchmark optimization
  • Description optimization and eval testing

Creation Workflow

  1. Capture Intent — what, when, output
  2. Research — best practices via docs-seeker
  3. Plan — identify scripts, references, assets
  4. Initializescripts/init_skill.py <name> --path <dir>
  5. Write — implement SKILL.md + resources
  6. Test & Evaluate — eval suite with parallel runs
  7. Optimize Description — AI-powered trigger optimization
  8. Publishpublish_skill(path: "skills/<name>")
  9. Package (optional) — ZIP for external distribution
  10. Iterate — refine from feedback

Skill File Structure

skills/<skill-name>/
├── SKILL.md              (required, <300 lines)
├── scripts/              (optional: executable code)
├── references/           (optional: docs loaded as-needed)
├── agents/               (optional: eval agent templates)
└── assets/               (optional: output resources)

Key Constraints

Resource Limit
Description ≤1024 chars
SKILL.md <300 lines
Each reference <300 lines
Scripts No limit (executed, not loaded into context)

6. Database Schema

skills table (relevant columns)

Column Type Purpose
id UUID Primary key
slug VARCHAR(255) UNIQUE Canonical identifier
name VARCHAR(255) Display name
description TEXT Auto-activation trigger text
owner_id VARCHAR(255) User who created (or "system")
visibility VARCHAR(10) privateinternal (on grant) → public
version INT Increments on re-publish
status VARCHAR(20) active or archived
is_system BOOLEAN True for bundled skills
enabled BOOLEAN Admin toggle
file_path TEXT Filesystem path to versioned dir
file_hash VARCHAR(64) SHA-256 of SKILL.md
deps JSONB {"missing": ["pip:opencv", "python3"]}
frontmatter JSONB Parsed YAML metadata
embedding vector(1536) pgvector for similarity search

skill_agent_grants table

Column Type Purpose
skill_id UUID FK References skills
agent_id UUID FK References agents
pinned_version INT Stored but not used — agent always uses latest
granted_by VARCHAR User who granted

7. Visibility & Access Model

publish_skill creates with visibility = "private"
        │
        ▼
GrantToAgent auto-promotes → "internal"
        │
        ▼
ListAccessible query includes:
  - is_system = true          (all system skills)
  - visibility = 'public'     (anyone)
  - visibility = 'private'    (owner only)
  - visibility = 'internal'   (agents/users with grants)

Revoking the last grant auto-demotes internalprivate (atomic SQL).


8. Cache Invalidation

After publishing, two caches are bumped:

  1. PGSkillStore cacheBumpVersion() sets version = time.Now().UnixMilli(), invalidating the ListSkills() cache (TTL 5min + version check)
  2. Skills Loader cacheloader.BumpVersion() invalidates the filesystem-based skill index used for system prompt injection

Next agent turn picks up the new skill in its tool set.


File Purpose
internal/tools/publish_skill.go Tool implementation
internal/skills/helpers.go Shared helpers: ParseSkillFrontmatter, Slugify, IsSystemArtifact, SlugRegexp
internal/store/pg/skills_crud.go DB operations: CreateSkillManaged, GetNextVersion, StoreMissingDeps
internal/store/pg/skills_admin.go Admin operations: IsSystemSkill
internal/store/pg/skills_grants.go GrantToAgent, RevokeFromAgent, ListAccessible
internal/skills/loader.go Filesystem skill loader with priority hierarchy
internal/skills/seeder.go System skill seeder (bundled → DB)
internal/skills/dep_scanner.go Static analysis for skill dependencies
internal/skills/dep_checker.go Runtime dependency verification
internal/http/skills_upload.go HTTP ZIP upload handler (alternative to publish_skill)
cmd/gateway.go Tool registration and gateway initialization
cmd/gateway_builtin_tools.go Builtin tool seed data
skills/skill-creator/SKILL.md Core skill instructions