@minonl/dia 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +253 -2
- package/bin/dia.js +5 -0
- package/dist/cli.js +7408 -0
- package/docs/acp-integration.md +136 -0
- package/docs/architecture.md +166 -0
- package/docs/cli.md +117 -0
- package/docs/dependency-registry.md +105 -0
- package/docs/deps.jsonl +7 -0
- package/docs/ecosystem-integration.md +155 -0
- package/docs/ecosystem-positioning.md +95 -0
- package/docs/entrypoints.md +83 -0
- package/docs/evolution-process.md +298 -0
- package/docs/history/framework-bootstrap.md +109 -0
- package/docs/host-control-surface.md +213 -0
- package/docs/index.md +80 -0
- package/docs/kit-install.md +339 -0
- package/docs/migrations/kb-golden.md +32 -0
- package/docs/migrations/llm-migration.md +49 -0
- package/docs/migrations/no-python.md +52 -0
- package/docs/migrations/yan-agent-current.md +52 -0
- package/docs/migrations/yan-agent-next.md +168 -0
- package/docs/migrations/yan-kb-parity.md +159 -0
- package/docs/migrations/yan-kb.md +120 -0
- package/docs/model-baseline-sidecar.md +220 -0
- package/docs/model-behavior.md +229 -0
- package/docs/monorepo.md +83 -0
- package/docs/overview.md +126 -0
- package/docs/patching.md +91 -0
- package/docs/persona-install.md +264 -0
- package/docs/platforms/index.md +66 -0
- package/docs/platforms/registry.json +54 -0
- package/docs/pricing.md +43 -0
- package/docs/proposals.md +76 -0
- package/docs/research/benchmarks-survey.md +96 -0
- package/docs/research/collaboration-theory.md +85 -0
- package/docs/research/dsh-superagent.md +97 -0
- package/docs/research/frameworks-survey-2.md +75 -0
- package/docs/research/h0/report.md +135 -0
- package/docs/research/h0/sample.json +34 -0
- package/docs/research/model-boundary-patterns.md +99 -0
- package/docs/research/opencode-session-scoping.md +84 -0
- package/docs/review/reuse-review.md +105 -0
- package/docs/review/verification-2026-10-28.md +49 -0
- package/docs/security/audits/2026-11-04.json +44 -0
- package/docs/security/credentials.md +95 -0
- package/docs/security/public-release.md +108 -0
- package/docs/security-sandbox.md +157 -0
- package/docs/status.md +157 -0
- package/docs/team-automation.md +169 -0
- package/docs/team.md +112 -0
- package/docs/versioning.md +226 -0
- package/docs/vision.md +161 -0
- package/package.json +45 -4
- package/packages/job/README.md +98 -0
- package/packages/job/bin/dia-job +1283 -0
- package/packages/job/config.example +5 -0
- package/packages/job/install.sh +37 -0
- package/packages/job/lib/config.sh +18 -0
- package/packages/job/lib/json.mjs +130 -0
- package/packages/job/lib/policy.sh +103 -0
- package/packages/job/package.json +10 -0
- package/packages/job/shim/yan-task +24 -0
- package/packages/job/tests/bootstrap.test.sh +115 -0
- package/packages/job/tests/install.test.sh +30 -0
- package/packages/job/tests/linux.test.sh +130 -0
- package/packages/job/tests/p2.test.sh +46 -0
- package/packages/job/tests/policy.test.sh +38 -0
- package/packages/wt/bin/dia-wt +1148 -0
- package/packages/wt/tests/check.test.sh +126 -0
- package/packages/wt/tests/clean.test.sh +126 -0
- package/packages/wt/tests/prune-merged.test.sh +169 -0
- package/packages/wt/tests/route.test.sh +112 -0
- package/packages/wt/tests/scope.test.sh +69 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# 版本与多会话(persona / kit)
|
|
2
|
+
|
|
3
|
+
> 日期 2026-10-28。问题:dia 要支持升级/本地迭代期间不同会话用不同版本 persona;kit 是否也要会话级版本?
|
|
4
|
+
> 结论:**persona 硬钉;kit 按类型分**——工具/技能硬钉,知识滚动但记录索引哈希。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 为什么 yan 的做法不够
|
|
9
|
+
|
|
10
|
+
yan:同一时间只有一个 agent 版本生效,升级 = 覆盖。
|
|
11
|
+
问题:
|
|
12
|
+
- 升级时在跑的会话会被动切换(或直接坏);
|
|
13
|
+
- 本地迭代无法与稳定版并存;
|
|
14
|
+
- 出问题无法回答"这个会话当时用的哪版"。
|
|
15
|
+
|
|
16
|
+
dia 需要:**多版本并存 + 会话级钉住 + 可追溯**。
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. 存储模型
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
~/.local/share/dia/
|
|
24
|
+
├── personas/<id>/<version>/ # 每个版本完整目录(含 dia.json)
|
|
25
|
+
├── kits/<id>/<version>/
|
|
26
|
+
├── channels.json # stable/dev → 具体版本
|
|
27
|
+
└── sessions/<session-id>.json # 会话钉住的版本与哈希
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `version` = `semver+commit`(如 `1.2.0+abc1234`);
|
|
31
|
+
- 内容寻址:同 hash 的目录只存一份(跨版本去重);
|
|
32
|
+
- 保留策略:`gc --keep N`(默认 3),dev 版本可标 `ephemeral` 自动清。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2.1 semver 判定 + breaking 标记
|
|
37
|
+
|
|
38
|
+
| 变更 | bump | 例子 |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| 移除工具/技能、工具签名变化、策略收紧或放宽、人格身份变化 | **major** | 删除 `bash` 工具、改审批阈值 |
|
|
41
|
+
| 新增工具/技能、增量提示词、知识新增 | **minor** | 加 `dsh` 工具、补一条规则 |
|
|
42
|
+
| 文档、错别字、非行为修正 | **patch** | 改说明文字 |
|
|
43
|
+
|
|
44
|
+
- `dia.json` 可显式标 `"breaking": true`(或 `breaking: ["remove-tool:bash"]`)→ 强制 major。
|
|
45
|
+
- `dia` 在 `persona update --check` 时**建议版本号**:按 diff 分类给出 `major/minor/patch`,作者确认。
|
|
46
|
+
- **硬检查**:实际 bump 不得小于建议级别;否则拒绝发布。
|
|
47
|
+
|
|
48
|
+
## 2.2 双重审查(硬检查 + 模型)
|
|
49
|
+
|
|
50
|
+
| 闸门 | 检查 | 失败 |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| **硬检查(dia)** | schema、semver、hash、文件白名单、capabilities 是否扩大、secret 扫描、依赖约束 | **拒绝** |
|
|
53
|
+
| **模型审查** | diff 是否削弱策略/引入注入/与 persona 意图冲突;给 verdict + 证据 | 标记 `needs-human`,人批 |
|
|
54
|
+
|
|
55
|
+
模型**不能推翻硬失败**;硬检查**不替代**语义审查。
|
|
56
|
+
|
|
57
|
+
## 3. 会话钉版本
|
|
58
|
+
|
|
59
|
+
会话开始时解析并写入:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"session_id": "...",
|
|
64
|
+
"persona": { "id": "dabo", "version": "1.2.0+abc1234", "hash": "sha256:..." },
|
|
65
|
+
"kits": [
|
|
66
|
+
{ "id": "core", "version": "1.2.0+def5678", "mode": "pinned" },
|
|
67
|
+
{ "id": "knowledge", "index": "idx-2026-10-28T10:00Z", "mode": "rolling" }
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
规则(基线):
|
|
73
|
+
- **persona:默认硬钉**;是否允许"增量补丁"取决于宿主能力(见 §3.1)。
|
|
74
|
+
- **工具/技能 kit:默认硬钉**;增量新增可被感知,移除/签名变化需要新会话或 `in-history` 能力。
|
|
75
|
+
- **知识 kit:滚动**,但**每次检索记录索引版本/hash**;eval/canary 场景可强制硬钉。
|
|
76
|
+
- 没有记录 = 无法判定,审计直接标 `unknown`。
|
|
77
|
+
|
|
78
|
+
### 3.1 能力分级(决定"能感知到什么")
|
|
79
|
+
|
|
80
|
+
| 级 | 能力 | 代表 | 能做什么 |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| **T0** | 无钩子 | 纯 CLI、无事件 | 只能下次会话生效 |
|
|
83
|
+
| **T1** | 工具边界 | MCP 状态、工具报错 | 下次工具调用时感知(如"需要登录") |
|
|
84
|
+
| **T2** | 事件/预步 | dsh `tools/change`、`llm/adapters-updated`、`agent/pre-step`;opencode `event.subscribe`、`session.hook` | 下一轮模型请求前注入通知 |
|
|
85
|
+
| **T3** | 原生增量更新 | dsh `toolUpdate=addition-only/in-history`;opencode `agent.transform` | 增量工具/定义可在会话内生效 |
|
|
86
|
+
|
|
87
|
+
**关键差异(dsh 实测)**:
|
|
88
|
+
- `addition-only`:新增工具以 tool-addition 块跟随缓存,**移除不通知**;
|
|
89
|
+
- `in-history`:新增 + 移除都进历史,能感知移除;
|
|
90
|
+
- 缺省:每次请求重写完整工具表(缓存失效)。
|
|
91
|
+
|
|
92
|
+
### 3.2 变更类型 × 能力 → 动作
|
|
93
|
+
|
|
94
|
+
| 变更 | T0 | T1 | T2 | T3 addition-only | T3 in-history |
|
|
95
|
+
|---|---|---|---|---|---|
|
|
96
|
+
| 知识更新 | 下次会话 | 下次检索 | 下次检索 | 下次检索 | 下次检索 |
|
|
97
|
+
| **新增工具** | 下次会话 | 下次调用 | 注入通知 | **原生追加** | **原生追加** |
|
|
98
|
+
| **移除工具/签名变化** | 下次会话 | 报错 | 通知 + 拒绝调用 | **下次会话**(不通知移除) | **原生移除 + 拒绝** |
|
|
99
|
+
| persona 增量补丁 | 下次会话 | 下次调用 | **注入补丁通知** | 原生更新(若支持) | 原生更新 |
|
|
100
|
+
| persona 换身份 | 下次会话 | 下次会话 | 下次会话 | 下次会话 | 下次会话 |
|
|
101
|
+
|
|
102
|
+
**原则**:用当前会话能安全支持的最强动作,而不是一律降级;**破环性变更永远不静默热切**。
|
|
103
|
+
|
|
104
|
+
**H19 实测(2026-10-28,opencode 2.1.3)**:
|
|
105
|
+
同一 ACP 会话,`h19probe` agent 文件从 v1 改为 v2 后,第二轮仍返回 `H19-V1`;
|
|
106
|
+
模型 reasoning 原文:"The system update didn't change my identity."
|
|
107
|
+
→ **persona 身份在会话内被钉住**;next-session 默认正确。
|
|
108
|
+
(dsh 源码级一致:profile/bundle 启动时加载,headless HMR 关闭。)
|
|
109
|
+
|
|
110
|
+
**H17 实测(`projectToolUpdates`,2026-10-28)**:
|
|
111
|
+
给定历史 `a,b`、新增 `c`、移除 `a`:
|
|
112
|
+
|
|
113
|
+
| 模式 | 工具声明 | 历史块 |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `addition-only` | `b, c(deferred)` | 只有 `tool-addition:c`(**移除 a 不通知**) |
|
|
116
|
+
| `in-history` | `a, b, c(deferred)` | `addition:c` + `removal:a` |
|
|
117
|
+
| 缺省 | `b, c` | 无 developer 消息(每轮重写全表) |
|
|
118
|
+
|
|
119
|
+
→ **新增工具可在会话内公告;移除只有 `in-history` 能感知**。
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 4. 通道(channel):稳定版与迭代版并存
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
// channels.json
|
|
127
|
+
{ "dabo": { "stable": "1.2.0+abc1234", "dev": "1.3.0-dev+fedcba9" } }
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
- `stable`:日常入口,用户的默认选择;
|
|
131
|
+
- `dev`:本地迭代,只给开发者/测试用;
|
|
132
|
+
- 宿主侧映射:
|
|
133
|
+
- opencode:`dabo`(stable)与 `dabo-dev` 两个 agent 文件;
|
|
134
|
+
- dsh:`dabo`(stable)与 `dabo-dev` 两个 profile。
|
|
135
|
+
- 这样升级 stable 时,dev 可以继续跑,互不影响。
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 5. 激活规则
|
|
140
|
+
|
|
141
|
+
| 动作 | 行为 |
|
|
142
|
+
|---|---|
|
|
143
|
+
| `persona update` | 新版本落盘;按 `activation` 模式决定是否切 active |
|
|
144
|
+
| `persona activate dabo@<ver>` | 切 stable 指针;有活跃会话时按能力分级:T3 增量可 `--apply active`,破环性变更要求 0 活跃 |
|
|
145
|
+
| `--activate-now --i-am-human` | 强制切;运行中会话仍用旧版(宿主不热更) |
|
|
146
|
+
| `persona gc --keep 3` | 清理旧版本;被会话引用/被 pin 的跳过 |
|
|
147
|
+
| `persona rollback dabo` | 切回上一 stable(同 activate 规则) |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 5.1 生效时机:用户选择并记住
|
|
152
|
+
|
|
153
|
+
配置存 `~/.config/dia/activation.yaml`:
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
dabo:
|
|
157
|
+
mode: next-session # next-session | active-additive | active-all | manual
|
|
158
|
+
notify: true
|
|
159
|
+
confirm_breaking: true
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| 模式 | 行为 | 适用 |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| **next-session**(默认) | 只切指针;运行中会话保持旧版 | 日常升级 |
|
|
165
|
+
| **active-additive** | 只把"增量变更"推给活跃会话;破环性变更排队 | 加工具/加知识 |
|
|
166
|
+
| **active-all** | 尝试全部生效;破环性需 `--i-am-human`;可能迁移/重启 | 紧急修复 |
|
|
167
|
+
| **manual** | 只落盘;用户逐会话 `dia persona apply` | 保守/调试 |
|
|
168
|
+
|
|
169
|
+
命令:`dia persona activation dabo --mode active-additive`(记住)。
|
|
170
|
+
|
|
171
|
+
## 5.2 "所有会话立即用最新"能怎么做
|
|
172
|
+
|
|
173
|
+
| 方式 | 保证 | 代价 |
|
|
174
|
+
|---|---|---|
|
|
175
|
+
| **增量注入**(T3) | 新增工具/补丁在下一轮生效 | 只支持增量;不覆盖破环 |
|
|
176
|
+
| **会话迁移/fork** | 用新配置重建会话,保留上下文 | 依赖宿主 fork/resume;一次一会话 |
|
|
177
|
+
| **重启宿主 daemon/profile** | 所有新会话必用新版;在跑会话中断 | 破坏性;仅 `active-all` 且人批 |
|
|
178
|
+
| **标记 stale + 提示新建** | 不中断,用户自己换 | 用户需操作 |
|
|
179
|
+
|
|
180
|
+
**没有"对运行中会话无损、全量、立即"的通用方案**;必须在上面四选一。
|
|
181
|
+
|
|
182
|
+
## 6. 通知(热切必须提示)
|
|
183
|
+
|
|
184
|
+
任何对活跃会话的变更都要注入提示(能注入时):
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
[dia] persona dabo 1.2.0 → 1.3.0
|
|
188
|
+
变更:新增 web 工具;排障口吻调整
|
|
189
|
+
生效:下一轮 / 需新会话
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
- 注入点:dsh `agent/pre-step`;opencode `session.hook("context")`;
|
|
193
|
+
- 不能注入(T0/T1)→ 在下一次工具结果或 `dia status` 中提示;
|
|
194
|
+
- 同时写审计(`persona_switched` 事件,含 session/old/new/reason)。
|
|
195
|
+
|
|
196
|
+
## 7. 宿主限制(必须写清)
|
|
197
|
+
|
|
198
|
+
- **dsh**:profile 在进程启动时加载;多版本靠**多 profile**(`dabo` / `dabo-dev` / 可选 `dabo-<ver>`),不能在一个进程里换。
|
|
199
|
+
- **opencode**:agent 文件按 id 加载;多版本靠**多 agent id**(stable/dev),不能同一个 id 两个版本。
|
|
200
|
+
- dsh:`toolUpdate` 模式决定增量能力(`addition-only` 不感知移除;`in-history` 可感知);profile 本身仍需重启。
|
|
201
|
+
- opencode:MCP 状态实时(`mcp list` 可见);agent 目录可由 `reload`/`agent.transform` 更新,但会话快照是否切换需探针(H17)。
|
|
202
|
+
- **不做无差别的"一律热更"**:破环性变更(移除工具/换人格)永远要求新会话。
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 8. UX
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
$ dia persona list dabo --versions
|
|
210
|
+
1.2.0+abc1234 stable active sessions: 1
|
|
211
|
+
1.3.0-dev+fed dev active sessions: 2
|
|
212
|
+
|
|
213
|
+
$ dia persona activate dabo@1.2.0+abc1234
|
|
214
|
+
refused: 3 active sessions; use --activate-now --i-am-human or wait
|
|
215
|
+
|
|
216
|
+
$ dia session show ses_xxx
|
|
217
|
+
persona dabo@1.2.0+abc1234
|
|
218
|
+
kits core@1.2.0+def (pinned), knowledge@idx-2026-10-28T10:00Z (rolling)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 9. 待确认
|
|
224
|
+
|
|
225
|
+
1. **知识 kit 的默认策略**:滚动 + 记录索引哈希(推荐)vs 会话硬钉。
|
|
226
|
+
2. **多版本宿主映射**:stable/dev 双通道(推荐)vs 每版本独立 agent id / profile。
|
package/docs/vision.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# dia 长期定位:从"安装器"到 superagent / agent-team 工厂
|
|
2
|
+
|
|
3
|
+
> 2026-11-03,方向性文档。**它不是现状**——现状看 [`overview.md`](overview.md) 与 [`status.md`](status.md);
|
|
4
|
+
> 两者冲突时以现状为准。本文回答:"一年后 dia 要长成什么,现在缺什么。"
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 一句话
|
|
9
|
+
|
|
10
|
+
**dia 是 superagent / agent-team 的生成与维护工具。**
|
|
11
|
+
把一个「域」编译成能跑、能审、能进化的 agent(单域)或 agent-team(多角色),
|
|
12
|
+
再把它送进更大的组织形态(rig / fleet / software factory)里自行工作。
|
|
13
|
+
|
|
14
|
+
现在 dia 只做到这条链的前半段:**persona 安装 + 渲染 + 知识/审计控制面**;
|
|
15
|
+
后半段(团队生成、平台版本经验、自身成为 agent、fleet 对接)还没有。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. 产物谱系
|
|
20
|
+
|
|
21
|
+
| 产物 | 域 | 形态 | 现状 |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| **yan** | 工作域 · 偏前端领域 | 单 superagent(16 个域命令 + 知识库 + 技能) | 已装,落后来源仓 1 个提交 |
|
|
24
|
+
| **dabo** | 个人 · 游戏 / 生活 / 个人项目 | 单 superagent(人格 + 9 角色团定义 + 2 个域命令) | 已装,与来源一致 |
|
|
25
|
+
| **redmine case agent**(计划) | 工作域 · 工单处理 | 单域 superagent(case 检索 → 判定 → 草稿 → 留痕) | 未开始 |
|
|
26
|
+
| **家庭库管家**(计划) | 个人 · 家庭资料 | 单域 superagent(私有数据根 + 只读索引 + 定期巡检) | 未开始 |
|
|
27
|
+
| **openrig rig**(计划) | 多 agent 协作 | agent-team / rig(组织形态见 §5) | 未开始;边界待定 |
|
|
28
|
+
|
|
29
|
+
**编译链(dia 的职责)**
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
域内容(人格 + 知识 + 技能 + 命令 + 策略)
|
|
33
|
+
→ dia persona/kit 校验 + 渲染(opencode / dsh / 未来宿主)
|
|
34
|
+
→ 运行(宿主 / ACP / headless)
|
|
35
|
+
→ 观测(audit / episodes / usage)
|
|
36
|
+
→ 知识沉淀 + 评审
|
|
37
|
+
→ 再编译(update / patch / activation)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
判据:同一个域,换宿主只换 render target,不重写内容;换版本不丢审计与回滚。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 3. dia 的两个面
|
|
45
|
+
|
|
46
|
+
| 面 | 形态 | 属性 | 现在 |
|
|
47
|
+
|---|---|---|---|
|
|
48
|
+
| **A. 控制面** | `dia` CLI(确定性、无 LLM) | 可脚本化、可审计、可回滚;CI/门禁的稳定接口 | 已存在(见 `cli.md`) |
|
|
49
|
+
| **B. dia-agent** | **独立 persona `dia-evoler`**(跑在宿主里,工具 = 控制面 + 知识) | 能对话、能规划、能解释"为什么这样配" | 未开始 |
|
|
50
|
+
|
|
51
|
+
**仓库边界(2026-11-03 定)**:dia 仓库**只放控制面(工具)**。agent 面是独立 persona `dia-evoler`
|
|
52
|
+
(独立仓 + 独立数据根),由 `dia persona create` 出骨架、`dia persona add` 安装;dia 不为它写专属代码。
|
|
53
|
+
|
|
54
|
+
**B 不是把 LLM 塞进 A。** 硬边界:
|
|
55
|
+
|
|
56
|
+
1. A 的每条命令保持确定性;同一输入同一输出,模型不参与判定。
|
|
57
|
+
2. B 只能**调用** A,不能绕过门禁(写操作仍要 `--force` / 人确认 / 审计)。
|
|
58
|
+
3. B 的成长 = 知识库 + 提案 + 评审,不是运行时自我改写(复盘见 `evolution-process.md`)。
|
|
59
|
+
4. B 的产物仍然是 persona:可 `verify`、可 `remove`、可回滚。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 4. 平台对接能力(当前最大的工程缺口)
|
|
64
|
+
|
|
65
|
+
目标:**同一份域内容,能在不同平台 / 不同版本上稳定落地**,且每个坑都有记录、有判据。
|
|
66
|
+
|
|
67
|
+
### 4.0 原则:宿主配置对 persona 透明
|
|
68
|
+
|
|
69
|
+
persona 只声明"我是谁、我会什么"(逻辑入口、能力、策略);opencode / dsh / pi / codex 的配置键、
|
|
70
|
+
目录结构、frontmatter 由 dia 的适配层编译生成。**写 persona 的人不需要知道宿主怎么配。**
|
|
71
|
+
|
|
72
|
+
现状差距:`dia.json` 仍要求按平台写 `entry.{opencode,dsh}`(同一份正文写两遍),
|
|
73
|
+
`--host` 也只认这两家——这仍是"让 persona 操心宿主"。
|
|
74
|
+
|
|
75
|
+
方向:清单收敛为 `agent`(一份正文)+ `capabilities` + 可选 `overrides`;适配层按平台生成;
|
|
76
|
+
平台缺能力时**显式失败**(不静默降级)。
|
|
77
|
+
|
|
78
|
+
### 4.1 需要的能力
|
|
79
|
+
|
|
80
|
+
| 能力 | 说明 | 现状 |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| 配置矩阵 | opencode / dsh / codex / mimocode / zed / ACP 的配置键与渲染目标 | 只有 opencode + dsh;`ecosystem-integration.md` 有对照但无矩阵 |
|
|
83
|
+
| **版本经验库** | 每个宿主 × 版本的:配置键、断代点、已知坑、验证命令、降级策略 | **缺**(坑散落在知识库与提交信息里) |
|
|
84
|
+
| 能力探测 | 启动前判断宿主版本支持什么(hooks / ACP / skill 目录) | 只有 `dsh.checkPreset` 一项 |
|
|
85
|
+
| 依赖校验 | `deps.jsonl` 与实际可执行文件/版本比对 | **已做(M1)**:`doctor` 的 `deps` 项 |
|
|
86
|
+
| 降级策略 | 宿主能力缺失时明确降级还是失败(不静默) | 设计有(`entrypoints.md` §4),未实现 |
|
|
87
|
+
|
|
88
|
+
### 4.2 版本经验库的建议形态
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
docs/platforms/ # 记录 AI 工具平台,不记录设备(脱敏规则见 index.md §0)
|
|
92
|
+
registry.json # 单一事实源:支持范围 / 实测版本 / 已知坑(2026-11-03 起)
|
|
93
|
+
index.md # 只写规则与用法,不复制数据
|
|
94
|
+
opencode.md # 配置键、渲染目标、已知坑、验证命令(含 v1→v2 断代)
|
|
95
|
+
dsh.md # bundle/patch 语义、preset 校验、冷启动坑
|
|
96
|
+
codex.md / mimocode.md / zed.md # 有接入才建
|
|
97
|
+
hosts.yaml # 机器可读:version_range / checks / fallback(doctor 消费)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
规则:**一条经验 = 版本范围 + 复现命令 + 现有判据**;没有复现命令的写"未验证"。
|
|
101
|
+
`dia doctor` 按注册表探测本机并派生视图(`platform:<name>`);`deps.jsonl` 仍是"装了什么"的账本,两者不混。
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 5. fleet / factory(openrig 层)
|
|
106
|
+
|
|
107
|
+
边界建议(**待与 openrig 侧确认**):
|
|
108
|
+
|
|
109
|
+
| 层 | 谁负责 | 内容 |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| 域内容与配置 | **dia** | persona/kit、宿主渲染、知识根、审计契约、版本经验 |
|
|
112
|
+
| 编排与隔离 | **openrig** | rig 定义、席位、队列、快照、隔离环境、跨 agent 调度 |
|
|
113
|
+
| 证据格式 | 两边共用 | 任务 id、回合、审计行、成本行(dia 已有 `audit` / `usage` 形状) |
|
|
114
|
+
|
|
115
|
+
dia 对 fleet 的交付物:**可导出的 persona 包 + 能力声明 + 校验结果**,而不是"帮 openrig 调度"。
|
|
116
|
+
判据:一个 rig 不依赖 dia 的运行时也能跑;dia 只负责"装配正确 + 可追溯"。
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 6. 路线(按依赖排序)
|
|
121
|
+
|
|
122
|
+
| 阶段 | 内容 | 依赖 / 判据 |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| **P0** | 平台经验库 + 依赖校验(M1):`docs/platforms/` + `hosts.yaml` + `doctor --host` | 现有两台平台实测通过;`deps.jsonl` 不再与真实环境脱节 |
|
|
125
|
+
| **P1** | team 生成:team spec → 多个 persona/角色 + 门禁 | `team run --mock` 已可用;需补"从 spec 生成角色" |
|
|
126
|
+
| **P2** | `dia-evoler`:独立 persona(读文档、解释配置、给迁移建议) | P0 的经验库是前置(否则它只会瞎猜);dia 仓不动 |
|
|
127
|
+
| **P3** | rig 导出:persona 包 + 能力声明 → openrig | 与 openrig 的接口定稿 |
|
|
128
|
+
| **P4** | 多域隔离(团队/家庭/项目)与数据根策略 | `data_root` 契约 + `DIA_DATA_ROOT_SCOPE` 已有雏形 |
|
|
129
|
+
|
|
130
|
+
与既有缺口的关系:P0 吃掉 M1;P1 顺带解决 `kit show/update/gc` 的一半需求;
|
|
131
|
+
P2 依赖 `patch` / `activation` 的边界先定清。
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 7. 不做什么(防止漂移)
|
|
136
|
+
|
|
137
|
+
- **不自建运行时 / 沙箱 / 通道**:复用宿主与 openrig,dia 只做装配与控制。
|
|
138
|
+
- **不在 dia 仓里写 agent 人格 / 对话实现**:agent 面独立成 persona(`dia-evoler`),保持仓库的工具形态。
|
|
139
|
+
- **不把 LLM 放进确定性控制面**:模型只在 dia-agent 面说话,判定仍走命令与判据。
|
|
140
|
+
- **不做公共市场 / 自动安装**:安装必须可审、可回滚。
|
|
141
|
+
- **不存业务数据**:域数据留在各域的数据根。
|
|
142
|
+
- **无证据不扩团、不扩档位**:团队规模按真实任务增长。
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 8. 决策记录
|
|
147
|
+
|
|
148
|
+
**已定(2026-11-03)**
|
|
149
|
+
|
|
150
|
+
1. **dia-agent 的边界**:独立 persona `dia-evoler`(独立仓 / 数据根);**dia 仓库保持工具形态**。
|
|
151
|
+
2. **`hosts/` 的语义**:记录的是 **AI 工具平台**(opencode/dsh/pi/codex…),不是设备;目录改名 `docs/platforms/`,
|
|
152
|
+
写之前按 `docs/platforms/index.md §0` 脱敏——公共仓只放公开平台事实,设备/家庭/内网信息落私人仓。
|
|
153
|
+
3. **多域数据隔离**:**需要**。家庭库这类敏感域用独立数据根 + 独立审计线;凭据管理单独立项(见下)。
|
|
154
|
+
|
|
155
|
+
**待定**
|
|
156
|
+
|
|
157
|
+
4. **fleet 层归谁**:配置与知识归 dia、编排与隔离归 openrig——这条边界要 openrig 侧确认。
|
|
158
|
+
5. **版本经验库的载体**(已定 2026-11-03):**单一事实源 = `docs/platforms/registry.json`**;
|
|
159
|
+
md 只写规则与用法,不复制数据;人读视图由 `dia doctor` 按需派生。
|
|
160
|
+
6. **凭据管理的落地**:现在用 `bw` CLI 入库,但"按账号分组"约束下放行粒度粗、个人 vault 内容过多 + 风险集中;
|
|
161
|
+
需要继续调研开源项目与最佳实践。现状与候选方向见 [`security/credentials.md`](security/credentials.md)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minonl/dia",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "dia (嗲) — lightweight agent framework: knowledge index, audit, session ingest",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dia": "bin/dia.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"dist",
|
|
12
|
+
"packages/wt",
|
|
13
|
+
"packages/job",
|
|
14
|
+
"docs",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=24",
|
|
19
|
+
"bun": ">=1.2"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "bun packages/cli/src/index.ts",
|
|
23
|
+
"build": "bun build packages/cli/src/index.ts --target node --outfile dist/cli.js --external bun:sqlite",
|
|
24
|
+
"test": "bun test tests && bash tests/smoke.sh && bash tests/e2e.sh",
|
|
25
|
+
"compile": "bun build packages/cli/src/index.ts --compile --outfile dist/dia",
|
|
26
|
+
"prepublishOnly": "bun run build",
|
|
27
|
+
"test:job": "pnpm --filter @dia/job test",
|
|
28
|
+
"test:kb": "pnpm --filter @dia/kb test",
|
|
29
|
+
"bench:kb": "bun experiments/kb-bench.ts",
|
|
30
|
+
"golden:kb": "bun experiments/kb-golden.ts",
|
|
31
|
+
"docs:index": "node scripts/docs-index.mjs",
|
|
32
|
+
"docs:check": "node scripts/docs-index.mjs --check"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"packageManager": "pnpm@12.5.1",
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@dia/kb": "workspace:*"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/minonl/dia.git"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/minonl/dia"
|
|
47
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# dia-job
|
|
2
|
+
|
|
3
|
+
> Generic OS scheduler adapter extracted from `yan-task` (launchd / cron / schtasks).
|
|
4
|
+
> **Status: M1** — monorepo package `@dia/job` (merged from `minonl/dia-job` via subtree).
|
|
5
|
+
> The standalone repo is being archived; use `dia job` or the global install.
|
|
6
|
+
|
|
7
|
+
## Why a package (not a separate repo)
|
|
8
|
+
|
|
9
|
+
`yan-task` is an OS integration layer (1075 lines, 4 backends, destructive launchd tests), not a dia framework primitive.
|
|
10
|
+
It lives in `packages/job` so `dia` keeps one version/CI while the package boundary stays explicit.
|
|
11
|
+
`yan-agent@next` and `dabo` consume the same package; the old standalone repo is archived.
|
|
12
|
+
|
|
13
|
+
## Contract (v1, compatible with yan-task)
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
dia-job list|status|doctor|platform
|
|
17
|
+
dia-job install <name> --cmd '<shell>' [--interval N|--calendar HH:MM] [--desc D] [--type periodic|bounded|service]
|
|
18
|
+
dia-job uninstall <name>
|
|
19
|
+
dia-job run|stop|logs <name> [-n N]
|
|
20
|
+
dia-job selfcheck [--dry-run]
|
|
21
|
+
dia-job bootstrap
|
|
22
|
+
dia-job registry
|
|
23
|
+
dia-job gc [--days N] [--dry-run]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Exit codes: `0/1/2/3/4/5` (same as yan-task).
|
|
27
|
+
|
|
28
|
+
## Configuration (P2)
|
|
29
|
+
|
|
30
|
+
| Variable | Default | Meaning |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `DIA_JOB_ROOT` | `YAN_DATA_ROOT` if set, else `~/.local/share/dia-job` | 数据根(旧数据根用全局 config 显式指定) |
|
|
33
|
+
| `DIA_JOB_LABEL_PREFIX` | `local.dia-job-` | launchd/cron label 前缀;新部署可用 `local.dia-job-` |
|
|
34
|
+
| `DIA_JOB_OWN_TASKS` | 空 | 本仓自有任务名(空格分隔);不再硬编码 yan 业务任务 |
|
|
35
|
+
| `DIA_JOB_NO_LAUNCHD` | 继承 `YAN_TASK_NO_LAUNCHD` / `DIA_JOB_NO_SCHED` | 测试隔离:**不写任何调度条目**(launchd / crontab / systemd) |
|
|
36
|
+
| `DIA_JOB_CRONTAB_BIN` | `command -v crontab` | Linux periodic 后端用的 crontab(测试可指向假实现) |
|
|
37
|
+
| `DIA_JOB_SYSTEMCTL_BIN` | `command -v systemctl` | Linux service 后端用的 systemctl(测试可指向假实现) |
|
|
38
|
+
| `DIA_JOB_CRON_PATH` | `~/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin` | 写进 cron 行的 PATH(cron 环境极简,任务常依赖 `~/.local/bin`) |
|
|
39
|
+
| `DIA_JOB_EXPECTED` | 空 | 可选 expected 清单;空则跳过 |
|
|
40
|
+
| `DIA_JOB_CONFIG` | `~/.config/dia-job/config` | 全局配置文件(纯 KEY=value,不 source) |
|
|
41
|
+
| `DIA_JOB_ENTRY_DIR` | `$DIA_JOB_ROOT/bin` | 全局稳定入口目录(ref-entry 判定) |
|
|
42
|
+
|
|
43
|
+
兼容:`YAN_DATA_ROOT` / `YAN_TASK_NO_LAUNCHD` 仍可用。路径策略在 `lib/policy.sh`,**不依赖 yan-agent / platform.sh**;worktree 用 git `worktree list` 权威判定,不只看命名。
|
|
44
|
+
|
|
45
|
+
## Install (global, no project dependency)
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
bash install.sh # ~/.local/share/dia-job + ~/.local/bin/dia-job
|
|
49
|
+
bash install.sh --dry-run
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`yan-task` shim: `shim/yan-task` resolves only `DIA_JOB_BIN` / `~/.local/bin/dia-job`; refuses worktree paths.
|
|
53
|
+
|
|
54
|
+
## Backends (2026-10-30:Linux/WSL 落地)
|
|
55
|
+
|
|
56
|
+
| 平台 | periodic(`interval`/`calendar`) | service(`--type service`) |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| macOS | launchd `~/Library/LaunchAgents/<label>.plist` | 同左(`RunAtLoad` + 无 `StartInterval` 的常驻) |
|
|
59
|
+
| **Linux / WSL** | **crontab** 行,带 `# dia-job:<name>` 标记(幂等增删) | **systemd `--user`** unit(`Restart=always` ≈ KeepAlive) |
|
|
60
|
+
| Windows native | 未实现(`install` → rc=3,见设计 §4.1) | 未实现 |
|
|
61
|
+
|
|
62
|
+
Linux 语义对齐要点:
|
|
63
|
+
|
|
64
|
+
- **无调度**(既无 `--interval` 也无 `--calendar`)→ cron `@reboot`(≈ launchd `RunAtLoad` 的"加载时跑一次")。
|
|
65
|
+
- `--interval` 必须是 **≥60 秒的整分**(cron 最小粒度);表达不了就 **rc=2 明确拒绝**,绝不"装成看着跑"。
|
|
66
|
+
`--calendar 09:30 --weekdays 1-5` → `30 9 * * 1,2,3,4,5`。
|
|
67
|
+
- cron 环境极简 ⇒ 行内显式给 `PATH`;任务体统一走 wrapper(`tasks/<name>.sh`,记 `state.jsonl`)。
|
|
68
|
+
- **service 的 linger**:user service 默认随登录会话结束而停 ⇒ 常驻服务需 `loginctl enable-linger <user>`(`doctor` 会提示)。
|
|
69
|
+
- `status`:periodic 没有进程状态(cron 是一次性进程)⇒ 显示 `scheduled`/`absent` + `state.jsonl` 上次结论;
|
|
70
|
+
service 显示 `active/failed` + `MainPID`。
|
|
71
|
+
|
|
72
|
+
## Tests
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
bash tests/bootstrap.test.sh # 16 PASS
|
|
76
|
+
bash tests/p2.test.sh # 6 PASS
|
|
77
|
+
bash tests/policy.test.sh # 7 PASS
|
|
78
|
+
bash tests/install.test.sh # 8 PASS(⚠️ 在 `*-worktree--*` 路径下跑会有 1 例假红:shim 按设计拒绝 worktree)
|
|
79
|
+
bash tests/linux.test.sh # 34 PASS(仅 Linux;假 crontab/systemctl,不碰真实调度器)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`YAN_TASK_NO_LAUNCHD=1` is honored by the inherited tests; no launchd writes.
|
|
83
|
+
|
|
84
|
+
## Migration phases
|
|
85
|
+
|
|
86
|
+
| Phase | Goal |
|
|
87
|
+
|---|---|
|
|
88
|
+
| P1 | fork baseline + tests (this repo) |
|
|
89
|
+
| P2.1 | parameterize root/label/path; drop yan-specific expected list (done) |
|
|
90
|
+
| P3 | adapt tests to `DIA_JOB_ROOT`; CI macOS+Linux |
|
|
91
|
+
| P4 | yan-agent@next shim `yan-task` → `dia-job` |
|
|
92
|
+
| **P5** | **Linux/WSL 后端落地**(crontab periodic + systemd `--user` service,自愈/在场判定/doctor 同步,2026-10-30) |
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## JSON adapter
|
|
96
|
+
|
|
97
|
+
`lib/json.mjs` is a thin Node adapter for bash (built-in `JSON` only). No Python,
|
|
98
|
+
no custom parser. JSONC/JSON5 are not enabled for registry/state files.
|