Skills and instruction trust
Sophia treats skills as a governed instruction supply chain: owner-gated publication, compiled cross-harness workflows, final-byte installation receipts, and an explicitly unattested runtime signal that never widens agent authority.
Every claim on this page checked against the product source at a pinned revision — 2026-07-21 @ 804cbf79.
What this is
A skill is a stored body of instructions that an agent loads and follows as a playbook. Sophia Superpowers is the governed operating-method layer that teaches agents when and how to use Sophia: one canonical capability graph and set of workflow contracts, compiled into native routers for each supported agent tool. This page covers both boundaries around it: which instruction bodies may ever reach an agent, and what Sophia can honestly verify about the pack installed for a live session.
Why it exists
Most stored content is data — an agent reads it and decides what to do. A skill
is not data. It is instructions, and the system delivers it automatically to
whichever agent the task matches. So an unapproved skill body arriving in an
agent’s context is not a content-quality problem; it is a cross-agent prompt
injection, carrying the system’s own authority, delivered on the system’s own
initiative. The code states the rule where it enforces it: “an unapproved body
reaching an agent’s context IS the cross-agent injection”
(proxy/src/mcp/skills.ts:556-565).
That is why publication is the one write no agent can perform. It is not a question of trusting our agents; it is that “agent-authored instructions that every other agent will obey” is a channel that should not exist without a person in it.
How it works
No agent profile can publish, however privileged. sophia.save_skill accepts
only draft and refuses anything else before any write — no row, no file, no
partial state (tools/skillTools.ts:262-288). This is not a permission check a
stronger profile could pass: publishing happens on a different transport
altogether. It is an owner HTTP route behind the daemon session key held by the
owner’s paired browser, and an agent authenticates to the MCP surface, not to that
one (routes/api/skillPublishRoutes.ts). There is no privilege level on the agent
plane that reaches it. Publication is journaled, so which human approved which
body is a matter of record — and an agent cannot overwrite a skill the owner
already approved.
A draft is inert: never served, never ranked. A single predicate,
isServableStatus (skills.ts:566), governs every read, and it lives in the data
layer rather than in each handler — “so a future read path cannot reintroduce the
hole by forgetting.” Drafts are excluded from load_skill, from list_skills
(including its body-bearing projection), and from the ranker that feeds orient —
the automatic-delivery path, where only published skills are eligible. Even draft
titles are withheld, because an attacker-chosen title is itself a small
injection surface. A test enumerates every agent-facing read path and asserts a
draft body is unreachable through all of them.
The chokepoint is wherever the content can escape. The skills vault is a
watched directory: anything written there is ingested into documents and
full-text search, and would then be readable through ordinary document retrieval —
straight around any check on the skill reader. A gate on one reader is a fence,
not a chokepoint. So a draft never reaches disk at all. Publishing writes the
file; unpublishing tears the ingested copy back out — the artifact, its full-text
row, its index entry — because deleting a file does not un-ingest it
(wiki/retractVaultArtifact.ts). If retraction fails, unpublish returns an error
saying the body may still be readable, rather than a clean success.
The same principle decides who an agent is: a coordination message’s author is taken from the authenticated connection, never from the message body. A body claiming to be someone is text, not a credential.
The pack that ships with the product is compiled, and the compiler enforces
least privilege. The sophia-* skills are authored once as a capability graph
plus a workflow description, then rendered into a native pack per agent tool. Two
checks run at build time, and both are failures rather than warnings: a workflow
may not declare more privilege than the capability it stands on, and the compiler
will not emit a composition mode it has not observed that tool actually support
(proxy/src/superpowers/compatibility.ts). Where a tool’s behaviour is unknown,
the fixture records "unknown" — it is never rounded up to true. And the
compiled pack is held to a live cross-harness conformance gate: a fresh agent
on each supported tool, run against the real daemon rather than asserted in a
document, before a wave counts as done.
The daemon can distinguish a matching installed release from a model merely
saying it loaded a skill. The installer hashes the final bytes it actually
placed on disk, then injects an activation descriptor naming the installation,
harness, adapter version, graph version, build-receipt hash and signature state
into the lifecycle hook. At startup, resume, clear and compact, that hook performs
a two-step activation with a connection-bound, single-use nonce. The daemon
accepts the runtime signal only when the descriptor matches its exact current
adapter, graph and build receipt (adapterCompatibility.ts). A release mismatch,
replayed or expired nonce, or ordinary load_skill activity does not produce
installed-router status. Update, rollback, uninstall and revocation clear prior
activation rather than carrying trust forward.
That signal is deliberately authority-inert. A matching pack may organize the
tools a connection already has; it cannot add a tool, widen entity scope, remove
an approval gate or enable a privileged workflow. Current releases are unsigned,
so the surfaced mode is installed_router_unattested, never a stronger claim.
This is meaningful prompt-injection resistance because drift and model testimony
cannot silently become trusted installation state. It is not a claim that Sophia
can see inside the model or prove the model obeyed the method.
What your agent does with it
// An agent may propose a skill. It may not publish one.
await sophia.save_skill({
id: 'sophia:resume-session',
title: 'Resume a multi-turn session without re-deriving context',
body_md: '## Trigger\n...',
status: 'stable', // ← requesting publication
});
// → { error: 'owner_approval_required' }
// Refused BEFORE any write: no row, no vault file, no partial state.
// Drop the status (or pass 'draft') and the same call succeeds as a draft.
// The owner reviews drafts in the owner UI and publishes there — over the
// session-key HTTP route an agent bearer cannot reach.
// Until then the draft is inert. It is not served:
await sophia.load_skill({ id: 'sophia:resume-session' });
// → { error: 'SKILL_NOT_PUBLISHED' } (no body)
// ...and it is not ranked into any other agent's orient(). The failure is the interesting part: the refusal happens before anything is written, so a rejected publish leaves nothing behind to clean up.
Boundaries
There is no signature or cryptographic attestation on the pack today. The installer re-hashes final installed bytes and the runtime matches the reported receipt to its current release, but the lifecycle signal remains a self-reported, unsigned local receipt. The build says so itself: the first field of every receipt reads “deterministic development receipt; not an attestation.” Signed releases, per-install device keys and a cryptographic verifier remain in flight.
Sophia also does not claim per-skill behavioral adherence. Manual skill loading cannot activate installed-router state, and the lifecycle signal identifies the pack release rather than every instruction the model subsequently followed. Per-session skill loads are not recorded as proof, and behavior that looks consistent with a skill remains observation—not attestation.
This also inherits The Security Model’s local-trust boundary — whoever controls your OS user controls the daemon, its vault, and its database. None of this defends against a person who already has your account.