Skip to main content

SkillFS

SkillFS is a FUSE-based virtual filesystem for agent skills. It maps a physical skill source tree into a stable runtime view, compiles SKILL.md on read, and keeps ordinary files backed by the source tree.

SkillFS does not make business-level security decisions. External components such as agent-sec-core or Skill Ledger scan skills and write activation state. SkillFS consumes that state and exposes each skill as live, fallback snapshot, or hidden.

When to Use It

Use SkillFS when you need:

  • a stable mount path for agents;
  • separation between the source workspace and the agent-visible view;
  • default-view filtering plus skill-discover for secondary skills;
  • in-place policy and audit coverage for production access;
  • Skill Ledger integration for fallback and hidden runtime views;
  • .skill-meta protection from ordinary agent processes.

Do not in-place mount an existing hub workspace directly when that workspace also contains registry metadata such as .hub directories or external manifests. Keep the hub workspace and the clean SkillFS source root separate.

Requirements

RequirementDetails
OSLinux for FUSE mounts
FUSEFUSE3 (libfuse3-dev, fuse3, or equivalent)
Device/dev/fuse must be available
Rust1.86+ for source builds

macOS can run non-FUSE commands such as validate, list, and classify, but it cannot mount SkillFS.

Installation

# Recommended package install
anolisa install skillfs

# Source build for developers
cd src/skillfs
cargo +1.86.0 build --release

Source Layout

SkillFS expects a source directory with one skill per child directory:

/path/to/skills/
demo-weather/
SKILL.md
scripts/
run.sh
demo-search/
SKILL.md
config.json

The directory name is the canonical runtime skill id. The name field inside SKILL.md is display metadata and does not override the directory key.

Do not treat .skill-meta as ordinary agent data. It stores SkillFS and ledger metadata and is hidden from ordinary callers.

Quick Start

# Validate skills in a source directory
skillfs validate /path/to/skills

# List all skills
skillfs list /path/to/skills

# Generate skillfs-views.toml
skillfs classify /path/to/skills

# Mount the virtual filesystem
skillfs mount /path/to/skills /mnt/skillfs --foreground

After a normal mount, agents read:

/mnt/skillfs/skills/<skill-name>/SKILL.md

Unmount a foreground test mount with Ctrl+C or:

fusermount3 -u /mnt/skillfs

Mount Layouts

Normal Mount

Normal mount uses different source and mountpoint directories:

skillfs mount /path/to/skills /mnt/skillfs --foreground

Agents access skills under <MOUNTPOINT>/skills. Direct writes to the source directory bypass SkillFS policy and audit, while writes through the mount pass through to the source tree.

Use normal mount for local development, compatibility checks, and environments where the source workspace is managed by another process.

In-place Mount

In-place mount uses the same directory for source and mountpoint:

skillfs mount /path/to/skills /path/to/skills \
--foreground \
--security-mode \
--audit-log /var/log/skillfs/audit.jsonl

SkillFS over-mounts the source directory, so normal userspace access goes through FUSE policy and audit. In-place mounts do not add a /skills layer:

/path/to/skills/<skill-name>/SKILL.md

Use in-place mount for production security integration. Tools that replace or rename the mountpoint directory itself, such as workspace checkpoint or rollback tools, must run before mounting or after unmounting.

Managed Mount

--managed starts a detached supervisor that keeps the mount desired state as mounted and remounts after unexpected worker exits:

skillfs mount /path/to/skills /mnt/skillfs --managed
skillfs stop /mnt/skillfs

skillfs stop <MOUNTPOINT> clears desired state, terminates the supervisor and worker, and unmounts. It is idempotent and safe to run when the mount is already stopped.

Managed mode also detects stale or dead FUSE endpoints after unexpected worker termination, clears them, and remounts with bounded recovery retries. Default foreground mounts are unchanged: they still exit and unmount on SIGTERM or Ctrl+C.

CLI Utilities

validate

skillfs validate /path/to/skills
skillfs validate /path/to/skills --format json

validate reports successful, degraded, and failed skill parses. Parse failures are included in the status summary and produce a non-zero exit code; degraded-only skills are reported but keep exit code 0.

