宿主环境感知(INV-ENV)
wesgine 自动感知主机环境(操作系统、已安装工具、运行时版本等),并将结果注入 Memory 的 Environment 层。
核心设计:每进程感知一次
一台机器只被感知一次,且感知器不认识租户。
memenv.SharedSnapshot(ctx) ← 唯一入口(single-flight + 5min TTL)
capenv.SharedSurface(ctx) ← 唯一入口(single-flight + 5min TTL)
为什么不 per-Cell
答案不因租户而异。持 N 个 Cell 的进程付 N 次字面相同的钱,全落在 Cool→Warm 的 100-500ms 预算上。
反模式
| 禁止 | 正确做法 |
|---|---|
| 同一台机器被感知两遍且每 Cell 一遍 | SharedSnapshot / SharedSurface |
感知器里出现 CellID / Actor / Tenant | per-Cell 事实层叠在消费者上 |
command -v / which 每个工具 fork 一次 | exec.LookPath(零 fork) |
两个感知包
internal/memory/env
检测主机上的工具和运行时:
- Go / Python / Node / npm / pnpm / yarn
- Docker / kubectl / git
- 操作系统类型和版本
- Shell 类型
- 其他开发工具
internal/govern/capability/env
检测已安装的包和应用:
pip3 listnpm ls -g/Applications扫描(macOS)
per-Cell 层叠
共享快照不含租户信息。per-Cell 事实在消费者上层叠:
loader.WithRuntimeOverrides(cellSpec.HostEnvironment)
例如:某 Cell bundled 了 Python 3.11,而主机是 3.9 → 引擎为该 Cell 覆盖 Python 版本。
探测预算
| 探测器 | 预算 |
|---|---|
| envSeedBudget | 15s |
| capabilitySurfaceBudget | 25s |
| providerProbeBudget | 10s |
预算取 min(自身预算, 父 ctx 剩余)。ctx 已死则不缓存。
深拷贝保护
EnvSnapshot.clone() 是共享缓存的唯一防线:
- 逐字段深拷所有 map / slice
- 用反射校验(含 vacuity guard:反射一个字段都没查到时同样失败)
感知结果去向
SharedSnapshot → Environment 层 Memory
↓
L1 环境信息
↓
系统提示词的环境段
Environment 层记忆:
ScopeSystem- 无 actor(共享事实)
- 不可由用户写入(
ErrLayerNotWritable)
闸门
scripts/audit-lock/38-host-env-shared.sh
三条约束缺一不可:
- 每包只有
shared.go一个构造点 - 包外任何 alias 都不得构造(含测试)
- 感知包内不出现
CellID/Actor/Tenant
相关文档
- 记忆层模型 →
memory-layer-model.md - Cell 温度转换 →
cell-temperature-transitions.md - 记忆写入管线 →
memory-write-pipeline.md