Documentation
¶
Overview ¶
Package policy 操作审计门:多种会话执行策略模式(confirm/auto/plan/full)下的 统一操作裁决——每个操作必过、三值裁决、全程留痕。模式改变的是裁决策略,不是移除 审计点;红线(变异工具拒绝、高危恒人审)在矩阵层硬编码,任何模式不可绕过。
裁决分层:例外规则(Policy.Rules,首个命中即胜)→ 模式×风险矩阵 → 兜底 need_human (未知形态 fail-safe)。灰区可挂 Arbiter 仲裁插件,失败/非法输出一律 fail-safe 升人审 ——「只升不降」在 fail-safe 方向恒成立。工具调用面的装饰器见 AuditGate。
沉淀自 bianque engine/policy(v0.9.6):领域包 yaml 路径约定改为显式入参 (LoadOverrides path),其余原样。
Index ¶
- func AuditGate(g *Gate, op Op, onAudit func(Op, Decision), t tool.InvokableTool) tool.InvokableTool
- func Disposition(err error) toolfail.Class
- func FailureClass(kind mcp.ErrorKind) toolfail.Class
- func Stage(g *Gate, op Op, onDecision func(Decision)) invoke.Stage
- func ValidMode(s string) bool
- type Arbiter
- type Decider
- type Decision
- type Gate
- type Mode
- type Op
- type OpType
- type Policy
- type Rule
- type Verdict
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AuditGate ¶
func AuditGate(g *Gate, op Op, onAudit func(Op, Decision), t tool.InvokableTool) tool.InvokableTool
AuditGate 给工具套操作审计门;gate 为 nil 原样返回(未装配审计门=存量行为)。
func Disposition ¶ added in v0.12.3
Disposition 一次失败的处置类别——调用点该调的那一个。
判定顺序:
- 宿主已用 toolfail 显式归类(*Failure / 哨兵 / 自报可重试)→ 以那份为准: 那是产出它的那一层已经做完的判断,比协议层事实更具体。
- 宿主自报「不可重试」→ ClassUnknown:不得回落到协议层映射,否则会把宿主 已经否决的失败重新判成可重试。
- 否则按协议层事实机械映射(FailureClass)。
第 2 步单独存在的原因:toolfail 的自报分支把「自报不可重试」也归成 ClassUnknown, 从返回值上与「什么都没判出来」不可分。此处补一次判别,把这两种情形分开。
func FailureClass ¶ added in v0.12.3
FailureClass 协议层分类 → 处置层类别。
这是**唯一**的映射入口:下游不要各写各的映射表。
未登记的分类(含零值与越界值)一律回落 ClassUnknown——不可分类 = 不可重试, 不给「查不到就乐观」留口子。
func Stage ¶ added in v0.6.1
Stage 把操作审计门接成 invoke 链上的一环。
为什么要这个适配器 ¶
AuditGate 是**装饰器**:宿主忘了包一层,这次调用就没有审计门——而且不报错、 不告警,事后从日志里也看不出这次调用没走门。invoke 链不存在这个形态: 拿到链就只能走 Do,绕过代码写不出来(见 invoke 包头)。
故两者并存:AuditGate 保留以兼容既有调用点,**新代码的审计门走这里**。
Op 的取法 ¶
op 是**模板**:Type / Mode / Risk / Mutating 在装配期固化(它们按调用点是静态可判的), Tool 每次由链上的实际调用覆盖。这样一个 stage 能服务同一调用点下的多个工具, 不必为每个工具各装配一次。
裁决到放行/拒绝的映射 ¶
VerdictAuto 放行
VerdictDeny 拒绝,不可重试(策略否定;重试不会让策略变松)
VerdictNeedHuman 拒绝,**不可重试**:重试会立刻得到同样的结果,
人工审批是带外动作,不该由退避重试去撞
VerdictPlanOnly 拒绝(执行被降级为仅提审),不可重试
VerdictUnknown 拒绝(fail-closed),不可重试
需要人工介入的情形一律不可重试:把「需要人」翻译成「多试几次」是退避语义 最常见的误用,重试风暴会一直撞同一堵墙,且把真正的阻塞点埋在日志里。
Types ¶
type Arbiter ¶
Arbiter 灰区仲裁插件(可选)。契约:只允许返回 auto_proceed/need_human/deny; 失败或非法输出由 Gate fail-safe 升人审——「只升不降」在 fail-safe 方向恒成立。
type Gate ¶
type Gate struct {
// contains filtered or unexported fields
}
Gate 操作审计门。Decide 只读 policy,并发安全,可放工具调用热路径。
type Op ¶
type Op struct {
Type OpType
Mode Mode
Tool string // 工具名(tool_call/execute_step)
Risk int // 1-4(plan_submit);0=未评级
Mutating bool // 工具名命中变异动词段(agentrun.IsMutatingTool)
}
Op 一次待裁决操作。
type Policy ¶
type Policy struct {
AutoMaxRisk int `yaml:"auto_max_risk"`
FullMaxRisk int `yaml:"full_max_risk"`
Rules []Rule `yaml:"rules"`
}
Policy 策略表:代批阈值 + 例外规则。yaml 外置(LoadOverrides,缺文件用 DefaultPolicy 基座;解析失败 fail-fast)。
func DefaultPolicy ¶
func DefaultPolicy() *Policy
DefaultPolicy 内置基座:auto 代批至 L2、full 代批至 L3(L4 恒人工双确认)。
func LoadOverrides ¶
LoadOverrides 读 <fsys>/<path> 外置策略文件(yaml 根键 operation_policy)。 缺文件 → 内置基座(nil error);读取/解析失败 → error(fail-fast,启动即败, 宁拒不启动不带错跑)。阈值 clamp 到基座——外置文件只能调低不能调高 (调高=扩权,须改基座走评审)。path 由宿主传入(如领域包布局约定 "_shared/operation_policy.yaml")。
type Rule ¶
type Rule struct {
ID string `yaml:"id"`
OpTypes []string `yaml:"op_types"` // 空=全部操作类型
Tools []string `yaml:"tools"` // 工具名精确匹配;空=不限
MinRisk int `yaml:"min_risk"` // 含(对 plan_submit 的 Risk 生效;0=不限)
MaxRisk int `yaml:"max_risk"` // 含;0=不限
Mutating *bool `yaml:"mutating"` // nil=不限
Verdict Verdict `yaml:"verdict"` // auto_proceed|need_human|deny|unknown
Reason string `yaml:"reason"`
}
Rule 例外规则(首个命中即裁决,优先于矩阵层)。