@c956180462/awbs 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AWBS_CORE_DESIGN.md +983 -0
- package/AWBS_CURRENT_FEATURES.md +463 -0
- package/LICENSE +21 -0
- package/README.md +265 -0
- package/TASK_001_VIEW_AUTHORITY.md +446 -0
- package/TASK_003_AUTHORITY_LEDGER_AND_DB_AUDIT.md +268 -0
- package/TASK_004_TRUSTED_AUTHORITY_LAYER.md +547 -0
- package/TASK_005_AUTHORITY_SESSION.md +218 -0
- package/TASK_006_TRUST_BOUNDARY_HARDENING.md +381 -0
- package/TASK_007_TRUSTED_OPERATION_ENTRY.md +129 -0
- package/bin/awbs.js +2 -0
- package/docs/DEVELOPMENT_LEARNING.md +319 -0
- package/docs/FULL_CHAIN.md +295 -0
- package/docs/PRODUCT.md +188 -0
- package/docs/USAGE.md +294 -0
- package/package.json +45 -0
- package/src/adapters/file-summary-store.ts +88 -0
- package/src/adapters/git-cli.ts +107 -0
- package/src/adapters/local-authority-session.ts +606 -0
- package/src/adapters/local-file-database.ts +199 -0
- package/src/adapters/sealed-authority.ts +725 -0
- package/src/adapters/session-authority-client.ts +176 -0
- package/src/adapters/sqlite-index-store.ts +176 -0
- package/src/cli.ts +491 -0
- package/src/domain/authority-types.ts +194 -0
- package/src/domain/constants.ts +11 -0
- package/src/domain/errors.ts +6 -0
- package/src/domain/hash.ts +27 -0
- package/src/domain/path-policy.ts +36 -0
- package/src/domain/paths.ts +65 -0
- package/src/domain/session-proof.ts +140 -0
- package/src/domain/session-types.ts +101 -0
- package/src/domain/types.ts +94 -0
- package/src/ports/authority-session.ts +8 -0
- package/src/ports/authority.ts +26 -0
- package/src/ports/file-database.ts +18 -0
- package/src/ports/git.ts +23 -0
- package/src/ports/index-store.ts +7 -0
- package/src/ports/summary-store.ts +16 -0
- package/src/runtime.ts +56 -0
- package/src/session-entry.ts +1 -0
- package/src/usecases/authority.ts +53 -0
- package/src/usecases/changeset.ts +437 -0
- package/src/usecases/db.ts +192 -0
- package/src/usecases/index.ts +136 -0
- package/src/usecases/init.ts +48 -0
- package/src/usecases/ledger.ts +146 -0
- package/src/usecases/session.ts +48 -0
- package/src/usecases/trusted-chain.ts +56 -0
- package/src/usecases/view.ts +166 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# AWBS 005:A 模式 Authority Session
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
005 实现 **A 模式 / 运行期本地钥匙托管**。
|
|
6
|
+
|
|
7
|
+
它不创建 Windows / Linux 用户,不接操作系统 keychain,不做系统服务。005 的目标是先把 AWBS 的可信写入从“CLI 直接读取 `.awbs/private/local.json`”升级为:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
上层应用的非 AI 控制层
|
|
11
|
+
-> 通过 stdin 注入 recoverySecret + controllerToken
|
|
12
|
+
-> 启动 AWBS authority session
|
|
13
|
+
-> session daemon 读入 local key
|
|
14
|
+
-> 删除磁盘 local.json
|
|
15
|
+
-> agent 生命周期内不能通过文件系统顺手读取 key
|
|
16
|
+
-> 可信写入必须带 controller token
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
这里的恢复因子不是 AWBS 内置的人类交互密码。它由上层应用的非 AI 调度层提供;人类、后端服务、supervisor、部署系统都可以是上层来源,但 agent 工作流本身不应持有它。
|
|
20
|
+
|
|
21
|
+
## Core Boundary
|
|
22
|
+
|
|
23
|
+
005 仍然不是强安全沙箱,也不承诺对抗 admin/root。
|
|
24
|
+
|
|
25
|
+
它解决的是一个具体问题:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
强 agent 在自己的普通工作生命周期中,不应该能从 repo 文件系统直接读到 authority key。
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
因此,005 把 key 的生命周期改成:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
session stopped:
|
|
35
|
+
.awbs/private/local.json 存在
|
|
36
|
+
适合维护、备份、启动下一次 session
|
|
37
|
+
|
|
38
|
+
session active:
|
|
39
|
+
.awbs/private/local.json 不存在
|
|
40
|
+
key 只在同用户后台 session daemon 内存中
|
|
41
|
+
.awbs/private/recovery.seal.json 存在
|
|
42
|
+
|
|
43
|
+
session crashed:
|
|
44
|
+
local.json 不存在
|
|
45
|
+
recovery.seal.json 存在
|
|
46
|
+
AWBS 进入 authority unavailable
|
|
47
|
+
必须显式 recover
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Actor Model
|
|
51
|
+
|
|
52
|
+
005 区分两类 actor:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
host controller
|
|
56
|
+
上层应用的非 AI 控制层。
|
|
57
|
+
持有 recoverySecret / controllerToken。
|
|
58
|
+
可以启动、停止、恢复 session。
|
|
59
|
+
可以授权可信写入。
|
|
60
|
+
|
|
61
|
+
workflow agent
|
|
62
|
+
在工作空间中执行任务。
|
|
63
|
+
可以读取视图、生成 changeset、请求诊断。
|
|
64
|
+
不应持有 recoverySecret、controllerToken 或 raw key。
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
这条边界很关键。否则 agent 虽然拿不到 key,却仍然可以自己调用 `view create --write A`,让 authority 帮它创建新的可写视图。005 因此要求可信写入必须带 `controllerToken`。
|
|
68
|
+
|
|
69
|
+
## CLI
|
|
70
|
+
|
|
71
|
+
新增命令:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
awbs authority session start --control-stdin
|
|
75
|
+
awbs authority session status [--json]
|
|
76
|
+
awbs authority session stop --control-token-stdin
|
|
77
|
+
awbs authority session recover --recovery-secret-stdin
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`--control-stdin` 读取 JSON:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"recoverySecret": "...",
|
|
85
|
+
"controllerToken": "..."
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`controllerToken` 和 `recoverySecret` 不通过 argv 传递,不写入 workspace,不写入 `.awbs/private/session.json`。
|
|
90
|
+
在 session IPC 中,CLI 不发送 raw `controllerToken`,而是发送包含请求 hash、nonce 和 createdAt 的 HMAC controller proof。session daemon 会记录已使用 nonce,拒绝重放;可信写入成功响应也必须带 response proof,CLI 会验证后才承认成功。
|
|
91
|
+
|
|
92
|
+
需要 controller token 的可信写入命令:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
awbs ledger bootstrap --control-token-stdin
|
|
96
|
+
awbs view create ... --control-token-stdin
|
|
97
|
+
awbs view revoke <viewId> --control-token-stdin
|
|
98
|
+
awbs changeset apply <changesetId> --control-token-stdin
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
裸 CLI 没有 `--control-stdin` 时不能启动 session;AWBS 不自动生成 secret,不弹人类口令,不把恢复因子藏进自己的配置文件。
|
|
102
|
+
|
|
103
|
+
## Files
|
|
104
|
+
|
|
105
|
+
005 使用这些运行材料:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
.awbs/private/local.json
|
|
109
|
+
session stopped 时存在。
|
|
110
|
+
session active 时删除。
|
|
111
|
+
|
|
112
|
+
.awbs/private/session.json
|
|
113
|
+
只记录 repoId、pid、socketPath、startedAt、status。
|
|
114
|
+
不包含 key,不包含 recoverySecret,不包含 controllerToken。
|
|
115
|
+
|
|
116
|
+
.awbs/private/recovery.seal.json
|
|
117
|
+
使用 recoverySecret 派生 key 加密 AuthorityLocal。
|
|
118
|
+
只用于显式 recover。
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`.awbs/private/` 继续被 Git 忽略,不进入 AWBS 可信数据库内容。
|
|
122
|
+
|
|
123
|
+
`repo.json` 增加:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"trustMode": "ephemeral-local-key-v1"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
开发期不做旧仓库兼容。仓库缺少 `trustMode` 时,`authority session start` 应拒绝继续运行,并要求用当前 AWBS 结构重新初始化。
|
|
132
|
+
|
|
133
|
+
## Failure Behavior
|
|
134
|
+
|
|
135
|
+
正常停止:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
awbs authority session stop --control-token-stdin
|
|
139
|
+
-> daemon 写回 local.json
|
|
140
|
+
-> 删除 recovery.seal.json
|
|
141
|
+
-> 删除 session.json
|
|
142
|
+
-> 退出
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
异常退出:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
local.json 不存在
|
|
149
|
+
session.json 可能残留
|
|
150
|
+
recovery.seal.json 存在
|
|
151
|
+
可信写入拒绝
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
恢复:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
awbs authority session recover --recovery-secret-stdin
|
|
158
|
+
-> 解开 recovery.seal.json
|
|
159
|
+
-> 写回 local.json
|
|
160
|
+
-> 删除 stale session.json
|
|
161
|
+
-> 删除 recovery.seal.json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
错误的 recoverySecret 必须失败,不能写出伪成功的 `local.json`。
|
|
165
|
+
|
|
166
|
+
## Current Implementation
|
|
167
|
+
|
|
168
|
+
005 当前实现是同用户后台 session daemon:
|
|
169
|
+
|
|
170
|
+
```text
|
|
171
|
+
CLI
|
|
172
|
+
-> hidden local IPC request
|
|
173
|
+
-> session daemon
|
|
174
|
+
-> SealedAuthorityAdapter(memoryLocal)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
session daemon 不暴露 raw key,不提供 `sign(rawHash)`。它只执行 AWBS authority 语义接口,例如读取 view contract、创建 view、撤销 view、封存 changeset receipt、记录 changeset apply 和修复 mirror。
|
|
178
|
+
|
|
179
|
+
为了保持第一版简单,IPC 使用本机回环 TCP endpoint,并把 endpoint 记录为 `session.json.socketPath`。这不是远程服务,也不是网络信任模型;它只是本机 CLI 和同用户 daemon 之间的通信方式。
|
|
180
|
+
daemon 启动后绑定到启动仓库;请求 root 只能是该仓库,或同一 Git common dir 下的 AWBS 临时 worktree。复制 repoId / session.json 到另一个仓库不能让 daemon 服务该仓库。
|
|
181
|
+
|
|
182
|
+
## Not In 005
|
|
183
|
+
|
|
184
|
+
005 不实现:
|
|
185
|
+
|
|
186
|
+
- OS 用户隔离。
|
|
187
|
+
- Windows DPAPI / Credential Manager。
|
|
188
|
+
- Linux keyring / Secret Service。
|
|
189
|
+
- 独立系统服务 `awbsd`。
|
|
190
|
+
- remote signer。
|
|
191
|
+
- admin/root 防护。
|
|
192
|
+
|
|
193
|
+
B 模式和独立 Authority Service 仍然是后续方向。
|
|
194
|
+
|
|
195
|
+
## Verification
|
|
196
|
+
|
|
197
|
+
005 增加测试覆盖:
|
|
198
|
+
|
|
199
|
+
- session start 后 `local.json` 被删除。
|
|
200
|
+
- `session.json` 不含 key / token / recoverySecret。
|
|
201
|
+
- 无 controller token 的可信写入被拒绝。
|
|
202
|
+
- raw controller token 不能直接作为 IPC 请求通过。
|
|
203
|
+
- controller proof 不能重放。
|
|
204
|
+
- 未带 response proof 的伪成功响应会被 CLI 拒绝。
|
|
205
|
+
- 复制 session.json/repoId 到另一个 Git 仓库不能复用 session。
|
|
206
|
+
- session active 时可完成 bootstrap、view create、collect、apply。
|
|
207
|
+
- session stop 后 `local.json` 写回,session/recovery 状态清理。
|
|
208
|
+
- 模拟 session 崩溃后可信写入拒绝。
|
|
209
|
+
- 错误 recoverySecret 恢复失败。
|
|
210
|
+
- 正确 recoverySecret 能恢复 `local.json`。
|
|
211
|
+
|
|
212
|
+
回归命令:
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
npm test
|
|
216
|
+
node src\cli.ts --help
|
|
217
|
+
npm pack --dry-run
|
|
218
|
+
```
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# AWBS 006:可信边界加固问题记录
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
006 记录可信事实层实现暴露出的边界问题,并完成第一轮实现修复。
|
|
6
|
+
|
|
7
|
+
这些问题的核心不是“沙箱逃逸”,也不是操作系统权限问题,而是 AWBS 自己的数据库可信链还没有完全收束成少数硬机制:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
AWBS 认证数据库
|
|
11
|
+
!= 当前工作区
|
|
12
|
+
!= 普通 Git HEAD
|
|
13
|
+
!= agent 可写文件系统
|
|
14
|
+
|
|
15
|
+
AWBS 认证数据库
|
|
16
|
+
= trusted chain 当前链头对应的 Git tree
|
|
17
|
+
+ authority 认可的 changeset / operation 记录
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
本任务的目标是把所有可能绕开可信链、污染 authority、破坏 Git 仓库、篡改 changeset payload、误导索引和摘要的路径记录下来,并用统一机制修掉第一批高风险问题。
|
|
21
|
+
|
|
22
|
+
## Development Compatibility Policy
|
|
23
|
+
|
|
24
|
+
AWBS 当前没有投产仓库,因此默认不考虑旧仓库兼容。
|
|
25
|
+
|
|
26
|
+
后续所有任务遵循这条规则:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
除非任务明确要求兼容旧仓库,否则 AWBS 永远不默认考虑旧仓库兼容。
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
这意味着:
|
|
33
|
+
|
|
34
|
+
- 可以直接修改数据结构。
|
|
35
|
+
- 可以直接废弃旧 manifest / authority / ledger 形态。
|
|
36
|
+
- 可以要求重新 init / bootstrap / create view。
|
|
37
|
+
- 不因为“已有开发期仓库”牺牲新可信链设计。
|
|
38
|
+
- 不把兼容迁移逻辑混进普通运行路径。
|
|
39
|
+
|
|
40
|
+
如果未来真的需要兼容旧仓库,必须单独开 migration 任务,明确迁移源版本、目标版本、校验方式和失败处理。
|
|
41
|
+
|
|
42
|
+
## Review Findings
|
|
43
|
+
|
|
44
|
+
### P0:workspace 可泄露 `.awbs/private`
|
|
45
|
+
|
|
46
|
+
`view create` 只拦截直接传入 `.awbs/private` 的情况,但如果传入:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
--read .awbs
|
|
50
|
+
--read .
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
就可能绕过直接检查。可信投影过程中如果把 `.awbs/private` 复制进 workspace,agent 就可能看到:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
.awbs/private/recovery.seal.json
|
|
57
|
+
.awbs/private/session.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
这直接违反 005 的边界:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
agent 生命周期内不应从 repo 文件系统读到 authority key / secret 材料。
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
涉及位置:
|
|
67
|
+
|
|
68
|
+
- `src/usecases/view.ts`
|
|
69
|
+
- `src/usecases/trusted-chain.ts`
|
|
70
|
+
|
|
71
|
+
修复方向:
|
|
72
|
+
|
|
73
|
+
- 建立统一 path policy。
|
|
74
|
+
- 默认拒绝投影 `.git`、`.awbs/private`、`.awbs/index`、`.awbs/views`、`.awbs/changesets`、`.awbs/tmp` 等系统目录。
|
|
75
|
+
- 对 `.`、父目录、包含系统目录的上级路径进行展开检查,而不是只做字符串直等判断。
|
|
76
|
+
- workspace 中永远不出现 AWBS private 材料。
|
|
77
|
+
|
|
78
|
+
### P0:`.git` 可以被声明为可写路径并被删除
|
|
79
|
+
|
|
80
|
+
如果允许:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
awbs view create --write .git
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
那么 agent 可以在 workspace 中删除 `.git`,之后 `changeset apply` 可能把删除传播回数据库目录。
|
|
87
|
+
|
|
88
|
+
这属于最严重的失败类型:
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
命令最终失败,但副作用已经破坏仓库。
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
涉及位置:
|
|
95
|
+
|
|
96
|
+
- `src/usecases/view.ts`
|
|
97
|
+
- `src/usecases/changeset.ts`
|
|
98
|
+
- `src/adapters/local-file-database.ts`
|
|
99
|
+
|
|
100
|
+
修复方向:
|
|
101
|
+
|
|
102
|
+
- `.git` 永远是 AWBS 系统保留路径,不能 read、write、view、changeset、apply。
|
|
103
|
+
- apply 前必须先完成所有路径合法性验证。
|
|
104
|
+
- 任何写入数据库根目录的动作,都必须经过统一 path policy。
|
|
105
|
+
- 禁止在没有完整预检通过前执行 `rmSync` / overwrite / copy。
|
|
106
|
+
|
|
107
|
+
### P0:changeset payload 没有不可变校验
|
|
108
|
+
|
|
109
|
+
当前 `changeset collect` 生成:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
manifest.json
|
|
113
|
+
diff.patch
|
|
114
|
+
files/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
但 `apply` 时主要信任磁盘上的 payload,不重新校验 `record.sha256`,`operationHash` 也没有覆盖 payload 内容。
|
|
118
|
+
|
|
119
|
+
风险是:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
collect 后替换 .awbs/changesets/<id>/files/... 的内容,
|
|
123
|
+
apply 仍可能提交被替换后的内容。
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
这会让 changeset 从“可信最小变更单元”退化成“可被本地磁盘篡改的临时包”。
|
|
127
|
+
|
|
128
|
+
涉及位置:
|
|
129
|
+
|
|
130
|
+
- `src/usecases/changeset.ts`
|
|
131
|
+
|
|
132
|
+
修复方向:
|
|
133
|
+
|
|
134
|
+
- collect 时为每个 payload 文件记录 sha256。
|
|
135
|
+
- apply 前重新计算所有 payload 文件 sha256。
|
|
136
|
+
- operationHash 必须覆盖 manifest 关键字段和 payload hash。
|
|
137
|
+
- changeset seal / receipt 应当把 payload hash 纳入不可变契约。
|
|
138
|
+
- 任何 payload 校验失败都必须拒绝 apply,不能降级。
|
|
139
|
+
|
|
140
|
+
### P1:Authority Service 抽象太低层
|
|
141
|
+
|
|
142
|
+
当前 session daemon 暴露的能力偏底层,例如:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
appendLedgerEntry
|
|
146
|
+
createViewContract
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
这更像是“远程 sealed 文件写入器”,而不是 004 设计中的 Authority Service。
|
|
150
|
+
|
|
151
|
+
004 的核心要求是:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
Authority Service 不能签任意 hash。
|
|
155
|
+
Authority Service 不能只提供底层写入原语。
|
|
156
|
+
Authority Service 应该只提供 applyVerifiedOperation 这类语义接口。
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
也就是说,Authority Service 应当自己重新计算、验证、应用 operation,而不是让外层 CLI 把已经算好的结果交给它写入。
|
|
160
|
+
|
|
161
|
+
涉及位置:
|
|
162
|
+
|
|
163
|
+
- `src/adapters/local-authority-session.ts`
|
|
164
|
+
- `src/adapters/session-authority-client.ts`
|
|
165
|
+
- `TASK_004_TRUSTED_AUTHORITY_LAYER.md`
|
|
166
|
+
|
|
167
|
+
修复方向:
|
|
168
|
+
|
|
169
|
+
- 提升 AuthorityPort 语义层级。
|
|
170
|
+
- 收敛为 `applyVerifiedOperation` / `createVerifiedView` / `revokeVerifiedView` 等语义操作。
|
|
171
|
+
- daemon 内部重新计算 operationHash。
|
|
172
|
+
- daemon 内部验证 trusted head、view contract、changeset payload、path policy。
|
|
173
|
+
- controller token 只能授权语义操作,不能授权任意底层写入。
|
|
174
|
+
|
|
175
|
+
### P1:ledger verify 还不足以称为可信链验证
|
|
176
|
+
|
|
177
|
+
当前 ledger verify 更接近:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
从 trusted commit 读取 sealed ledger
|
|
181
|
+
确认 head entry 存在
|
|
182
|
+
确认 ref 大体对应
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
但完整可信链需要验证:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
previousEntryHash
|
|
189
|
+
entryHash
|
|
190
|
+
operationHash
|
|
191
|
+
parentTrustedCommit
|
|
192
|
+
currentTrustedCommit
|
|
193
|
+
refs/awbs/trusted
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
如果没有 hash-linked ledger,AWBS 还不能严肃地说“整条链可验证”。
|
|
197
|
+
|
|
198
|
+
涉及位置:
|
|
199
|
+
|
|
200
|
+
- `src/usecases/ledger.ts`
|
|
201
|
+
- `src/domain/authority-types.ts`
|
|
202
|
+
- `TASK_004_TRUSTED_AUTHORITY_LAYER.md`
|
|
203
|
+
|
|
204
|
+
修复方向:
|
|
205
|
+
|
|
206
|
+
- ledger entry 增加 `previousEntryHash`、`entryHash`。
|
|
207
|
+
- entryHash 覆盖 entry 的规范化 JSON。
|
|
208
|
+
- operationHash 覆盖 operation 输入、changeset payload hash、path list、base commit。
|
|
209
|
+
- verify 从 genesis 一路重算到 current trusted entry。
|
|
210
|
+
- verify 同时校验 `refs/awbs/trusted` 指向的 commit 与 ledger head 一致。
|
|
211
|
+
|
|
212
|
+
### P1:session IPC 没有绑定死到启动 repo
|
|
213
|
+
|
|
214
|
+
daemon 接受 `request.root`,再根据这个 root 执行 authority 操作。
|
|
215
|
+
|
|
216
|
+
风险是:
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
如果 endpoint 被知道,或 session.json 被伪造,
|
|
220
|
+
请求方可能让 daemon 对非启动 repo 执行 authority 操作。
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
另外,一些非 controller 方法看似是只读,但仍可能触发 mirror / event 写入。
|
|
224
|
+
|
|
225
|
+
涉及位置:
|
|
226
|
+
|
|
227
|
+
- `src/adapters/local-authority-session.ts`
|
|
228
|
+
|
|
229
|
+
修复方向:
|
|
230
|
+
|
|
231
|
+
- session daemon 启动后绑定固定 repo root / repoId。
|
|
232
|
+
- 所有请求中的 root 只能用于 sanity check,不能改变 daemon 操作对象。
|
|
233
|
+
- 非 controller 方法必须真正只读。
|
|
234
|
+
- mirror repair / event append 这种写入动作必须明确归类为 controller operation 或 trusted maintenance operation。
|
|
235
|
+
|
|
236
|
+
### P2:文件系统边界缺少 symlink / realpath 策略
|
|
237
|
+
|
|
238
|
+
当前大量路径操作依赖:
|
|
239
|
+
|
|
240
|
+
```text
|
|
241
|
+
statSync
|
|
242
|
+
cpSync
|
|
243
|
+
rmSync
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
如果允许路径下出现 symlink,可能导致:
|
|
247
|
+
|
|
248
|
+
```text
|
|
249
|
+
index / view / apply 触达 repo 根目录之外的真实路径。
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
涉及位置:
|
|
253
|
+
|
|
254
|
+
- `src/adapters/local-file-database.ts`
|
|
255
|
+
- `src/usecases/changeset.ts`
|
|
256
|
+
|
|
257
|
+
修复方向:
|
|
258
|
+
|
|
259
|
+
- 统一使用 `lstat` 识别 symlink。
|
|
260
|
+
- v0/v1 阶段可以直接拒绝 symlink。
|
|
261
|
+
- 如未来支持 symlink,必须有 realpath containment 校验。
|
|
262
|
+
- `copy`、`snapshot`、`remove`、`apply` 全部走同一套 path policy。
|
|
263
|
+
|
|
264
|
+
### P2:summary 允许旧摘要静默套到当前文件
|
|
265
|
+
|
|
266
|
+
当前 summary 查询如果 exact miss,可能 fallback 到 path-level 或最后一条摘要。
|
|
267
|
+
|
|
268
|
+
风险是:
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
文件内容已经变化,但索引仍显示旧摘要。
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
索引不是 AWBS 事实源,但摘要会影响 agent 如何选择上下文,因此不能静默错配。
|
|
275
|
+
|
|
276
|
+
涉及位置:
|
|
277
|
+
|
|
278
|
+
- `src/adapters/file-summary-store.ts`
|
|
279
|
+
- `src/usecases/index.ts`
|
|
280
|
+
|
|
281
|
+
修复方向:
|
|
282
|
+
|
|
283
|
+
- 默认只接受 sha256 精确匹配的摘要。
|
|
284
|
+
- path-level 摘要必须显式标记为 `summarySource: "path-level"` 或类似状态。
|
|
285
|
+
- stale summary 不能伪装成 current summary。
|
|
286
|
+
- query 输出应能区分 exact / stale / path-level / missing。
|
|
287
|
+
|
|
288
|
+
## Cross-Cutting Fix Order
|
|
289
|
+
|
|
290
|
+
优先级建议如下:
|
|
291
|
+
|
|
292
|
+
1. 统一 path policy。
|
|
293
|
+
2. 禁止 `.git`、`.awbs/private`、`.awbs` 系统路径绕过。
|
|
294
|
+
3. 禁止 symlink escape。
|
|
295
|
+
4. changeset payload hash 封装和 apply 前重算。
|
|
296
|
+
5. AuthorityPort 提升为语义 operation 接口。
|
|
297
|
+
6. ledger 增加 hash-linked verify。
|
|
298
|
+
7. session daemon 绑定启动 repo。
|
|
299
|
+
8. summary stale 语义显式化。
|
|
300
|
+
9. 补 adversarial tests。
|
|
301
|
+
|
|
302
|
+
## Required Test Cases
|
|
303
|
+
|
|
304
|
+
本轮实现已经补以下对抗测试:
|
|
305
|
+
|
|
306
|
+
- `view create --read .` 不能复制 `.awbs/private`。
|
|
307
|
+
- `view create --read .awbs` 被拒绝或被系统路径策略过滤。
|
|
308
|
+
- `view create --write .git` 被拒绝。
|
|
309
|
+
- workspace 删除 `.git` 后,collect/apply 不得破坏数据库根目录。
|
|
310
|
+
- collect 后篡改 `changeset/files/`,apply 必须拒绝。
|
|
311
|
+
- operationHash 变化能检测 payload 篡改。
|
|
312
|
+
- ledger verify 能从 genesis 重算整条 hash-linked chain。
|
|
313
|
+
- session daemon 不能对非启动 repo 执行 authority 操作。
|
|
314
|
+
- 非 controller session 方法不能写 mirror/event。
|
|
315
|
+
- symlink 指向 repo 外部时,index/view/apply 必须拒绝。
|
|
316
|
+
- stale summary 不得被标成 exact current summary。
|
|
317
|
+
- `.awbs` / `.git` 大小写变体不能绕过保留路径策略。
|
|
318
|
+
- 通过 symlink 作为写入目标时,文件数据库必须拒绝而不是覆盖链接外部目标。
|
|
319
|
+
|
|
320
|
+
## Non-Goals
|
|
321
|
+
|
|
322
|
+
006 不把 AWBS 改成沙箱系统。
|
|
323
|
+
|
|
324
|
+
006 不承诺对抗 admin/root。
|
|
325
|
+
|
|
326
|
+
006 不实现旧仓库兼容。
|
|
327
|
+
|
|
328
|
+
006 不引入 AI 摘要。
|
|
329
|
+
|
|
330
|
+
006 不引入 OS keychain / Windows service / Linux daemon 账户。
|
|
331
|
+
|
|
332
|
+
006 不做自动删除污染目录的危险清理。
|
|
333
|
+
|
|
334
|
+
## Acceptance Direction
|
|
335
|
+
|
|
336
|
+
006 完成后,AWBS 的可信边界应当更接近:
|
|
337
|
+
|
|
338
|
+
```text
|
|
339
|
+
开放文件系统可以混乱。
|
|
340
|
+
agent workspace 可以混乱。
|
|
341
|
+
Git 普通 HEAD 可以混乱。
|
|
342
|
+
|
|
343
|
+
但 AWBS 认证数据库只能由:
|
|
344
|
+
path-policy-valid changeset
|
|
345
|
+
+ payload-hash-verified operation
|
|
346
|
+
+ authority-semantic apply
|
|
347
|
+
+ hash-linked ledger
|
|
348
|
+
+ trusted ref
|
|
349
|
+
共同推进。
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
这才符合 AWBS 的核心设计:输入开放,落地受控;失败可观察,不能伪成功;可信事实只能从可信链进入。
|
|
353
|
+
|
|
354
|
+
## First Implementation Pass
|
|
355
|
+
|
|
356
|
+
第一轮修复已经覆盖以下内容:
|
|
357
|
+
|
|
358
|
+
- 新增统一 path policy,拒绝把数据库根、`.git`、`.awbs`、`.awbs-view.json` 当成用户数据路径投影或写入。
|
|
359
|
+
- `view create --read .`、`--read .awbs`、`--write .git` 会被拒绝。
|
|
360
|
+
- index 默认排除整个 `.awbs` 系统目录,不再把 authority / private / run material 作为可查询用户数据。
|
|
361
|
+
- 文件系统 copy / snapshot / remove / index walk 拒绝 symlink,避免通过链接触达 repo 根之外。
|
|
362
|
+
- changeset collect 不再复制只读或保留路径违规 payload。
|
|
363
|
+
- changeset manifest 增加 `payloadHash` 和 `operationHash`。
|
|
364
|
+
- changeset collect 会生成 authority-sealed receipt,apply 必须打开 receipt 并匹配 manifest / payload。
|
|
365
|
+
- apply 前会先完成 path policy、payload sha256、payloadHash、operationHash、sealed receipt 校验,再执行写入。
|
|
366
|
+
- ledger entry 增加 `previousEntryHash`、`entryHash`、`changesetPayloadHash`。
|
|
367
|
+
- ledger append 会检查 entry 是否链接当前 head,ledger verify 会从头重算 entry hash 链。
|
|
368
|
+
- session daemon 绑定启动 repo,并只允许同 repoId / 同 Git worktree 语义下的内部 trusted worktree 请求。
|
|
369
|
+
- session start 不再自动迁移旧 repo trustMode;开发期仓库结构不兼容就应重新初始化。
|
|
370
|
+
- summary set / get 改为基于 trusted commit 计算 sha,旧 sha 摘要不会静默套到新内容。
|
|
371
|
+
- `.awbs` / `.git` 保留路径判断改为大小写无关,适配 Windows 文件系统语义。
|
|
372
|
+
- session controller token 不再作为 raw token 进入 IPC,请求使用 nonce HMAC proof。
|
|
373
|
+
- session daemon 拒绝重复 nonce,防止 controller proof 重放。
|
|
374
|
+
- 可信写入成功响应必须带 response proof,CLI 会拒绝未签回的伪成功响应。
|
|
375
|
+
- session daemon 启动改为 hidden detached + stdio ignore,避免 Windows 测试/运行时弹出大量控制台窗口。
|
|
376
|
+
- `npm test` 改为串行执行,避免并发测试一次性拉起过多 session daemon。
|
|
377
|
+
|
|
378
|
+
第一轮仍未完成的更大结构改造:
|
|
379
|
+
|
|
380
|
+
- Authority Service 还没有完全提升为唯一的 `applyVerifiedOperation` 语义入口。
|
|
381
|
+
- OS keychain / 独立系统服务身份仍然属于后续任务,不在 006 第一轮内。
|