How SKILL.md Files Are Discovered and Executed by the OpenHuman Skill Runtime

The OpenHuman skill runtime discovers SKILL.md bundles by scanning hierarchical filesystem scopes in src/openhuman/skills/ops_discover.rs, enforcing trust via .openhuman/trust markers, and executes them through the run_workflow RPC tool that launches a sandboxed skill_executor agent.

The tinyhumansai/openhuman repository implements a deterministic two-phase pipeline for skill management. The discovery phase locates and validates SKILL.md bundles across multiple filesystem roots, while the execution phase runs the resolved workflows in an isolated agent environment. This architecture ensures that only trusted, non-symlinked skill manifests are loaded and that profile-local skills remain private to their owner.

SKILL.md Discovery Mechanism

The discovery process is orchestrated by src/openhuman/skills/ops_discover.rs, which implements a hierarchical scanner that respects four distinct scopes with defined precedence rules.

Root Categories and Scope Hierarchy

Discovery examines two root kinds—Skill roots and Workflow roots—across four scopes. The enum RootKind, defined in src/openhuman/skills/ops_types.rs, distinguishes these categories, while the WorkflowScope type tracks provenance. The runtime scans in this order:

  • User scope (~/.openhuman/skills/, ~/.agents/skills/) — Always scanned for global user capabilities.
  • Project scope (<workspace>/.openhuman/skills/, <workspace>/.agents/skills/) — Scanned only if the workspace contains the trust marker file .openhuman/trust.
  • Legacy scope (<workspace>/skills/) — Included for backward compatibility when full discovery is requested.
  • Profile-local scope (<workspace>/personalities/<id>/skills) — Optional root passed via discover_workflows_with_profile (lines ≈121-130).

Trust Verification and Security Checks

Before loading project-level skills, the runtime verifies workspace trust via is_workspace_trusted (lines ≈332-337), which checks for the existence of .openhuman/trust. Additionally, is_safe_manifest validates that discovered manifests are regular files—not symlinks—preventing directory traversal attacks.

Collision Resolution and Precedence

When multiple bundles share the same display name or directory slug, the absorb function (lines ≈223-286) merges discovery maps and applies precedence rules. The precedence ladder (lines ≈388-395) ranks scopes as: Legacy < User < Project < Profile. Later-scanned scopes override earlier ones, with warnings logged for discarded entries.

Bundle Loading and Manifest Parsing

Each candidate directory is processed by load_skill_dir (lines ≈438-470), which detects manifests in priority order:

  1. WORKFLOW.md (current format, defined in ops_types.rs)
  2. SKILL.md (legacy markdown format)
  3. SKILL.json (legacy JSON format)

The helper invokes load_from_workflow_md for markdown manifests or load_from_legacy_manifest for JSON, returning a Vec<Workflow> via the public entry point load_workflow_metadata (lines ≈66-71).

Skill Execution Runtime

Once discovered, skills are executed through a secure RPC-mediated pipeline that maintains isolation between the caller and the skill logic.

RPC Tool Registration and Skill Resolution

The run_workflow tool is registered in src/openhuman/skills/runtime/tools.rs. When invoked via JSON-RPC, the runtime resolves the requested skill using load_workflow_metadata_for_profile (lines ≈84-92), ensuring profile-local bundles are honored and that private skills are only accessible by their owner.

The Skill Executor Agent

Resolved workflows execute within the skill_executor agent defined in src/openhuman/skills/runtime/agent/skill_executor/, coordinated by src/openhuman/skills/runtime/run_machinery.rs. This pipeline reads the skill's manifest and resources via read_workflow_resource (lines ≈506-666), streams prompt templates to the LLM, processes tool calls, and returns the final output through the RPC response channel.

Secure Resource Access

The read_workflow_resource function enforces strict sandboxing: it validates symlinks to prevent directory traversal, enforces size limits, and guarantees UTF-8 compliance before returning file contents from the bundle directory.

Practical Code Examples

Listing Discovered Skills

To enumerate available skills while respecting workspace trust boundaries:

use std::path::Path;
use openhuman::skills::ops_discover::{load_workflow_metadata, is_workspace_trusted};

fn list_skills(workspace: &Path) {
    // Projects without .openhuman/trust will only show user-scope skills
    let trusted = is_workspace_trusted(workspace);
    let skills = load_workflow_metadata(workspace);
    for skill in skills {
        println!("✅ {} ({:?}) – {}", skill.name, skill.scope, skill.description);
    }
}

Reading Skill Bundle Resources

Access files within a specific skill bundle using the hardened resource reader:

use std::path::Path;
use openhuman::skills::ops_discover::read_workflow_resource;

fn read_resource(workspace: &Path, skill_id: &str, relative_path: &Path) {
    match read_workflow_resource(workspace, skill_id, relative_path) {
        Ok(content) => println!("📄 {relative_path:?} →\n{content}"),
        Err(err)   => eprintln!("❌ Failed to read resource: {err}"),
    }
}

// Example: Read references/note.md from the "mail-helper" skill
read_resource(&workspace_dir, "mail-helper", Path::new("references/note.md"));

Executing Skills via JSON-RPC

Trigger skill execution through the runtime's RPC interface:

{
  "jsonrpc": "2.0",
  "id": "run-42",
  "method": "openhuman.run_workflow",
  "params": {
    "skill_id": "mail-helper",
    "input": "Fetch the latest unread emails and summarize them."
  }
}

Summary

  • Hierarchical discovery scans User, Project, Legacy, and Profile scopes in src/openhuman/skills/ops_discover.rs, with precedence rules ensuring Profile-local skills override global ones.
  • Trust enforcement requires the .openhuman/trust marker for project-level skills, while is_safe_manifest blocks symlink attacks during manifest loading.
  • Flexible parsing supports WORKFLOW.md, SKILL.md, and SKILL.json formats via load_skill_dir.
  • Secure execution occurs through the run_workflow RPC tool, which resolves skills via load_workflow_metadata_for_profile and isolates execution in the skill_executor agent coordinated by run_machinery.rs.
  • Resource sandboxing via read_workflow_resource prevents unauthorized filesystem access through symlink validation and size constraints.

Frequently Asked Questions

What file names does the OpenHuman runtime recognize for skill manifests?

The runtime recognizes three manifest filenames in priority order: WORKFLOW.md (current standard), SKILL.md (legacy markdown), and SKILL.json (legacy JSON). The load_skill_dir function in src/openhuman/skills/ops_discover.rs checks for these files sequentially and invokes the appropriate parser for each format.

How does OpenHuman prevent unauthorized execution of project-level skills?

The runtime requires a trust marker file—.openhuman/trust—to be present in the workspace root before scanning project-scope skill directories. The is_workspace_trusted function (lines ≈332-337) performs this check, ensuring that untrusted repositories cannot execute arbitrary code from .openhuman/skills/ directories.

What determines which skill bundle takes precedence when names collide?

The absorb function implements a precedence ladder where Profile > Project > User > Legacy. When two bundles share the same display name or directory slug, the bundle from the higher-precedence scope overrides the lower one, with the runtime logging warnings for any discarded duplicate entries.

Can skills access arbitrary files outside their bundle directory?

No. Skills must access resources through the read_workflow_resource helper (lines ≈506-666), which enforces strict sandboxing. This function validates that requested paths are regular files within the bundle directory (not symlinks), enforces size limits, and validates UTF-8 encoding, preventing directory traversal attacks and unauthorized filesystem access.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →