插件编写¶
本指南涵盖框架侧的运行时插件契约。签名信任、物化、SBOM/证据和更新策略归 产品(PRAXOVELA)所有。
Manifest v1¶
插件附带严格的 JSON manifest。未知字段和尾随数据会被拒绝。
{
"schemaVersion": 1,
"id": "com.example.search",
"version": "1.0.0",
"kind": "tool.provider.v1",
"entrypoint": { "type": "process", "command": "./bin/search" },
"protocol": "jsonrpc-2",
"capabilities": ["tool.invoke"],
"permissions": {
"filesystem": [{ "path": "/workspace", "mode": "read" }],
"network": [{ "host": "api.example.com", "port": 443 }],
"env": ["SEARCH_API_KEY"]
},
"limits": { "memoryMB": 256, "cpuMillis": 2000, "timeoutMs": 30000, "maxInflight": 8 },
"isolation": "process",
"health": { "method": "health", "intervalMs": 15000 },
"signature": { "algorithm": "ed25519", "keyId": "example-release-1" },
"sbom": "sbom.spdx.json"
}
kind为tool.provider.v1、model.provider.v1、policy.provider.v1、memory.provider.v1或sandbox.provider.v1。entrypoint.type和isolation为process、wasm或container, 且必须匹配。process需要entrypoint.command;wasm需要entrypoint.module;container需要entrypoint.image。permissions默认拒绝。文件系统模式为read、write或readwrite。- 在签名信任配置下,
signature和sbom是必需的。未签名配置是明确的 本地开发选择。
使用以下代码解析和校验:
m, err := plugin.ParseManifest(raw)
if err != nil { /* reject */ }
if err := m.ValidateTrust(plugin.TrustSigned); err != nil { /* reject */ }
进程宿主¶
进程宿主通过子进程的 stdio 使用 JSON-Lines。每个请求是每行一个 JSON 对象:
{
"id": "req-1",
"version": 1,
"plugin_id": "com.example.search",
"service": "tool.provider",
"method": "invoke",
"token": "<per-process token>",
"payload": "<opaque contract bytes>"
}
插件回复:
{
"id": "req-1",
"version": 1,
"ok": true,
"payload": "<opaque contract bytes>"
}
规则:
- 在每个请求上校验
token。宿主默认通过PRAXOVELA_PLUGIN_TOKEN环境变量 提供它(可通过process.Config.TokenEnvVar覆盖);它绝不通过 argv 传递。 - 在启动期间响应
health。 - 收到
cancel时放弃进行中的工作;在shutdown后干净退出。 - 将失败映射为
CAPABILITY_DENIED、NOT_ACTIVE、NOT_FOUND、INVALID_REQUEST、TIMEOUT或INTERNAL。 - 不要将协议帧写入 stderr;stderr 会被捕获并有界。
宿主侧配置(process.Config)包括 PluginID、Provider、Sink、
RequireEvidence、Path、Args、Dir、Env、Token、TokenEnvVar、
超时、帧大小限制、Limits 和 RequireLimits。生产调用方应设置
RequireLimits 和 RequireEvidence。
WASM 宿主¶
WASM guest 必须导出:
memoryalloc(len i32) i32prax_request(ptr i32, len i32)
并导入 env.prax_respond(ptr i32, len i32)。每次 prax_request 必须恰好
交付一个响应帧。宿主使用 MaxMemoryPages 限制线性内存,并在调用上下文结束
时终止 guest。v1 中不强制 CPU fuel。
一致性测试套件¶
实现 tck.HostFactory / tck.HostHarness:
type HostHarness interface {
Start(context.Context) error
Stop(context.Context) error
Invoke(ctx context.Context, service, method string, payload []byte) ([]byte, error)
PluginID() string
Contract() plugin.Contract
Methods() tck.HostMethods
}
HostMethods 命名测试夹具方法:
Echo:原样返回载荷。Block:等待上下文完成。Denied:返回CAPABILITY_DENIED。Timeout:限制阻塞调用的时间。
然后运行:
if err := tck.CheckLifecycle(plugin.NewLifecycle()); err != nil { /* fail */ }
if err := tck.CheckRegistry(registry); err != nil { /* fail */ }
if err := tck.CheckHost(factory); err != nil { /* fail */ }
CheckHost 覆盖分帧、超时、取消、能力拒绝和非活跃门禁。每个检查都会从
工厂获取一个全新的宿主。
信任边界¶
核心宿主启动已经验证的载荷。产品必须在构造宿主之前验证描述符签名、SBOM、
身份、ABI 和兼容性。pkg/plugin 从不解析需求,也从不调用信任存储。