Files
AskaEth c9144c1096
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
feat(plugins): 插件「管理面板声明」库——声明模型 + 闭集校验 + catalog(design/09 §5.2/§5.2.1)
纯库、零接线:不碰 gateway/frontend/Docs/.env*(本片刻意不接线,避免与在途切片争用文件面)。

- pkg/plugins/sdk:面板声明类型(JSON tag 与 design/09 §5.2 示例逐字同形);
  字段类型与 section 类型都是**闭集**;When 三态 + **严格 UnmarshalJSON**(未知条件键报错,
  不静默丢)
- internal/capability/paneldecl:闭集校验(47 条拒绝用例,断言的是**分类哨兵 + JSON 路径**,
  不是错误字符串)· catalog(并发安全、返回拷贝、按 (group, order, 登记序号) 的**全序**稳定排序)·
  when 求值(上下文由 Resolver 注入,本包不读环境变量/文件)· 角色过滤(viewer 只留
  status/log/table 且摘掉 rowActions,纯写面板整体隐藏;未知角色 fail-closed)
- 拒绝粒度:插件 id 非法 ⇒ 整插件拒绝;单个面板非法 ⇒ 只拒该面板 + 聚合显式报错(理由见报告)

【我的验收】隔离 worktree(19 文件)build/vet/linux/darwin 全过、69 包全绿;
我亲手打红变异:把同组同序的回退比较  反成  ⇒ TestCatalog_StableOrder FAIL。
(记录一条观察:比较器已靠 seq 构成全序,故 sort.SliceStable 的稳定性是冗余保护 ——
我第一次用「SliceStable→Slice」打不红,正是因为全序与算法无关;这不是测试虚护。)
2026-10-06 08:06:20 +08:00

20 lines
1.4 KiB
Go

// Package paneldecl 是 design/09-插件生态 §5 的「插件管理面板声明」在宿主侧的库:
// 校验(validate)、清单目录(catalog)、when 求值、按角色过滤。
//
// 职责边界(§5.2.1 B「插件管理器 = 唯一中枢」里的前三项):
//
// - 声明校验:闭集 + 形状 + 命名,逐条给出**可分类**的错误;非法声明绝不静默丢弃
// (口径见 Catalog.Register 与 PLG1-report.md)。
// - 清单目录:收集各插件显式声明的 adminPanels,编译期内置插件与热装条目进**同一张**
// 目录;生命周期(install/enable/disable/uninstall)重算面板集合。
// - 按角色过滤 + when 求值:owner/admin/viewer 与「是否启用」决定下发给面板的快照。
//
// 刻意**不做**的事(这一片是纯库,接线留给后续切片):
//
// - 不注册任何 HTTP 端点、不认识 gateway、不认识前端(§5.2.1 的「唯一契约面」
// GET /api/v1/admin/panels 由后续切片按契约先行登记进 Docs/api-client.md);
// - 不读环境变量、不读文件、不读 config:when 的求值上下文由调用方(插件管理器)
// 注入(见 Resolver)—— 单一事实来源,也让本包可以在没有宿主的情况下单测;
// - 不执行动作、不落审计:本包只声明「动作名」,分发与审计在 §5.2.1 的后半段。
package paneldecl