| Context、Plugin 与 Fiber 分别表示作用域入口、可执行定义和运行实例 |
Context.extend、Plugin 类型 与 Fiber 状态/字段 |
同一 Plugin 可产生多个 Fiber;插件 Context 属于运行实例,不是进程全局容器 |
| Effect 将 disposer 归属 Fiber,但只有单个 effect 内有逆序串行语义 |
DisposableList、ctx.effect 与 Fiber unload |
同一 effect 的 disposer 逆序执行;顶层 effects 通过 Promise.all 收敛,不能假定跨 effect 串行 |
| inject 建立动态 provider-consumer 关系 |
ctx.inject 与 Plugin inject、依赖 epoch 与 reload 与 Service notify/provide |
依赖缺失时 pending;provider 消失或身份变化时 consumer 卸载,并在依赖恢复后重跑 |
| Service 访问区分声明依赖和可选探测 |
直接属性访问检查 与 Context.get |
ctx.service 要求 inject 且 provider active;ctx.get() 是显式可选查询 |
| emit、bail、serial、waterfall 具有不同等待和短路语义 |
isBailed 与 dispatch 实现 与 emit/serial/bail/waterfall |
bail 值不是普通 truthy;waterfall 以 next() 表达委托,不调用即接管/短路 |
| DSH 用 waterfall 实现 Step 准入和请求错误恢复 |
事件类型契约 与 默认 Agent 调用点 |
next() 是把控制交给后续插件或默认实现;事件模式直接参与 Agent 控制流 |
| Profile 配置按层组合,同 id 后层替换整行 config |
composeProfile、base patch 规则 与 applyEntryPatches |
bundle、profile、home、CLI 与 telemetry overlay 构成最终树;config 不是递归深合并 |
| Web 与 Headless profile 从空根选择不同 bundle 序列 |
profile 模板(bundle 序列选择,PROFILE_TEMPLATES) 与 启动器重写空根 |
Web 使用 base→web-app,Headless 使用 base→headless;cordis.yml 被启动器无条件重写为空数组(profile-boot.ts:60-64,98-103),只是 include 锚点而非手工维护的最终树 |
| base、Web 与 Headless 是共享主干上的不同 patch 形状 |
base 共享树、Web Host/Client 与 Agent-plane 重组 与 Headless 三个新增 row |
固定提交中 base 插入 78 个 row;Web 新增 51 个并修改/禁用 27 个;Headless 新增 3 个并修改 3 个。数量仅描述装配差异 |
| Web 启动参数经 Service 依赖进入 bind 与 trust 配置 |
web-startup 解析并 provide、Web row inject 链 与 webRuntime 发布及 readiness |
!!js ctx.webStartup.* 要等依赖满足后求值;Web readiness 还等待 Loader settlement,不是静态 YAML 顺序 |
| 启动器把 shipped agent preset 根作为只读装配补丁注入 |
装配补丁注入 agent-presets row(SHIPPED_PRESET_ROOT 定义于同文件 L34-35)与 preset trust 语义 |
只读 shipped root 位于 apps/cli/config/agent-presets/(code/cordis/minimal/standard),以 trust: 'system' 注入 agent-presets row 的 roots;该补丁只出现在 live boot,不进 dump |
| Headless 是等待整树稳定、flush 会话后退出的一次性驱动器 |
Headless patch 入口链 与 runner 的 create/followup/idle/flush/output |
它直接复用 core Agent/Session,不挂 Host/Browser;固定入口创建新 Session,不能从 core resume 能力推断 CLI 已提供 resume |
| config dump 可追踪用户层来源,但不是完整 live runtime 快照 |
runDumpConfig 的层选择、dump 的 provenance 算法 与 live boot 追加 assembly/telemetry patch |
dump 不求值 !!js(表达式原样输出);对照两条代码路径,CLI dump 不包含 live boot 追加的 shipped preset root 与 telemetry hard-disable,这是源码推论 |
| 发布 CLI 测试约束 Web/Headless dump 的产品边界 |
built-bin config dump cases |
测试声明 Web 包含 Host row、Headless 不含 Host/Web/Client row,并验证 overlay 覆盖及来源注释;本仓库当前未安装依赖,未在本轮重跑 |
| Loader 的配置替换带等待与回滚,但局部模块 HMR 不是外部事务 |
Entry update/dispose/rollback、Group rollback、Registry delete 不等待 dispose 与 模块 HMR 重载 |
配置 entry 替换会等待旧 Fiber dispose;模块 HMR 可恢复缓存并尽力重建旧插件,但不保证外部副作用回滚或所有异步 disposer 与新实例隔离 |
| Web 与 Headless 关闭共享模块 HMR,但启动器保留配置 watch fallback |
Web patch、Headless patch 与 watch-only HMR 装配 |
固定产品面把代码模块热替换与用户 patch 热刷新分开;不能笼统声称 Web/Headless 已启用完整 HMR |
| Agent Loop 是可注册 Service |
AgentLoop 声明依赖并实现 factory |
默认循环参与 Cordis 服务装配,不是唯一不可替换入口 |
| followup、steer、inject 进入不同 inbox 目标 |
Agent.send/followup/steer/inject |
三种输入具有不同调度语义 |
| Turn/Step 事实被追加到 Session |
turn() |
正常、阻断、错误和取消都落在明确边界 |
| 模型历史从日志投影 |
step() 调用 deriveMessages() |
模型请求不以另一份独立消息数组为权威来源 |
| 请求配置也进入事实日志 |
buildRequest() 写 request header/context |
provider、model、system 和 tools 可随会话重建 |
| 工具 body 可并发但结果按模型顺序提交 |
executeToolCalls/runGroup |
并发执行不改变模型可见的结果顺序;取消会停止补充调用并收敛已启动调用 |
| Agent dispose 等待驱动器和 scope 收敛 |
AgentLoop.prepare() 的反向 teardown |
卸载不仅撤销 registry,还等待进程内 Agent 工作停止 |
| Profile/Bundle 形成产品装配 |
架构文档中的装配顺序 |
Web/Headless 是配置装配而非两套独立核心;属于实现文档与配置共同证据 |
| SessionEvent 是连续、不可变的 append-only 事实 |
SessionEvent 信封 与 Session.append() |
模型可恢复事实在写入处完成 JSON 校验、连续 seq 分配与冻结;observer 失败不撤销提交 |
| 模型历史是 surface 投影,replacement 不改写旧事件 |
deriveEventMessage 与 deriveMessages |
current model context 与 append-origin transcript 是同一日志上的不同读模型 |
| 持久化采用 write-behind,flush 是显式耐久屏障 |
持久化 listener 与 drain 与 flush |
append 热路径不等待 I/O;checkpoint 必须显式 flush |
| checkpoint 在模型请求与顶层工具副作用之前 fail-closed |
session-checkpoint-policy |
能证明动作前缀已耐久,不能证明日志与外部副作用跨系统原子 |
| 冷恢复保留完整事件并为 open tail 合成确定性 closer |
interruptedTurnClosers 与 prepare/repair 提交 |
区分未开始工具与 outcome unknown;非幂等副作用仍需外部核验 |
| fork 只接受 live session 的闭合前缀 |
SessionStore.fork |
fork 是带 parent/seed lineage 的新会话,不复制活动调用栈 |
| JSONL 和 SQLite 共享语义但物理提交边界不同 |
JSONL materialize/append/fsync 与 SQLite append/repair 事务 |
后端可以替换,但备份、retention、writer ownership 与恢复演练仍是部署责任 |
| context 管理通过新事件替换 surface,而非删除历史 |
tool-result pruner replacement |
压缩后模型视图变小,append-only 原始历史仍可审计 |
| 能力 seam 由 Definition/Provider/Consumer 三角色组成 |
capability-seams 角色说明 与 seam 清单 |
可替换能力的验收条件是声明分离、冲突 fail loud、原子替换、卸载撤销;“接口存在”不足以证明可替换 |
ctx.llm 注册全有或全无,替换原子,卸载后旧句柄失效 |
registerAdapter 与 commitRoutes |
重复 provider 抛 DUPLICATE_ADAPTER;replace 同步段内换路;disposer 后抛 REGISTRATION_DISPOSED |
模型调用经 llm/stream waterfall,解析与派发绑定同一注册 |
waterfall 契约 与 prepareCall |
深冻结 config 只派发一次;config 变化抛 INVALID_PREPARED_CALL,HMR 换 adapter 不混配解析结果 |
| 模型能力不支持时在 provider I/O 前拒绝,无降级或别名 |
resolveCallFor 的 reasoning 校验 |
显式 effort 不支持抛 UNSUPPORTED_REASONING_EFFORT;目录清单是建议性的,不参与请求路由 |
| adapter 失败归一化为终止 chunk,错误码 provider 无关 |
adapterStream 终态处理 与 LlmError |
选择/派发/迭代失败成为 error/aborted finish chunk;中间件失败保持抛出 |
| 凭据引用与值分离,按操作解析 |
llm-deepseek 解析路径、credentials seam 说明 与 密钥校验 |
轮换后的凭据在下一次请求生效;诊断只报引用位置,不回显密钥 |
| 工具流水线顺序与各阶段权限 |
事件契约与 guard、finalizeContent、结果冻结 与 单调 guard |
拒绝单调、审批一次性、guard 只能收紧;tools/result 前结果已冻结 |
| tool-fs 写操作经 fs/write-intent、fs/edit-intent 单一决策槽 |
fs-observation-policy 占据决策槽 |
意图门禁不调用 next();fs/observed 同步且不抛错 |
| FS 写操作携带版本守卫,字面量编辑返回前后内容 |
FsVersion 与写意图 与 字面量编辑结果 |
createIfAbsent/replaceIfVersion 由 stat/write 结果提供版本,Provider 不自行制造 |
| 子进程终止是进程树级的,带信号升级 |
SubprocessHandle 契约 与 AbortSignal 触发 |
POSIX 信号分离进程树、Windows taskkill /T;SIGTERM→graceMs→SIGKILL 幂等升级 |
| sandbox-local 按策略生成平台 profile,策略根唯一 |
bwrap/sandbox-exec profile 构造 与 sandboxPolicy 说明 |
bash 与 fs 两类强制组件读同一策略根,不会各自限制到不同根 |
| system prompt 由 sections/context/tools/variables 组装,动态 context 物化为持久快照 |
system-prompt/assemble 与注册契约 |
多个生效 complete section 时组装失败;`` 在组装期插值 |
| 长任务状态分三档归属:日志折叠、进程内、Provider 侧 |
goal 纯回放折叠、jobs 注册契约 与 subagent 请求契约 |
goal/plan/todo 能从日志折叠;jobs-local、terminal 随进程消失;固定提交只证明注册面与归属,不证明跨重启恢复或分布式调度 |
| fork 子会话以父会话完成 turn 前缀为 seed,记录 parentSession |
fork-in-process seed 定义 与 子会话 id 归属 |
seed 止于最后一次 turn/end,当前 tool-call turn 不进入;spawn 创建全新子会话 |
| workflow 引擎终止路径合成 cancelled 终态 |
引擎终态 |
worker 超过宽限被杀时 outcome 为 cancelled;引擎每 Context 一个,worker-thread 是 Provider |
| 动态扩展三身份(plugin/package/run)独立铸造 |
registry.ts#L154-L183、types.ts#L10-L16 |
本地核验 mint 函数与 brand 定义 |
| define 校验并保存不可变 package 定义 |
index.ts#L151-L202、registry.ts#L37-L48 |
本地核验 define 路径与 packages Map |
| client 代码激活需审批,approveFutureVersions 覆盖后续版本 |
index.ts#L277-L282、registry.ts#L58-L61 |
本地核验 requiresApproval 判定 |
| Host half 在 node:vm 沙箱求值,注释明示非隔离 |
sandbox.ts#L2-L7 |
源码注释直述 |
| Typert registry 原子注册并以 effect 卸载 |
service.ts#L189-L212 |
本地核验 register 与 disposer |
| /api 信任围栏:loopback/trustedHosts,跨站拒绝 |
api-request-trust.ts#L41-L57、#L74 |
本地核验 Host 校验路径 |
| 双 WebSocket 只下行,客户端上行属协议违规 |
websocket-downlink.ts#L48 |
本地核验注释与泵流实现 |
| Headless flush→stdout→按 completed 决定退出码 |
headless/src/index.ts#L127-L133 |
本地核验 |
| ACP 每会话单 in-flight 槽,等待整 Agent idle |
acp/src/index.ts#L281、#L297-L327 |
本地核验 |
| SDK run() 区间:inbox receipt→idle,finalResponse 非因果归属 |
sdk/client/src/api.ts#L140-L190、types.ts#L61-L66 |
本地核验 |
| 工具执行五阶段与单调 guard |
packages/core/tools/src/index.ts#L142-L207、#L703-L711 |
事件契约与 guard 类型;调度顺序由 agent-loop/src/tool-calls.ts:215-242 佐证 |
| approval 审计对与 fail-closed 结果 |
packages/interaction/user-approval/src/index.ts#L239-L276 |
request() 的 turn 内审计对与 outcome 归一 |
| 升级必须严格更宽且先批后行 |
packages/sandbox/sandbox/src/escalation.ts#L157-L188、packages/fs/tool-fs/src/sandbox.ts#L87-L130 |
执行期更宽检查;fs/bash 共用词汇与 [sandbox: …] 标记 |
| workspace-write containment 与 TOCTOU 防护 |
packages/fs/fs-sandbox/src/index.ts#L115-L148、packages/sandbox/sandbox/src/roots.ts#L52-L54 |
新鲜规范化、写根集合、返回新鲜目标 |
| 观测策略的读后写状态门 |
packages/fs/fs-observation-policy/src/index.ts#L61-L88 |
writeIntent/editIntent 与 FS_NOT_OBSERVED |
| 平台 runner 链与 Windows ACL 部分强制 |
packages/sandbox/sandbox-local/src/index.ts#L1-L25 |
探测顺序与 fail-closed;ACL 限制为源码注释 |
| 进程树收敛与凭据擦洗 |
packages/subprocess/subprocess-local/src/index.ts#L2-L5、#L33-L34 |
进程组信号、退出阶段强制、环境擦洗 |
| 凭据分层且不进进程环境 |
packages/credentials/credentials-local/src/index.ts#L5-L34、#L309-L315 |
严格 CredentialRef 映射与 resolve 顺序 |
| request/header 无凭据字段 |
packages/llm/llm/src/call-config.ts#L23-L30、packages/llm/llm-deepseek/src/adapter.ts#L218-L284 |
日志配置字段表与 wire 头分离 |
| 默认装配的权限/审批/遥测/查询开关 |
packages/bundle/base/cordis.patch.yml#L83-L205 |
默认 mode、preset、telemetry DISABLED、openAt never |
| 事故复盘:Landlock 部分强制执行误归类 |
docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md |
文档记录;约束未被削弱的失败模式 |
| 测试策略按证据强度分层 |
测试层级列表 |
官方文档定义单元/覆盖率/e2e/快照/Web 快照各自的证明力与边界 |
| 覆盖率门禁按文件 100%,是必要条件 |
覆盖率条目 |
行执行覆盖不等于功能按交付预期工作;pwsh 缺失时其执行器套件自动跳过并有豁免 |
| 真实 API e2e 缺密钥自动跳过 |
e2e 条目 |
各 provider 由各自密钥控制(EXA_API_KEY、PERPLEXITY_API_KEY 等);跳过项不构成证据 |
| 快照 keyless 固定协议、transcript 与持久日志 |
快照条目 |
ACP 启动真实服务器回放录制会话;headless 场景经 JSONL 测试 driver;不能证明真实 provider |
| Web 浏览器快照为必需 Linux PR 门禁 |
Web 快照条目 |
Chromium 回放与 apps/web/tests/snapshots/ 比较;CI 强制只读 replay,record/refresh 留在本地 |
| 真实入口路径指已发布构建产物 |
真实入口路径 与 测试解析仅限源码 |
bin 运行构建后的 lib/bin.js;测试解析指向 src,构建产物只在显式指定时使用 |
| Agent 结果必须由外部世界复核 |
验证外部世界条目 |
e2e 断言重新运行命令或重新读文件;对 agent 自身输出做关键词探测会让作弊的 agent 通过 |
| mock 只用于高成本或不确定边界 |
mock 条目 |
只 mock LLM 适配器、网络、时钟;下游保持真实 |
| 模型/协议/人类可见变更需同 PR 更新快照 |
何时需要快照测试 |
每项非平凡可见变更在可运行示例所属快照套件加无密钥场景 |
| invariants 注册包归属的运行时不变式 |
invariants 注册表 |
检查可观察的事件/数据关系,不检查“服务方法是否存在” |
| postmortem 0001—0004 是失效记录证据档 |
postmortem 目录 |
0001 落在协议与装配面、0004 落在沙箱强制面;证明团队记录过失效,不证明同类问题不会复发 |
| SessionEvent 格式版本仍为 0,不承诺兼容迁移 |
SESSION_FORMAT_VERSION 校验 |
header 版本不符即拒绝读取 |
| SQLite 磁盘版本不兼容时拒绝打开、不自动迁移 |
SCHEMA_VERSION 常量与检查 |
当前 SCHEMA_VERSION 为 15;on-disk 不匹配直接报错 |