goagent-kernel
介绍
设计初衷
怎么用
能力
坑速查
  • 本站 llms.txt
  • oekit llms.txt
  • oagentkit llms.txt
  • 包清单与机器事实
  • 门禁体系
  • 决策记录(ADR)
  • 版本记录
GitHub
介绍
设计初衷
怎么用
能力
坑速查
  • 本站 llms.txt
  • oekit llms.txt
  • oagentkit llms.txt
  • 包清单与机器事实
  • 门禁体系
  • 决策记录(ADR)
  • 版本记录
GitHub
  • 参考

    • 包清单与机器事实
    • 门禁体系
    • 决策记录(ADR)
    • 版本记录
    • 坑速查

包清单与机器事实

本页由 site/gen.mjs 生成,勿手改

包表 / 工程底座基线 / 依赖版本 / 规则清单分别抽取自 README、go.mod、 architecture-policy.yaml、Makefile;每次 npm run docs:dev / docs:build 自动重新生成。 要改事实请改源头文件——手抄一遍就等于多一份会静默失真的真相。

能力包清单(41 个包)

依赖列只列仓外 import;「无」表示该包只用标准库。

包生产行数外部依赖职责
protocol2341oekit/pkg、jsonschemaReport 契约 + 五级容错解析 + 白名单校验 + Markdown 渲染
dispatch36oagentkit/agentallow 矩阵物化 + 深度上限 + 自派发拒绝 + 环检测(拓扑经 EdgeSource 由宿主提供)
eventbus377oagentkit/runtime进程内有损广播(缓冲 chan);持久化在发布点由宿主负责
policy89cloudwego/eino、oagentkit/guardx、oagentkit/toolgate操作审计门:阈值只降不升、解析失败即拒。两个接入口:WithAuditGate(包单个工具)与 Stage(接成判定环的一环——工具调用、程序内调用、子进程侧调用全走同一条 invoke 链,审批规则只装配一次;门面原先缺后者,宿主想接审批进判定链只能 import 上游 toolgate,「调用面逐字兼容」的承诺就断在那里)
spill263oekit/pkg输出预算溢出:提示契约 / 取回 / 按龄清理
pii712oekit/pkg个人信息价值面脱敏(手机号 / 身份证四重校验);运行时策略(开关/面/强度)整份单指针原子交换 + 变更订阅 Subscribe,代次从此不只可查、还可响应
netguard1212oagentkit/guardx、oekit/pkg出站 URL 守卫(SSRF):名字层(解析前按名拒)+ 解析后逐 IP 过 egress + 重定向逐跳重验。扩展名单整份原子交换 + 代次可观测(两次独立取会读到撕裂策略)。代次只有一个真相(策略指针内的 gen,全局值是它的投影;交换走 CAS 循环,故并发下代次唯一、单调、不回卷)。DialFunc 把同一套判定落到建连那一刻(名字层 + egress 预检 + 建连后核对真实 RemoteAddr)——闭合「校验 → 拨号」的 rebinding 窗口;判据仍是 egress,不引入第二套 IP 策略。放行面具名且两层共用同一类型(Allow,零值即严);NewClient/NewTransport 是接线件——宿主一行把守卫挂上,且 client 可注入(测试连本机假服务器时只在测试里放宽回环)非纯 stdlib;DNS 解析与拨号间的 rebinding 窗口见包头「已知局限」与 dial.go;与上游 oekit/pkg/urlguard 的分工(IP 策略单源 egress 不换、域名后缀层本包为超集)同样见包头
statemachine79无环节状态机:条件迁移的纯函数件
contract124无编排运行契约:编排引擎 ↔ 宿主状态的唯一边界(纯接口面,零实现)
checkpoint882oekit/pkg编排续跑契约:进度快照存取边界 + **「续跑而非重放」**的恢复判定(空洞不采信 / 终态不自动重开 / 序号单调闸)+ 跨进程 CAS 存取契约(StoreCAS.SaveIfNewer)与提交序列固化(Committer:抢序号→落库→仅失败时回滚,宿主无法漏掉)+ 依赖声明(StepDef.DependsOn / Isolated):并行 fan-out 的合法乱序完成按各自前驱采信,不再被「连续前缀」整批作废;零值 = 旧口径逐字不变
commitgate328oekit/pkg环节终态独占提交闸:同一 (run, 环节) 的终态只允许被提交一次(statemachine 是纯谓词,SeqGate 只排快照序号,两者都排不出「两条分支都赢了」)。终态词表由宿主注入。放闸靠凭证:Acquire 返回唯一令牌、ReleaseLease 凭令牌精确释放——靠 (状态,分支,序号) 认人的旧 Release 分辨不出两次同名同序的占用,迟到的释放会放掉别人的闸
budget750oekit/pkg上下文预算:分段计量 + 窗口钳位 + 压实计划骨架(三重空转守卫;摘要生成与原文落盘各留宿主接口)
offload587oekit/pkg内联大对象外置:sha 去重 + 两阶段(首次标记、后续轮才替换占位)+ fail-soft(与 spill 是姊妹机制)
tooldisclose959oagentkit/guardx、oekit/pkg渐进式工具披露(确定性打分检索换完整 schema)+ 执行门禁(未加载可重试 / 不在目录禁止绕过 两类严格二分,拒绝即激活,重试不绕路)+ 接成 invoke 链的一环(Stage,链上 Reason 直接回面向模型的指引)
toolfail89oagentkit/guardx工具失败的错误分类契约(门面,核心在 oagentkit/guardx/toolfail):类别 → 可重试性/退避/需人工/重发安全/模型指引为数据表而非散落 if;不可归类一律不可重试。重发安全与重试价值是两个正交维度——超时值得重试但服务端可能已执行,原样重发即重复施加副作用;Guidance() 是模型侧的唯一消费方。判定口径必须跨宿主一致,故核心归上游安全层,本仓只保调用面稳定
toolname96无工具名 → 程序内可用的 JS 标识符:一条单一真相。IsJSIdent(能不能直接用)+ Normalize(不能的话用哪个)。生产侧(tooldisclose 派生调用形态)与消费侧(ptc 挂载绑定并校验形态里的函数名)共用它——两侧必须逐字一致,否则就是「这里派得出、那里认不出」的夹缝。规整不保证唯一(get-logs 与 get_logs 同名),撞不撞由调用方判
sideeffect797oekit/pkg副作用「至多一次」的跨进程契约:幂等键(同一逻辑动作重试不重复施加)+ 租约(同一资源独占,带 TTL)+ 栅栏令牌(过期持有者的迟到写入被下游拒绝)+ 下游拒收契约(FencedSink:比较与写入须同一次原子操作,否则两个持有者会同时读到同一个旧值、双双通过检查,更旧的那次写入反而后落覆盖新的)。上游三个判据共用一次原子操作(Store.Acquire)——拆成三份存储就会出现「租约过了但幂等没过」的夹缝,允许同一动作被施加两次。执行失败不记账(没做成的不能记成做成了),但释放闸(否则失败残留的闸会把后续重试全挡成「别人占着」)。v0.32.0 起施加失败且无法判定远端是否已生效 ⇒ 结果未知(OutcomeUncertain):该 Key 禁止重试,必须先对账(Reconcile)——「响应丢了」与「远端没做」在调用方看来完全一样,而前者重试就是重复施加;执行器同时拿到栅栏令牌(lease.Fence)好把陈旧写拒在下游。施加前有资格检查(ExecuteWith 两段式:准备 → 检查 → 施加)——闸已易主时根本不施加,因为 Complete 被拒只说明没记上账,副作用早已生效,事后补救不了。承诺的是至多一次而非 exactly-once——后者要求下游也接受幂等键
sidetest696oekit/pkgsideeffect.Store 的共享契约测试套件:宿主写完存储实现后跑一遍,违反哪条契约就红在哪一条——免得「各写一遍必然各判一套,漂移到没人发现为止」。15 条子测试覆盖「只做一次 / 已完成优先于占用 / 未过期时争用 / 过期后接管 / 令牌单调 / 过期持有者不得记账 / 过期持有者不得放闸 / 释放不等于完成 / 续期延长且不换令牌 / 闸已易主后续期被拒」,外加「结果未知」一族五条(未知态禁止再执行 / 裁决未生效允许重试 / 裁决已生效记结果 / 裁决先到者为准 / 过期栅栏不得转未知)。范式沿用上游 cachetest / singleflighttest:硬失败不静默跳过(显式接入套件=声明要满足契约,跳过等于把「没测过」伪装成「通过了」)。时钟可注入(ClockedStore),否则过期场景恒不触发,套件会变成一组空断言
cmdpolicy527oagentkit/tools、oekit/pkg命令级判据:把判定面从「工具调用」向下延伸到工具内部实际执行的那条命令。此前边界停在工具名上——一次 exec 审批通过后,它内部跑的是 git status 还是 rm -rf / 没有任何机制面看得见,宿主只能靠正则黑名单兜,而黑名单在「写法与语义不一致」时必然失效。本包用前缀 token 规则(先分词再比 token,不随引号/转义/空白漂移)+ 三态裁决(allow/prompt/forbidden,与 toolgate 词表同义不另立口径)+ 规则自带样例(每条规则可带 Match/NotMatch,New 在加载期用真实判定路径跑一遍,不一致即报错——这是「从没见过它触发的规则等于没有规则」的机器化:规则会随命令名漂移,而漂移不会报错,只会静静地不再命中)。冲突口径确定性:前缀更长者胜 → 同长度取更严 → 同档取名字字典序最小。SplitCommands 单独存在是因为前缀判据的典型绕过:git status; rm -rf / 的前缀是 git,对整串只判一次就会让一条 git 的 allow 规则放行后半段。分词面已收编上游 oekit/pkg/shellx(2026-11-11):口径归上游一处,本仓不再维护第二份分词器;顺带修掉手写版三处 POSIX 错误(双引号内反斜杠被丢弃、分隔符按 token 相邻误合并、CR 未归空白),且 SplitCommands 的段文本改用上游 QuoteArgv 拼装,段可往返(段再分词得回原 token——否则含空格的备选前缀永不命中,是安全方向的漏判)。事实面已收编上游 oagentkit/tools/bashguard(真 shell AST):前缀判据的三类典型绕过(多段 git status; rm -rf /、命令替换 echo $(rm -rf /)、写重定向 git status > /etc/passwd)由「全调用面取最严 + 事实面下限(写重定向/动态展开 ⇒ 不低于 prompt)」闭合,本仓不手写 shell 解析器
egress428oekit/pkg出口策略:三档(ModeUnrestricted < ModeProxy < ModeDenied,单调可比、零值即最松)+ 声明自检(Validate)+ 兑现判据(Env / Verify)+ 后端能力问询(SatisfiedBy)+ 兑现强度(VerifyVerdict / SatisfiedVerdict:环境变量兑现出来的永远是建议型,只有后端能力声明才是强制型——「代理档已兑现」不等于「出站已被强制隔离」)。本包不含代理本体(那是上游 guardx 与宿主的活),只回答此前没人回答的三件事:这次执行要求哪一档出口 / 宿主给的环境是否真的兑现了那一档 / 某个沙箱后端能不能兑现它。两条底线都是「沉默与伪造都落在安全的那一侧」:后端不声明就按最弱处理(不是「没说不支持」=满足,否则从没实现过出口控制的后端会被选中,声明与实际之间的落差没有信号);禁网档拒绝伪造(ModeDenied 的 Env/Verify 直接报错,不做「尽力而为」——假装禁网比明确拒绝更危险,报告会显示「已兑现」而网络其实通着)
gatecheck504oagentkit/guardx、oagentkit/toolgate、oekit/pkg审批层与沙箱层的联合判据:Codex 的两层安全模型是「沙箱强制 + 审批策略,两层都同意才放行」。上游 guardx/sandbox(档位×预算)与 toolgate/policy(审批裁决)各自完整但互不知情——「两层是否都同意」这个判定没有单点,落在各宿主手里必然漂移。本包只做合成(不重新实现任何一层,那会造成与上游并存的第二份真相)。判据顺序有意为之:审批已否 ⇒ 直接否(档位再高也不该执行);需人审 ⇒ 优先于档位不足(人该在场,而不是让宿主去找后端——否则这次调用既没执行也没人管,静默丢失);计划模式单列(只审不执行 ≠ 拒绝)。Managed 是受管后端(把真后端包起来):判据不通过就不委派(副作用不会发生)——判据与执行不可分,否则「判过的后端 ≠ 实际跑的后端」又有了信号落差
preset230oekit/pkg命名权限预设:把「隔离档位 × 审批模式 × 出口策略」三件散参数收成一份具名、只读、加载期自检的组合(Preset{Name,Level,Mode,Egress,Unsafe,Justification})。散参数的病不是难写,是改一处漏两处——档位调到 OS 级而出口忘开代理、审批放到 auto 而沙箱仍是进程内,组合出来的权限谁都没声明过。自检两条最关键:三面全松必须显式 Unsafe 且写理由(「全都放开」最容易在调试时临时出现、然后留下来);语义相同的两个名字即报错——两个名字一份组合在配置里看起来是「两个选择」,真正的伤害在留痕:报告里出现两个名字,读者会以为执行过两种权限。Resolve 遇未登记名字报错而不降级(降级方向不可预测,可能更松,而「打错一个字就用上另一档权限」没有任何信号)。方向是 preset → gatecheck(高层组装件认识低层判据),gatecheck 不认识 preset
retryplan192oagentkit/guardx重试处置决策:把「该不该重试」(toolfail 判)与「重试会不会重复施加」(sideeffect 判)合成一条可执行结论——三档路径(不重试 / 原样重发 / 走幂等键重放)。与 guardset 同族:组合逻辑归内核,判定归各自机制(各宿主各写一遍组合逻辑,必然各判一套)。关键一档是「可重试但原样重发不安全」——toolfail 只说「先确认上一次是否已生效」,没说什么怎么做到,而这正是幂等键的活;故该档判为 PathReplayed(走幂等键)。关键取舍:没有幂等键就不许「猜着重试」(降级为不重试,而非原样重发赌一次)
delta253oagentkit/runtime增量节流:分片合并 + 权威整段优先 + 确定性收口扫序
pending73无多轮挂起态载体:单一编码入口 + 宽容解码(非法值降级为无挂起)
reminder30oagentkit/guardx系统注入提示的防伪包裹(门面):核心已下沉 guardx/injectband,本包只保调用路径稳定,宿主调用点一行不动
sessionref212oekit/pkg跨会话引用快照:把另一个会话的结论以有界、带来源、带失效点的片段注入当前上下文。budget/spill/offload 三者回答的都是「同一份上下文里内容放不下怎么办」,而「引用别的会话的结论」是另一件事——那份内容不在当前上下文里,它的边界与保鲜度没有任何机制面管。不管的后果不是「引用得不好」,是把当时的结论当成现在的结论用,而这类错误在报告里读起来完全正常(那段话当时确实是真的)。三条判据都走结构:① 裁剪上限采集时给定且裁剪必须显式(Truncated + OriginalBytes + 注入面的 truncated=true,静默截断会让模型以为看到全文);② Source/SourceVersion/CapturedAt/ExpiresAt 随快照走;③ 渲染写 `state=fresh\
drain320oekit/logx、oekit/pkg优雅排水:轮 ctx 取消脱钩 + 等在途收敛 + 预算耗尽强制收刀(经 Turns 接口)
ptc3116dop251/goja、oagentkit/guardx、oagentkit/runtime、oekit/concurrency、oekit/logx、oekit/pkg程序化工具编排:模型写程序 → 沙箱 VM 执行 → 经 bindings 调宿主工具;三重预算(墙钟/调用数/字节数)替代 OS 沙盘。N 轮 ReAct 往返塌缩成 1 轮,原始数据不过模型面;绑定可带 Signature 让模型按位置传参(可选形参以 ? 标记、未传则不出现在 JSON 里;形态里的函数名必须是净化后的名字,规则见 toolname);程序内的 host.<tool>() 与普通工具调用走同一套 Stage 判定环(不做这一步,本包就成了整条链上唯一绕过所有门禁的路径);v0.32.0 起缺省即拒绝:装了工具绑定却没装判定环 ⇒ 拒绝执行(ErrorKind=unmanaged),裸执行必须显式声明逃逸口(生产代码里由门禁拦下);绑定名净化后撞名即装配期拒(否则后绑者顶替前绑者,副作用错位无信号)。新增子进程后端(ptc-subprocess):把执行搬出宿主进程,用 cgroup v2 的 memory.max 兑现 MaxMemory(限物理内存;RLIMIT_AS 限的是虚拟地址空间,会把 Go runtime 一起掐死——已实测否掉)——进程内形态兜不住内存(Go 运行时没有「只给一个 VM 限内存」的开关,goja 公开 API 也没有内存限制),故子进程形态如实声明自己兑现这一项(sandbox.Capable),建不出即拒绝执行(fail closed),兜不住的后端在登记簿里不会被选中
sandbox116oagentkit/guardx执行沙箱的档位语义与后端协议(门面,核心在 oagentkit/guardx/sandbox):Level(进程内解释器 → 内核级 → 硬件虚拟化,单调可比,零值即最弱档——漏声明的后端只落到最弱一档,方向是安全的那一侧)+ Provider(后端自报提供哪一档并执行程序)+ Registry(登记簿;按要求档位选最弱满足者,无满足者即拒绝、不降级——降级会让「宿主声明的强度」与「实际执行的强度」之间没有信号,档位机制就成了装饰)。零内部依赖,ptc 反过来依赖它(沙箱机制不认识任何后端,后端认识沙箱)。已知局限:档位是后端自报的,内核不校验其真实性——宿主不信任某后端,唯一办法是不登记它。档位声明要签字:后端的档位登记在 policy 的 sandbox_providers 段(人 review 时看得见「它凭什么说自己有这一档」),门禁 harness-sandbox-provider-declared 核对登记与代码事实不漂移(走 go/ast 按方法指纹认出后端实现)
watchdog127无被动配对不变量监视:环节收口仍有未执行声明 / 结果无对应声明;只告警不裁决(热路径裁决在守卫侧)
guardset1027oagentkit/guardx、oekit/pkg守卫装配契约:一组相互独立的判定一并求值,多条拒绝合成一条(按 Rank 定序、不可重试优先的保守裁决、指引指向真正卡住的那一条)。接成 invoke 链上单独一环——链在第一个拒绝处就收口,后面的守卫永远没机会说话,模型一次只听得到一个理由,这正是本包补的那一面;链本身的顺序/留痕/panic 兜底沿用上游,不重复实现。装配面 Assembly 提供「撤销」的机械路径:撤销 = 换整份,不是改其中一条——改其中一条会让「当前有哪些守卫」出现两个真相;换份走 CAS + mutate(旧值)(并发撤销不丢更新,否则「撤销被撤销」)、代次住在被换的那份里(全局代次是投影)、链不用重接、旧份不被修改、在途判定跑在旧份上;「全部撤销」不是降级是失守(换上去的那份永远非空)
archcheck5246gopkg.in/yaml.v3架构门禁执行体:architecture-policy.yaml 的可执行面(规则判定 / 门包判定 / 依赖方向判定 / policy 自校验 / 结构阈值)。可导入包——宿主仓复用同一套判据,不必各写一遍(各写一遍必然各判一套,漂移到没人发现为止)。判据与执行体分离:结构性判定一律走 go/ast(import 声明有六种以上书写形态,逐行正则必然漏)。依赖方向判三条:越界内部依赖 / 越界跨仓依赖(ext: 登记)/ 未登记包目录。执行沙箱后端的档位登记(sandbox_providers 段 ↔ 代码事实,走 go/ast 按方法指纹认出后端实现,核对档位漂移与未登记)。陈旧包根当天即红——root 指向空目录即「声明与事实已偏离」,而没有执行体时这句话没人读
trajectory1043无轨迹投影器:事件流 → 一轮 turn 的步骤序列(增量投影:喂新事件继续更新既有行)。行含 kind / 起止时刻 / 实测耗时(起止相减现算)/ 工具调用配对状态(paired / missing_result / duplicate_result / unpaired_result / duplicate_call)/ 摘要。⭐ 结构上不设时长字段——时长唯一来源是起止相减,估算值无处安放(没有实测就是没有实测,不拿 payload 体积之类糊过去);配对缺口语义分两层:missing_result/unpaired_result 是当前状态(等到了会被清掉),duplicate_* 是发生过(永久留在清单里)。事件倒挂(结果先于调用)按「就地补起点」处理且此时判为无实测值。与 watchdog 分工:watchdog 判不变量(只告警),本包判这一轮的流水(给宿主渲染)。另有 OTel 映射契约(otelmap.go):每个属性写明来源字段 / 取值域(含 Go 类型)/ 基数上界 / 能否进 metric label,Span.ParentID 声明父子,trace 边界定在轮(Row.ID 的唯一性范围恰好就是轮内);无界看似维度的字段(session_id/agent_slug)列进禁区清单
taskboard398oekit/concurrency、oekit/pkg多 agent 协调面的存储中立契约 + 一致性判据:dispatch 只回答「能不能派」,派出去之后「谁负责哪个子任务、依赖谁、怎么还回去」此前没有任何机制面——各宿主自己拿一张表兜着,于是「同一子任务被两个 agent 同时认领」在报告里读起来完全正常(两条分支都干完了活,各自都以为自己是负责人)。本包不给存储实现(表结构/事务边界/持久化是宿主资产,给一份参考实现宿主就会照着改它,最后两份真相并存——与 checkpoint.StoreCAS 同一分工)。三条口径:① 认领必须原子由存储保证,本包只判结果(ConcurrentClaim 并发跑一遍,成功者必须恰好 1 个);② 释放/完成凭令牌不凭内容(同名 agent 与「失败→释放→重试」都会让内容比对认错人);③ failed 不是终态(一次失败不能把子任务永久钉死,否则补救路径静默失效)。Check 判快照不变量:id 唯一、依赖存在且无环、认领态与租约必须同时成立、依赖未完成不得认领、终态不带 owner
skilldisclose360oekit/pkg技能披露:确定性挑出该给模型看的那几个技能。与 tooldisclose 不是重复——那边的检索键是「工具调用需求」,而技能的触发信号有三种且强度不同:点名 > 资源命中 > 描述相关。混成一个分数会让「相关」压过「点名」,而那正是用户已经明确表达过的意图(故点名权重 1000,任何相关度信号之和都够不到)。判据三条:点名压过一切;同分按名字(不依赖目录遍历顺序与 map 顺序);预算裁剪显式(Truncated,静默截断会让宿主以为「就这几个相关」)。空结果必须写明原因——「没有检查」与「检查通过」在调用方看起来一样,而前者是「模型不知道有这个能力」
hookengine296oekit/pkgHooks 的判定面(不是传输面):Codex 是「外部进程协议 + 规则文件」,DSH 是「动态插件包」,形态已经分叉——由内核选边等于把一种传输焊进契约,故只定三件跨形态恒定的事:匹配(事件 + 工具前缀)/ 裁决(allow / deny)/ 顺序与收口(按名字确定序,第一个拒绝即停)。传输与加载归宿主(Runner 是唯一接缝)。两条 fail-closed:阻塞 hook 执行失败 ⇒ deny(跑不起来不等于没问题,否则一个写错的检查会静默变成空检查);超时裁决必须显式声明(OnTimeout,缺省 deny)——没有缺省值时超时会被 ctx 取消掩盖成「这次没拒绝」。非阻塞 hook 不参与裁决但失败必须留痕:它一旦能影响裁决就只是「慢的阻塞 hook」,而宿主会以为它是旁路的
memorypipe219oekit/pkg记忆注入的三段:注入 / 引用 / 打标(读写时机与摘要生成归宿主,与 budget 留 Summarizer 是同一条边界——内核不替宿主决定「这段对话值不值得记住」)。注入侧三件与策略无关、各宿主各写一遍又必然各判一套的事:① 来源是前提——没有来源的记忆与模型的猜测在文本上无法分辨,故不注入、显式丢弃并给出原因;② 逐条打标(id / source / at 三样缺一就少一条追溯路径:没 id 无法引用,没 source 无法判可信度,没 at 无法判新鲜度);③ 裁剪显式。scope 精确匹配、不做父级兜底:按 project 查却回退到 global 看起来友好,代价是作用域失去意义——只该在某个项目里生效的记忆会在任何会话里生效,而报告完全正常。同 ID 只留最新(两条正文不同的同 ID 记忆让读者只能猜)
delegate176oekit/pkg异构委托的契约面:ACP 一类东西同时是协议 + 传输,线格式归上游;本包只定跨传输恒定的三条。① 能力必须子集(做不到就拒,不许「尽力而为」——尽力而为的结果无法判定「没做到」与「本来就没要求」);② 最小能力原则选执行方:多个都能接时取能力最少者,同数量按名字——按顺序取第一个是错的,顺序通常来自配置文件书写次序,一次无关重排就会换掉执行方;③ 回执状态三值(completed / failed / refused),且 completed 不得带 Failure、failed 与 refused 必须带原因——把「被拒绝执行」混进「执行失败」会让委托方去修一个不存在的 bug
worktree232oekit/pkg工作区隔离的声明面与冲突判据(不碰真实文件系统——建目录/挂载/chroot 是宿主与执行后端的活)。并行工作区会不会互相踩此前没人判:两个 agent 各自「在自己的目录里工作」,可写区完全重叠时任何一边的写入都会让另一边的结论失效,而报告里只有两份「各自成功」。判三件:声明自检(同一工作区不得既只读又可写)、可写区重叠即冲突(只读重叠不算——多个人读同一份文件没有危害,写没有第二份真相)、无命中即不可读写(fail-closed:默认允许会让漏写的一行声明变成全域可写)。不支持通配(写明的局限):* 与 ** 的语义各实现不同,进契约就会出现「按 A 的理解写、按 B 的理解判」,需要更强表达力时宿主自己展开成多条精确声明
ticket203无一次性短时授权票据的机制面:签发 / 单次消费(用过即焚)/ TTL / 用途绑定(载荷原样携带,语义归宿主)。⭐ 过期判定与消费判定同一处(两处各判一次必有一处漂);时钟可注入——过期语义要能被确定性测,不靠 sleep(靠 sleep 的话「等到了」会被当成「判对了」,判定写反了测试照样绿);票据空间有界且满了显式拒发(默默淘汰会让宿主以为票据还在、实际已失效 ⇒ 表现为「偶发地连不上」,极难查);随机源失败显式报错(不降级成可预测 id——id 一旦可预测,单次消费就没意义了)。进程内存储(重启即失效)对「只活几十秒的票据」是正确默认:落盘即多一份要擦的痕迹

工程底座基线

指标值判定
生产代码28,332 行 / 154 文件make docsync 判相等,不留容差
测试192 个测试文件同上
覆盖率门槛全局 60% + 逐包下限 70%make cover-gate 判(实测值随用例批次漂,不抄进散文)

门禁规则清单(rules 段,8 条)

规则说明
harness-no-domain-vocabulary内核生产代码不得含运维领域词表(词表属于宿主/领域包)
harness-test-fixture-domain-vocabulary测试夹具必须使用合成数据,不得携带真实运维词面
harness-no-host-dependency内核不得依赖宿主仓任何包
harness-no-domain-runtime-deps内核不得引入宿主仓与领域运行时(含已退役的 agentkit 门面)
harness-no-bare-goroutine生产代码禁止裸 goroutine 启动(panic 无法被外层 recover,会杀进程);须走 concurrency/async 的 GoSafe
harness-no-printf-log-callbackSDK 包不得把 printf 风格日志回调焊进公开 API 签名;留痕走 logx.Delegating
harness-single-errors-package全仓只允许 oekit/pkg/errors 一套 errors 包(禁 stdlib errors 与 github.com/pkg/errors)
harness-sandbox-execution-single-entry外部程序执行只允许经 ptc 执行后端;其余生产代码不得直接 import os/exec

结构性判定(门包不变 / 依赖方向 / 沙箱档位登记 / 执行路径 / 子进程出口)走 go/ast, 声明面在 architecture-policy.yaml 的 facades / dependency_direction / sandbox_providers / execution_paths 各段。

第一方依赖(9 个模块)

独立发版、版本化引入、零 replace(go.mod 含 replace 即门禁红)。

模块版本
github.com/oagentkit/agentv0.14.8
github.com/oagentkit/guardxv0.24.1
github.com/oagentkit/runtimev0.12.6
github.com/oagentkit/toolgatev0.17.0
github.com/oagentkit/toolsv0.14.3
github.com/oekit/concurrencyv0.32.0
github.com/oekit/logxv0.9.2
github.com/oekit/pkgv0.42.0
github.com/oagentkit/mcpkitv0.12.8

本仓处在 oekit(基础库)→ oagentkit(agent 原语)→ goagent-kernel(编排内核)→ 宿主的同一条依赖链上。

Next
门禁体系