mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 17:27:31 +00:00
feat(security,device): security 成为独立内核模块(闸门+策略+限式),device 接管内置工具路由
security(新模块 internal/kernelmod/security)
- 凭据闸门:出向拦截成 @{别名}、入向清洗、执行前回填(internal/security/{gate,runtime}.go)
- 工具黑白名单 + 沙箱(读写根、网络、.. 逃逸):internal/security/policy.go
- 敏感词过滤 + 提示词注入预警(Finding 不带原文):internal/security/content.go
- 按主体授权(hard-private 对非内部主体永久拒绝):internal/security/principal.go
- 插件命名限式(可选档位,插件声明/内核执行,只能收窄):internal/security/profile.go
- 启动装配从 cmd/homed 迁入模块;启动顺序判据改盯真实装配点
device(新模块)
- 正式内核模块,Provides FacDevice,KernelState.Device
- 内置工具路由表下沉到 internal/toolroute(避免 core↔kernelboot 环),
device 保留对外入口;agent 未挂载时退化本地 switch
- Agent 侧只留 api.ToolHost/DeviceSurface 适配层
SDK
- InjectOptions.SecurityProfile:插件按 inputch 声明本轮安全档位(可选)
- InjectOptions.TurnHint:插件注入**本轮事实**,内核以独立 system 消息注入,
不混进用户正文(人设负责怎么说话,TurnHint 只放这一轮成立的事实)
- FacilitySecurity / FacilityDevice
提示词
- 内核自带 prompt/skill/工具返回全面英文化(中文提示会让模型行为漂移)
- 机制解释下沉到 4 个内置 skill(memory/output/tool-order/plugins),
skill 描述压到 80 runes 内(原来 94–108 全被索引截断)
- 默认人格模板英文化;[Voice] 段删除,规则并入 persona 块(单一段落)
- 历史记忆工具改名 coldcontext_query/commit,图记忆语义改称 stable memory
修复
- tracker: exec mount → unix.Mount(降权运行 + AmbientCapabilities 下才能挂)、
区分 EPERM 与不支持;启动日志说明后果与恢复方式
- healthcheck_kernel 输出瘦身:status.Tools 只给摘要(原 98,989 tokens/151% 预算)
- plugin_list 描述讲清 auto_start(按需)与 alive(此刻是否在跑),
明确不能由 alive=false 推断能力不存在
- pluginmgr/webui 去掉写死的 /home/newqqagent 回退路径(env → pluginDir 反推 → 报错)
- lua: 盘上适配器与内置版本不一致且无基线时响亮告警(deepseek 流式丢失
tool_calls 导致'模型不调工具'的真因)
测试:go build ./... 通过;go test ./... 60 包全绿
This commit is contained in:
10
third_party/homeagent-sdk/sdk/facilities.go
vendored
10
third_party/homeagent-sdk/sdk/facilities.go
vendored
@ -61,6 +61,14 @@ const (
|
||||
FacilityStageHost = "stagehost"
|
||||
// FacilityAgent 是主 Agent 就绪(**最晚**的一个,通常在插件加载前)。
|
||||
FacilityAgent = "agent"
|
||||
// FacilitySecurity 是安全防火墙就绪。
|
||||
//
|
||||
// 它不是"某项能力",而是横跨 Core 与全部外部模块的数据面闸门:
|
||||
// Core → 外部、外部 → Core 的每条数据流都经它审查。需要被安全审查后
|
||||
// 才能访问外部模块的插件声明依赖它。
|
||||
FacilitySecurity = "security"
|
||||
// FacilityDevice 是设备/工具数据面就绪(工具注册与分发、inputch、outputch)。
|
||||
FacilityDevice = "device"
|
||||
)
|
||||
|
||||
// KnownFacilities 返回本 SDK 已知的全部设施名(供工具链校验插件声明)。
|
||||
@ -72,6 +80,6 @@ func KnownFacilities() []string {
|
||||
FacilityConfig, FacilityKernelIO, FacilityMemory, FacilityLua,
|
||||
FacilitySupervisor, FacilityTracker, FacilityTextMemory, FacilityLLM,
|
||||
FacilityDocStore, FacilityKnowledge, FacilityMultimodal, FacilityONNX,
|
||||
FacilityStageHost, FacilityAgent,
|
||||
FacilityStageHost, FacilityAgent, FacilitySecurity, FacilityDevice,
|
||||
}
|
||||
}
|
||||
|
||||
3
third_party/homeagent-sdk/sdk/kernel.go
vendored
3
third_party/homeagent-sdk/sdk/kernel.go
vendored
@ -22,7 +22,8 @@ package sdk
|
||||
// RequestKernelShutdown ⇒ 内核清理 → 通知 guard 主动停机 → systemd 不再拉起
|
||||
//
|
||||
// ★ 关机为什么不能用"guard 退出"实现:systemd 是 Restart=always,
|
||||
// guard 退出会被它无条件重新拉起。必须显式 `systemctl stop`)
|
||||
//
|
||||
// guard 退出会被它无条件重新拉起。必须显式 `systemctl stop`)
|
||||
//
|
||||
// ## 失败语义
|
||||
//
|
||||
|
||||
51
third_party/homeagent-sdk/sdk/plugin.go
vendored
51
third_party/homeagent-sdk/sdk/plugin.go
vendored
@ -176,6 +176,57 @@ type InjectOptions struct {
|
||||
ScenePolicy string
|
||||
CleanerName string
|
||||
|
||||
// SecurityProfile 选择**本插件自己声明的命名安全限式**(可选)。
|
||||
//
|
||||
// ## 用途(用户 2026-10-26)
|
||||
//
|
||||
// > 插件可以声明自身安全限制策略,并在插件自身 inputch 触发时携带参数
|
||||
// > 选择其中一种 —— 正好对应 QQ 插件内部 owner 与非 owner 的差别对待。
|
||||
//
|
||||
// 例:QQ 声明两个档位
|
||||
//
|
||||
// Security().DeclareProfile(sdk.SecurityProfile{
|
||||
// Name: "qq.owner", Owner: "qq", AllowTools: []string{"*"},
|
||||
// })
|
||||
// Security().DeclareProfile(sdk.SecurityProfile{
|
||||
// Name: "qq.guest", Owner: "qq", DenyTools: []string{"cmd_*", "files_write"},
|
||||
// })
|
||||
//
|
||||
// 然后按发送者身份在注入时带上 `SecurityProfile: "qq.guest"`。
|
||||
//
|
||||
// ## 缺省语义(重要)
|
||||
//
|
||||
// 空串 = **不使用档位**,一切判定沿用内核默认安全策略
|
||||
//
|
||||
// 也就是说这是**可选**参数:不声明、不传的插件行为与之前完全一致。
|
||||
// 而一旦传了**未声明**的档位名,内核会**报错**而不是静默回落 ——
|
||||
// 拼错档位名却默默用默认策略是安全事故的经典形态。
|
||||
SecurityProfile string
|
||||
|
||||
// TurnHint 是**本轮附加提示**(可选):插件把"这一轮才成立的事实"
|
||||
// 交给内核,由内核以 system 侧说明注入,**不混进用户消息正文**。
|
||||
//
|
||||
// ## 为什么它属于 SDK 而不是某个插件自己拼字符串
|
||||
//
|
||||
// 现场(2026-10-26):QQ 插件把"用 output_send__qq 回复、群里要 @ 对方、
|
||||
// 可发表情包"这类提示**拼进中断文本**,于是
|
||||
// · 用户消息里混着给模型的操作说明,模型分不清哪句是人说的
|
||||
// · 每个插件各拼一套措辞,风格与安全审查都绕过了内核
|
||||
// · 想改提示必须重编插件
|
||||
//
|
||||
// 作为 SDK 字段后:提示是**结构化数据**,内核统一注入与审查,
|
||||
// 插件只负责陈述事实。
|
||||
//
|
||||
// ## 该写什么 / 不该写什么(分工)
|
||||
//
|
||||
// 该写:本轮渠道与回复 meta、群里是否必须 @、可用表情数量与用法、
|
||||
// 本批合并了几条消息 —— **只放这一轮确定成立的事实**
|
||||
// 不该写:短句、别用 markdown、别客服腔、语气与黑名单
|
||||
// —— 那些是**人设**,静态且对所有轮次都成立
|
||||
//
|
||||
// 多行用 "\n" 分隔;内核按行注入,空行忽略。
|
||||
TurnHint string
|
||||
|
||||
// Priority 声明**中断注入**的优先级(仅 InjectInterrupt* 有意义)。
|
||||
//
|
||||
// 取值 PriorityL1..PriorityL4;空等同 L1(默认级)。
|
||||
|
||||
12
third_party/homeagent-sdk/sdk/secrets.go
vendored
12
third_party/homeagent-sdk/sdk/secrets.go
vendored
@ -8,11 +8,11 @@ package sdk
|
||||
// AES-256-GCM + 别名表 + `${ENV}` 解析),与内核的 `internal/security`
|
||||
// **完全重复**:
|
||||
//
|
||||
// 内核 security.Store 插件 unifiedSecretFile
|
||||
// 落盘 secrets.json secrets.json
|
||||
// 加密 AES-256-GCM AES-256-GCM
|
||||
// 别名 HMAC 自动派生 用户指定
|
||||
// 引用语法 @{sec_xxx} @{name}
|
||||
// 内核 security.Store 插件 unifiedSecretFile
|
||||
// 落盘 secrets.json secrets.json
|
||||
// 加密 AES-256-GCM AES-256-GCM
|
||||
// 别名 HMAC 自动派生 用户指定
|
||||
// 引用语法 @{sec_xxx} @{name}
|
||||
//
|
||||
// 重复的代价不只是代码量:**两套变量库互不可见** —— 内核拦截时登记的
|
||||
// 变量,插件看不到;插件登记的,内核拦截不认识。结果是同一个凭据可能
|
||||
@ -103,7 +103,7 @@ type SecretsAPI interface {
|
||||
// SecretInfo 是一条变量的元信息(**不含明文**)。
|
||||
type SecretInfo struct {
|
||||
Alias string `json:"alias"`
|
||||
Source string `json:"source"` // intercepted | submitted
|
||||
Source string `json:"source"` // intercepted | submitted
|
||||
Note string `json:"note,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user