docs(agent-presets): record that a preset file is never written back

The Loader writes a tree back to its source whenever it decides the
config changed, and a row disposing its own fiber is enough to decide
that. The mounted subtree overrides `write()` as a no-op for that
reason — a fact that lived only in a PR description, so nothing in the
repo said why the override exists or what removing it would cost.
This commit is contained in:
Yichen Jiang
2026-08-07 00:35:30 +08:00
parent 25b6381c84
commit 523d95a9cf
3 changed files with 14 additions and 2 deletions
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/preset/agent-presets/README.md
README.md: e53a52f145b3f66ab115b93c614561fed8194719
README.zh.md: 39b470002816f309c8ec9af1d72e04495b020ad7
README.md: 8c95719bead97845519b7a334603005df201a34d
README.zh.md: c5e2fd3c7896437ddb4a2acdf101cd2e0e0eedaf
+6
View File
@@ -42,6 +42,12 @@ A directly-plugged subtree is absent from `ctx.loader.entries()`, so no boot aud
The package invariant re-checks that last rule on every service notification, because a row that publishes from a timer or an asynchronous continuation would escape the one-shot audit.
## A preset file is an input, never a persistence target
The Loader writes a tree back to its source file whenever it decides the config changed, and a row disposing its own fiber is enough to decide that: the entry is marked `disabled` and the tree is written. Inherited, that would burn one session's runtime state into a file every session shares — comments stripped by the YAML round trip, and a `writeFile` rejection inside a `setTimeout` for a read-only shipped preset.
The mounted subtree therefore overrides `write()` as a no-op. Nothing in this package writes a composition; authoring one is a separate, explicit operation.
## Trust
Presets are compositions, so a preset is exactly as privileged as the plugins it names. A `user` preset — authored by a person or by an agent — carries the same trust as shell access; the `trust` field exists so consumers can present that difference, not to enforce it.
@@ -42,6 +42,12 @@ agent 工厂的 `setup(agentCtx)` 钩子是唯一受支持的调用点。只有
最后一条规则由本包的运行时不变量在每次服务通知时复查,因为从定时器或异步续体中发布的行会绕过一次性审计。
## preset 文件是输入,不是持久化目标
只要 Loader 认为配置变了,它就会把树写回源文件——而一个行释放自己的 fiber 就足以让它这么认为:该 entry 被标记 `disabled`,随即触发写回。若继承该行为,一个会话的运行时状态就会被烧进所有会话共享的文件里:YAML 往返会抹掉注释,而对随附的只读 preset,`writeFile` 还会在 `setTimeout` 内抛出无人接管的 rejection。
因此被挂载的子树把 `write()` 覆写为空操作。本包不写任何组装;创作组装是另一件独立且显式的操作。
## 信任
preset 就是组装,因此一个 preset 的权限恰好等于它所引用的插件。`user` preset——无论由人还是由 agent 写出——与 shell 访问权限同级;`trust` 字段的存在是为了让消费方呈现这一差异,而不是用来强制隔离。