In JSON output, error and warning entries include a path field so consumers can locate the exact offending skill file.

list and classify

skillfs list /path/to/skills
skillfs list /path/to/skills --enabled-only
skillfs classify /path/to/skills --primary-count 6
skillfs classify /path/to/skills --dry-run

list reports discovered skills and metadata. classify generates or previews skillfs-views.toml; the first N skills go to the default view and the rest go to a secondary view.

Views and Discovery

skillfs-views.toml in the source directory controls visibility:

[[view]]
name = "major"
default = true
description = "Core skills shown directly in /skills"
skills = ["github", "notion", "slack"]

[[view]]
name = "other"
default = false
description = "Additional skills accessible through skill-discover"
skills = ["apple-notes", "blogwatcher"]

The default view appears directly in the mounted skill view. Secondary views are listed by the virtual skill-discover skill, whose SKILL.md includes the skill names and source paths.

Skills not assigned to any view are added to the default view on the next mount.

Read and Write Semantics

OperationBehavior
readdirControlled by views and runtime activation state
Read SKILL.mdReturns compiled content, not raw source text
Read ordinary filesPasses through to the physical source tree
Write SKILL.mdWrites through and reparses the store
Write ordinary filesWrites through without changing skill metadata
Rename skill directoryUses the directory name as the authoritative key
Symlink or hardlinkRestricted to safe same-skill relative targets
user.* xattrConservative passthrough on ordinary paths

