Validate the portable package before loading extensions
Use
when:
a
harness
accepts
portable
root
plugin.json
packages
beside
product-specific
overlays,
especially
when
the
package
can
expose
Agent
Skills,
MCP
servers,
hooks,
or
apps
from
a
downloaded
or
marketplace-installed
directory.
$schema
identifier;
never
fetch
a
schema
while
loading.
Reject
unsupported
versions
before
publishing
any
capability.
Keep
portable
discovery
fixed:
skills
are
immediate
children
of
skills/,
and
MCP
configuration
lives
at
mcp.json.
Resolve
every
package
path
against
the
materialized
root
and
skip
any
component
whose
canonical
target
escapes
it.
Allow
a
vendor
extension
to
supply
vendor-only
interface,
hook,
or
app
metadata,
but
do
not
let
it
replace
portable
identity,
version,
description,
or
fixed
component
roots.
Acceptance
check:
build
four
fixtures.
A
valid
v1
package
must
load
exactly
one
immediate-child
skill
and
one
test
MCP
marker.
Changing
only
$schema
to
an
unsupported
version
must
yield
zero
skills,
servers,
hooks,
and
apps.
Adding
a
nested
SKILL.md
or
a
symlink
whose
target
is
outside
the
plugin
root
must
expose
nothing
new.
Finally,
give
the
vendor
overlay
a
different
name,
version,
skill
path,
and
MCP
path.
Pass
only
if
portable
identity
and
fixed
components
remain
unchanged
while
the
permitted
vendor
interface
override
still
applies.
a28374e
adds
291
lines
of
manifest
tests
plus
83
skill-loader
boundary-test
lines,
covering
metadata,
unsupported
schemas,
overlay
precedence,
legacy
fallback,
and
direct-child
discovery.
The
Agent
Plugins
1.0.0
working
draft
independently
requires
local
schema
selection,
root-confined
paths,
and
immediate-child
skill
discovery.
Caveat: this establishes a package boundary, not content safety, dependency integrity, MCP authorization, or subprocess sandboxing. The specification is still a working draft. It also permits symlinks that resolve inside the plugin root; do not generalize the escape test into a blanket symlink ban. An open Codex issue documents a separate installer failure: local-marketplace copying can silently drop symlinked shared resources. Avoid symlink-based plugin composition until that path has a passing install-cache regression test.