skills/docs/adr/002-skill-manifest-format.md
dan c1f644e6a6 ADRs: add skill manifest, versioning, and trace security designs
- ADR-002: Skill manifest format with JSON Schema, path bases, preconditions
- ADR-003: Versioning with Nix store paths, lockfiles, interface contracts
- ADR-004: Trace security with HMAC redaction, entropy detection, trace modes

Refined based on orch consensus feedback from GPT and Gemini.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:55:18 -05:00

8 KiB

ADR-002: Skill Manifest Format

Status

Draft (Revised)

Context

Skills currently have minimal frontmatter (name, description). For molecule integration, we need skills to declare their interface so:

  • Beads can validate proto→skill bindings before spawning
  • Agents know what inputs to provide
  • Traces can record what was expected vs actual
  • Errors are clear when requirements aren't met

Decision

Extend SKILL.md frontmatter with optional manifest fields. All new fields are optional for backward compatibility.

Proposed Schema

---
manifest_version: "1.0"
name: worklog
description: Create org-mode worklogs documenting work sessions.

# Version info for reproducibility
version: 1.0.0

# What the skill needs to run
inputs:
  required:
    - name: session_date
      description: Date of the session (YYYY-MM-DD)
      schema:
        type: string
        pattern: "^\\d{4}-\\d{2}-\\d{2}$"
  optional:
    - name: topic
      description: Brief topic descriptor for filename
      schema:
        type: string
        default: "session"
    - name: output_dir
      description: Directory for worklog output (relative to repo root)
      schema:
        type: string
        default: "docs/worklogs"
    - name: api_key
      description: API key for external service
      sensitive: true
      schema:
        type: string

# Environment requirements
env:
  required: []
  optional:
    - name: PROJECT
      description: Project name for context
    - name: API_TOKEN
      description: Authentication token
      sensitive: true

# Tools/commands that must be available
preconditions:
  commands:
    - cmd: git
      min_version: "2.40"
    - cmd: date
  files:
    - path: scripts/extract-metrics.sh
      base: skill_root
      description: Metrics extraction script
    - path: templates/worklog-template.org
      base: skill_root
      description: Worklog template

# What the skill produces
outputs:
  files:
    - pattern: "{{output_dir}}/{{session_date}}-{{topic}}.org"
      base: repo_root
      description: The generated worklog file
  artifacts: []

# Execution characteristics (hints for scheduling, not enforcement)
execution:
  idempotent: false          # Safe to re-run?
  destructive: false         # Modifies existing files?
  network: false             # Requires network access?
  interactive: false         # Requires user input during execution?
  timeout: 30                # Maximum execution time in seconds

# For security classification
sensitive: false             # Handles sensitive data?
---

Field Definitions

manifest_version

Schema version for the manifest format itself. Allows parsers to handle breaking changes.

  • Current version: "1.0"
  • Semantic versioning: major version changes indicate breaking schema changes

inputs

Declares what the skill needs from the caller. Uses JSON Schema subset for type definitions.

  • required: Must be provided or skill fails
  • optional: Has defaults, can be overridden
  • Each input has: name, description, schema (JSON Schema), optional sensitive flag
  • sensitive: true: Mark inputs for redaction in traces

JSON Schema Subset Supported:

  • type: string, number, integer, boolean, array, object
  • pattern: regex for string validation
  • minimum, maximum: numeric bounds
  • items: array item schema
  • properties: object property schemas
  • default: default value
  • enum: allowed values

env

Environment variables the skill reads.

  • required: Skill fails if not set
  • optional: Used if available, not fatal if missing
  • sensitive: true: Mark for redaction

preconditions

What must exist before skill can run.

  • commands: CLI tools that must be in PATH
    • cmd: command name (required)
    • min_version: minimum version (optional, e.g., "2.40")
    • max_version: maximum version (optional)
  • files: Files that must exist
    • path: relative path (required)
    • base: path base - skill_root, repo_root, or cwd (default: skill_root)
    • description: what this file is for (optional)

Path Resolution:

  • skill_root: Directory containing SKILL.md
  • repo_root: Git repository root
  • cwd: Current working directory
  • Absolute paths (starting with / or ~) are forbidden

outputs

What the skill produces.

  • files: File patterns with {{var}} substitution
    • pattern: file path pattern
    • base: path base (default: repo_root)
    • description: what this output is for
  • artifacts: Other outputs (stdout, state changes, etc.)

execution

Characteristics for scheduling and safety. These are hints, not enforcement.

  • idempotent: Can run multiple times safely
  • destructive: Modifies or deletes existing data
  • network: Requires internet access
  • interactive: Needs human input during run
  • timeout: Maximum execution time in seconds

The runtime may use these hints to:

  • Schedule non-destructive skills in parallel
  • Warn before running destructive operations
  • Set execution timeouts

These flags do NOT enforce sandboxing or isolation.

sensitive

Whether skill handles sensitive data.

  • false (default): Standard tracing, eligible for elevation
  • true: Aggressive redaction, elevation blocked without review

Validation Rules

When beads spawns a molecule with skill: reference:

  1. Check skill exists
  2. Verify manifest_version is supported
  3. Validate all required inputs are mapped
  4. Validate input schemas using JSON Schema
  5. Check preconditions (commands with versions, files)
  6. Check required env vars are set
  7. Warn if optional inputs have no mapping
  8. Apply redaction rules for sensitive fields

Backward Compatibility

  • All new fields are optional
  • Skills with only name/description continue to work
  • Missing manifest = no validation (current behavior)
  • Missing manifest_version = assume legacy format

Consequences

Positive

  • Clear contracts between molecules and skills
  • Better error messages (fail before execution, not during)
  • JSON Schema provides standard, well-understood type system
  • Sensitive data handling built into manifest
  • Version constraints prevent runtime errors
  • Explicit path resolution prevents portability issues

Negative

  • More frontmatter to maintain
  • Risk of manifest drift from actual behavior
  • JSON Schema subset may not cover all validation needs

Neutral

  • Existing skills unaffected until they opt-in
  • Execution flags are hints, not enforcement

Examples

Minimal (current, still valid)

---
name: simple-skill
description: Does something simple
---

With inputs only

---
manifest_version: "1.0"
name: greeter
description: Greets the user
inputs:
  required:
    - name: username
      description: Name of the user to greet
      schema:
        type: string
---

With sensitive data

---
manifest_version: "1.0"
name: deploy
description: Deploy application to production
inputs:
  required:
    - name: deploy_key
      description: SSH deployment key
      sensitive: true
      schema:
        type: string
env:
  required:
    - name: DEPLOY_TOKEN
      description: Authentication token
      sensitive: true
execution:
  network: true
  destructive: true
  timeout: 300
sensitive: true
---

With version constraints

---
manifest_version: "1.0"
name: analyze-git
description: Analyze git repository history
preconditions:
  commands:
    - cmd: git
      min_version: "2.40"
    - cmd: python3
      min_version: "3.11"
  files:
    - path: scripts/analyze.py
      base: skill_root
inputs:
  optional:
    - name: since
      description: Analyze commits since this date
      schema:
        type: string
        pattern: "^\\d{4}-\\d{2}-\\d{2}$"
        default: "2025-01-01"
outputs:
  files:
    - pattern: "reports/git-analysis-{{since}}.md"
      base: repo_root
execution:
  idempotent: true
  timeout: 60
---

Open Questions

  1. Should outputs be validated after execution?
  2. How to handle skills that produce variable outputs?
  3. Should we allow custom JSON Schema extensions?
  4. Where does skill version come from - git tag, manual, or derived?