In-place authoring supports newly created skill directories. A fresh directory does not expose a phantom SKILL.md before the manifest exists; once SKILL.md is written, SkillFS reparses it and exposes the compiled view. Pending or direct-final installs can preserve ordinary top-level skill directory metadata such as mode, timestamps, and ownership. .skill-meta/** remains restricted to trusted metadata paths.

Without security integration, skills read from the live source tree. When security activation is enabled, visibility is constrained by the active mapping:

  • current: read from the live source tree, for example through the legacy decision-command resolve path;
  • fallback: read from a trusted snapshot under .skill-meta;
  • hidden: hide the skill from ordinary callers.

In activation file mode, activation JSON expresses fallback and hidden states. It does not write current/live state. If a skill has no activation JSON or activation xattr in this mode, SkillFS treats it as hidden by fail-safe default.

Security Integration

Activation File Mode

Use activation file mode when an external daemon receives SkillFS mutation events, scans the source tree, and writes activation metadata:

skillfs mount /path/to/skills /mnt/skillfs \
--foreground \
--security \
--activation-mode file \
--notify-socket /run/skill-ledger.sock \
--activation-events-log /var/log/skillfs/activation-events.jsonl \
--activation-reload-mode poll

Flow:

Agent or installer writes through SkillFS
-> SkillFS sends a notify event
-> Skill Ledger scans and writes activation state
-> SkillFS reloads activation state
-> the skill becomes live, fallback, or hidden

--activation-reload-mode poll requires --notify-socket or --activation-events-log, because SkillFS needs a trigger source for polling.

For in-place activation and notify mounts, set --ledger-backing-root to a daemon-visible backing source path:

skillfs mount /path/to/skills /path/to/skills \
--security-mode \
--security \
--activation-mode file \
--notify-socket /run/skill-ledger.sock \
--ledger-backing-root /run/user/$UID/skillfs-ledger/source

Avoid /tmp and /var/tmp for daemon integration paths when the daemon runs with PrivateTmp=true; those paths are invisible to the daemon and rejected by startup validation.

Control Socket

The trusted control socket is the preferred production path for activation writes:

skillfs mount /path/to/skills /mnt/skillfs \
--security \
--activation-mode file \
--control-socket /run/skillfs/control.sock \
--trusted-peer-exe /usr/bin/skill-ledger

The socket requires --security --activation-mode file, is mutually exclusive with --decision-command, and requires a pinned trusted peer executable. Peer validation uses Linux peer credentials and executable identity checks.

Supported JSONL request examples:

{"schemaVersion":"1","method":"ping"}
{"schemaVersion":"1","method":"status"}
{"schemaVersion":"1","method":"meta.writeActivation","skillName":"demo-weather","activation":{"schemaVersion":1,"target":null}}
{"schemaVersion":"1","method":"meta.setActivationXattr","skillName":"demo-weather","activation":{"schemaVersion":1,"target":null}}

Trusted Mount-path Writer

--trusted-writer-exe <PATH> is a compatibility gate for trusted writers that write through the mount path. Prefer the control socket for new production integrations.

--trusted-writer <NAME> is deprecated and only matches the Linux process comm name. Use executable identity when compatibility allows it.

Decision-command Mode

--security --decision-command <COMMAND> is the legacy compatibility path. SkillFS invokes the external command for scan and resolve decisions.

Decision-command mode is mutually exclusive with activation file mode, --notify-socket, --activation-events-log, --ledger-backing-root, and --control-socket.

Install Protocols

SkillFS supports installer-friendly lifecycle paths:

  • staging roots can be hidden from ordinary listing while exact staging paths remain writable;
  • direct-to-final installs can remain hidden until activation appears;
  • /.skillfs-inbox/<skill>/... is an install or repair entry point for hidden or new skills; writes land in the source tree and can trigger the external security flow;
  • quiet-timeout notification can aggregate install mutations after a configured quiet window;
  • post-publish grace can allow bounded installer metadata writes after publish;
  • post-publish grace paths for fallback skills are routed to the live source so installers can finish metadata updates after publish.

These behaviors are configured through the SkillFS TOML config and require a notify source such as --notify-socket or --activation-events-log.

Observability

Audit and Activation Logs

--audit-log <PATH> writes filesystem audit events as JSONL. --activation-events-log <PATH> writes activation protocol events as JSONL for daemon-driven activation flows.

SLS Ops and Runtime Metrics

SkillFS writes best-effort SLS records to:

/var/log/anolisa/sls/ops/skillfs.jsonl

The file is owned and pre-created by the deployment/SLS component. SkillFS only appends when the file exists; it never creates the file or parent directory, and write failures do not change CLI or FUSE behavior.

The following CLI commands append ops records: mount, list, validate, and classify. While a mount is alive, runtime metric records use record_type = "runtime_metric" and include mount lifecycle, view pruning, skill hits, and security policy outcomes. The legacy mount-session summary shares the same file for compatibility.

Common Options

OptionPurpose
--foregroundRun in the foreground
--managedStart a detached supervised mount
--security-modeRequire source and mountpoint to be the same path
--securityEnable security integration
--activation-mode fileConsume activation JSON/xattr state
--activation-reload-mode pollPoll activation after notify triggers
--notify-socket <PATH>Send mutation events to an external daemon
--activation-events-log <PATH>Write activation protocol events as JSONL
--audit-log <PATH>Write filesystem audit events as JSONL
--control-socket <PATH>Accept trusted activation write requests
--trusted-peer-exe <PATH>Pin the trusted control socket peer
--trusted-writer-exe <PATH>Pin a trusted mount-path writer
--ledger-backing-root <PATH>Provide a daemon-visible source view
--decision-command <CMD>Use legacy external decision mode
--pid-file <PATH>Write a process pid file
--allow-otherAllow other users to access the FUSE mount
--config <PATH>Load SkillFS TOML configuration
-v, --verboseEnable debug logging
--log-file <PATH>Write logs to a file

Troubleshooting

A newly installed skill is not visible. With security activation enabled, new skills can remain hidden until the ledger writes activation state. Check notify delivery and activation reload events.

Fallback reads an older version. Fallback intentionally reads a trusted snapshot under .skill-meta, not the live source tree.

.skill-meta is not listed. This is expected for ordinary callers. Trusted peers can access metadata through the configured trusted path.

Notify socket failures appear in logs. Notify failures are warnings and do not stop FUSE service, but the external daemon may miss mutation events until the socket is fixed.

In-place activation fails at startup. Check that --ledger-backing-root is set and visible to the daemon. Avoid /tmp and /var/tmp with services that use PrivateTmp=true.

A managed mount survived the launcher restart. That is expected. Stop it with skillfs stop <MOUNTPOINT>.

More References