@calcit/procs 0.13.12 → 0.13.13
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/.yarn/install-state.gz +0 -0
- package/README.md +19 -3
- package/RFCs/07-28-git-module-store-rfc.md +445 -30
- package/editing-history/202608122230-caps-project-module-store.md +81 -0
- package/editing-history/202608130003-release-0.13.13.md +9 -0
- package/lib/package.json +1 -1
- package/package.json +1 -1
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/README.md
CHANGED
|
@@ -132,7 +132,14 @@ Related examples and workflows:
|
|
|
132
132
|
|calcit-lang/lilac |main
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
Run `caps` to
|
|
135
|
+
Run `caps` to resolve the recursive dependency graph and install it. Immutable revisions are stored under
|
|
136
|
+
`~/.config/calcit/modules/.store/`, while the current project receives links under `.calcit/modules/`.
|
|
137
|
+
Different projects can therefore use different revisions without switching a shared checkout. Existing
|
|
138
|
+
`~/.config/calcit/modules/<repo>/` checkouts remain a runtime fallback during migration.
|
|
139
|
+
|
|
140
|
+
Published SemVer tags are preferred. Branch refs remain supported for development, but `caps` warns with
|
|
141
|
+
the resolved commit. When a graph requests several SemVer tags for one repository, the highest requested
|
|
142
|
+
version is selected and reported.
|
|
136
143
|
|
|
137
144
|
`:calcit-version` helps with version checks and provides hints in [CI](https://github.com/calcit-lang/setup-cr).
|
|
138
145
|
|
|
@@ -144,11 +151,20 @@ To load modules, use `:modules` configuration and the runtime snapshot file `cal
|
|
|
144
151
|
:modules $ [] |memof/calcit.cirru |lilac/
|
|
145
152
|
```
|
|
146
153
|
|
|
147
|
-
Paths defined in `:modules`
|
|
148
|
-
i.e.
|
|
154
|
+
Paths defined in `:modules` first load from the snapshot directory's `.calcit/modules/`, then fall back to
|
|
155
|
+
`~/.config/calcit/modules/`, i.e. `.calcit/modules/memof/calcit.cirru` or the legacy global path.
|
|
149
156
|
|
|
150
157
|
Modules ending with `/` are automatically suffixed with `calcit.cirru`, and still fall back to `compact.cirru` for compatibility.
|
|
151
158
|
|
|
159
|
+
Inspect and verify the resolved graph with:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
caps tree
|
|
163
|
+
caps why calcit-lang/memof
|
|
164
|
+
caps status
|
|
165
|
+
caps verify
|
|
166
|
+
```
|
|
167
|
+
|
|
152
168
|
### Development
|
|
153
169
|
|
|
154
170
|
Local validation commands:
|
|
@@ -1,59 +1,474 @@
|
|
|
1
|
-
# RFC: Git
|
|
1
|
+
# RFC: Git 模块依赖图与项目级模块视图
|
|
2
2
|
|
|
3
3
|
状态:Draft
|
|
4
4
|
日期:2026-07-28
|
|
5
|
+
更新:2026-08-12
|
|
5
6
|
关联:`docs/run/load-deps.md`
|
|
6
7
|
|
|
7
|
-
## 1.
|
|
8
|
+
## 1. 决策摘要
|
|
8
9
|
|
|
9
|
-
Calcit
|
|
10
|
+
Calcit 继续使用 GitHub repository + Git ref 管理模块,不建设 registry,
|
|
11
|
+
也暂不引入 workspace、依赖别名和同一项目内的多版本 namespace 隔离。
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
这次演进增加四层能力:
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
1. 全局目录可以同时保存同一模块的多个 revision;
|
|
16
|
+
2. 每个项目通过 `.calcit/modules/` 中的链接获得自己的模块视图;
|
|
17
|
+
3. `caps` 递归读取各模块的 `deps.cirru`,解析单版本依赖图并提供
|
|
18
|
+
`tree`、`why`、`status` 和 `verify`;
|
|
19
|
+
4. native 模块的构建产物按平台和 ABI 隔离,并生成可检查的构建回执。
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
依赖应优先声明为发布 tag。允许分支用于开发,但每次解析都必须 warning,
|
|
22
|
+
并显示最终 commit。多个可比较的版本 tag 冲突时统一选择最高版本,并显示
|
|
23
|
+
声明来源;不可比较的 branch、commit 或非版本 tag 不猜测“更高版本”。
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
整个迁移保持现有 `calcit.cirru` 的 `:modules` 内容可用。旧项目仍可从
|
|
26
|
+
`~/.config/calcit/modules/<repo>/` 加载,新项目则优先从自身
|
|
27
|
+
`.calcit/modules/<repo>/` 加载。
|
|
18
28
|
|
|
19
|
-
##
|
|
29
|
+
## 2. 目标与非目标
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
### 2.1 目标
|
|
32
|
+
|
|
33
|
+
- 两个项目可以使用同一模块的不同版本,互不切换对方的 checkout;
|
|
34
|
+
- 相同 repository + commit + native build key 在本机只安装一份;
|
|
35
|
+
- `caps deps.cirru` 在没有 `calcit.cirru` 的目录中也能完成递归下载;
|
|
36
|
+
- 依赖选择结果确定、可解释,冲突能追溯到每条父依赖;
|
|
37
|
+
- 项目链接只在完整解析、下载和构建成功后切换;
|
|
38
|
+
- native 产物不会在不同 target、Calcit ABI 或 `cirru_edn` ABI 间误用;
|
|
39
|
+
- 当前 `caps`、`caps outdated`、`caps upgrade`、`caps status` 和
|
|
40
|
+
`caps reset` 在迁移期继续可用。
|
|
41
|
+
|
|
42
|
+
### 2.2 非目标
|
|
43
|
+
|
|
44
|
+
- 不建设中心 registry、账号或发布服务;
|
|
45
|
+
- 第一阶段不支持 `^1.2`、`~1.2` 等版本范围,依赖值仍是准确 Git ref;
|
|
46
|
+
- 不允许同一项目同时加载同一模块的两个版本;
|
|
47
|
+
- 不用模块别名解决 namespace 冲突;
|
|
48
|
+
- 不要求所有历史模块立刻增加 native manifest;
|
|
49
|
+
- 不在第一阶段自动删除 legacy clone 或未引用的 store 内容。
|
|
50
|
+
|
|
51
|
+
## 3. 目录模型
|
|
52
|
+
|
|
53
|
+
当前正式路径是 `~/.config/calcit/modules/`。新 store 放在它下面,避免再引入
|
|
54
|
+
一套顶级目录;路径解析应集中到一个 helper,后续再考虑 XDG 或其他平台差异。
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
~/.config/calcit/modules/
|
|
58
|
+
.store/git/<owner>/<repo>/<commit>/source/
|
|
59
|
+
.store/git/<owner>/<repo>/<commit>/realizations/<build-key>/
|
|
60
|
+
<repo>/ # legacy clone,迁移期保留
|
|
61
|
+
|
|
62
|
+
<project>/
|
|
63
|
+
deps.cirru
|
|
64
|
+
.calcit/
|
|
65
|
+
caps-state.cirru
|
|
66
|
+
modules/
|
|
67
|
+
<repo> -> ~/.config/calcit/modules/.store/.../source/
|
|
68
|
+
<native-repo> -> .../realizations/<build-key>/
|
|
69
|
+
tmp/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Git tag 或 branch 只负责解析 commit;store 的 source 身份始终是 canonical Git
|
|
73
|
+
URL + resolved commit。这样同一 commit 被两个 tag 指向时不会重复保存。
|
|
74
|
+
|
|
75
|
+
`.calcit/caps-state.cirru` 是本次安装的诊断记录,不是 lockfile,也不参与下一次版本
|
|
76
|
+
选择。它至少记录:
|
|
77
|
+
|
|
78
|
+
- canonical repository URL;
|
|
79
|
+
- 所有请求来源及声明的 ref;
|
|
80
|
+
- 选中的 ref、ref 类型和 resolved commit;
|
|
81
|
+
- 项目链接目标;
|
|
82
|
+
- branch warning 和版本冲突 warning;
|
|
83
|
+
- native build key、回执路径与验证状态。
|
|
84
|
+
|
|
85
|
+
项目侧由 `caps` 生成或维护的内容统一放在 `.calcit/` 内,包括模块链接、状态、
|
|
86
|
+
临时文件、构建日志以及未来的本机 override sidecar,避免在项目根目录或模块链接
|
|
87
|
+
目录散落工具文件。项目根目录只保留用户维护、需要纳入版本控制的 `deps.cirru`。
|
|
88
|
+
`.calcit/` 整体默认应加入 `.gitignore`;其中内容是本机安装状态,不能作为跨机器
|
|
89
|
+
依赖身份。
|
|
90
|
+
|
|
91
|
+
### 3.1 模块目录名冲突
|
|
92
|
+
|
|
93
|
+
现有 `:modules` 使用 repository basename,例如 `memof/`。因此第一阶段继续用
|
|
94
|
+
basename 建立项目链接。如果依赖图里出现 `owner-a/utils` 与 `owner-b/utils`,
|
|
95
|
+
`caps` 必须报错并列出两者,不能静默覆盖。依赖别名需要同时解决 namespace
|
|
96
|
+
身份,不在本 RFC 范围内。
|
|
97
|
+
|
|
98
|
+
### 3.2 原子切换
|
|
99
|
+
|
|
100
|
+
`caps` 按以下顺序修改本机状态:
|
|
101
|
+
|
|
102
|
+
1. 在 store 的 `.store/tmp/` 下创建临时目录,解析 ref、下载 source(与 store 同文件系统,保证 rename 原子);项目侧临时 project view 写入 `.calcit/tmp/`;
|
|
103
|
+
2. 完成递归依赖图和版本选择;
|
|
104
|
+
3. 完成需要的 native realization 与验证;
|
|
105
|
+
4. 写入临时 project view;
|
|
106
|
+
5. 原子替换 `.calcit/modules/` 中的项目链接和 `.calcit/caps-state.cirru`。
|
|
107
|
+
|
|
108
|
+
任何一步失败都保留项目原来的链接。下载完成但未被链接的 store 内容可以留给
|
|
109
|
+
后续安装复用,由未来的 `caps clean` 回收。
|
|
110
|
+
|
|
111
|
+
Windows 上优先使用 directory junction;不支持链接时允许显式 copy fallback,
|
|
112
|
+
并在 `caps status` 中标记为非共享副本,不能假装已经去重。
|
|
113
|
+
|
|
114
|
+
## 4. `deps.cirru` 协议
|
|
115
|
+
|
|
116
|
+
保持当前字符串 map 兼容,先不引入复杂 constraint 对象:
|
|
117
|
+
|
|
118
|
+
```cirru
|
|
119
|
+
{}
|
|
120
|
+
:version |0.16.67
|
|
121
|
+
:calcit-version |0.13.10
|
|
122
|
+
:dependencies $ {}
|
|
123
|
+
|Respo/respo-ui.calcit |0.7.2
|
|
124
|
+
|calcit-lang/calcit.std |0.2.15
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
字段职责:
|
|
128
|
+
|
|
129
|
+
- `:version`:当前项目或模块自身的发布版本,由 `caps version` 管理;
|
|
130
|
+
- `:calcit-version`:期望使用的 Calcit 工具链版本;
|
|
131
|
+
- `:dependencies`:repository 到准确 Git tag、branch 或 commit 的映射。
|
|
132
|
+
|
|
133
|
+
依赖 key 继续要求 canonical `owner/repo`。GitHub URL 仅作为 `caps add` 输入,
|
|
134
|
+
写回文件前必须规范化。
|
|
135
|
+
|
|
136
|
+
### 4.1 项目版本迁移
|
|
137
|
+
|
|
138
|
+
当前项目版本在 `calcit.cirru :version`。迁移时不能立即删除该字段:
|
|
139
|
+
|
|
140
|
+
1. `deps.cirru :version` 存在时,它是发布工具的权威值;
|
|
141
|
+
2. 只有 `calcit.cirru :version` 时,`caps version get` 读取旧值并提示迁移;
|
|
142
|
+
3. `caps version set/bump` 只写入 `deps.cirru`,不隐式改写机器生成的 snapshot;
|
|
143
|
+
迁移期 snapshot `:version` 继续作为旧版 `cr` 的兼容字段,允许暂时不同;
|
|
144
|
+
4. `cr config set version` 先保留,但提示改用 `caps version set`;
|
|
145
|
+
5. 等生态完成迁移后,再让 snapshot 的 `:version` 变为可选并停止写入镜像。
|
|
146
|
+
|
|
147
|
+
建议命令:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
caps version get
|
|
151
|
+
caps version set 0.16.68
|
|
152
|
+
caps version bump patch
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`caps version` 必须验证 SemVer。安装 tag 时,如果模块的 `deps.cirru :version`
|
|
156
|
+
与 tag(允许 tag 带一个 `v` 前缀)不一致,`caps verify` 报错。branch 模块只做
|
|
157
|
+
warning,因为 branch 没有稳定发布版本身份。
|
|
158
|
+
|
|
159
|
+
### 4.2 standalone `deps.cirru`
|
|
160
|
+
|
|
161
|
+
位置参数继续是依赖文件:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
caps ./fixtures/demo/deps.cirru
|
|
165
|
+
caps /tmp/download-only/deps.cirru tree
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
项目根目录始终取该文件的父目录,项目视图写到同目录的 `.calcit/modules/`。
|
|
169
|
+
这个流程不得要求同目录存在 `calcit.cirru`、`package.json` 或 Git repository。
|
|
170
|
+
如果只想预览,`caps <file> tree --resolve` 可以解析远端但不创建项目链接。
|
|
171
|
+
|
|
172
|
+
## 5. ref 分类和 warning
|
|
173
|
+
|
|
174
|
+
不能只根据字符串长相判断 branch 或 tag。`caps` 获取远端 refs 后按以下顺序
|
|
175
|
+
分类:
|
|
176
|
+
|
|
177
|
+
1. 精确匹配 `refs/tags/<ref>`:tag;
|
|
178
|
+
2. 精确匹配 `refs/heads/<ref>`:branch;
|
|
179
|
+
3. 完整 commit hash:commit;
|
|
180
|
+
4. 都不匹配:错误。
|
|
181
|
+
|
|
182
|
+
如果远端同时存在同名 tag 和 branch,拒绝并要求用户明确修改命名;Git 自己的
|
|
183
|
+
模糊 ref 选择不能成为包管理语义。
|
|
184
|
+
|
|
185
|
+
warning 分级:
|
|
186
|
+
|
|
187
|
+
- SemVer tag:正常推荐路径;
|
|
188
|
+
- 非 SemVer tag:可复现,但无法参与“选择最高版本”,给提示;
|
|
189
|
+
- branch:每次安装 warning,并显示 branch -> commit;
|
|
190
|
+
- commit:可复现,但缺少发布版本语义,给提示。
|
|
191
|
+
|
|
192
|
+
`--ci` 不隐藏 warning。未来可增加 `--deny-branch`,让发布 CI 把 branch 依赖
|
|
193
|
+
升级为错误。
|
|
194
|
+
|
|
195
|
+
## 6. 递归解析与单版本选择
|
|
196
|
+
|
|
197
|
+
### 6.1 解析过程
|
|
198
|
+
|
|
199
|
+
`caps` 维护带 provenance 的请求集合:
|
|
22
200
|
|
|
23
201
|
```text
|
|
24
|
-
|
|
25
|
-
|
|
202
|
+
Request {
|
|
203
|
+
repository,
|
|
204
|
+
requested_ref,
|
|
205
|
+
requested_by, # root 或 owner/repo@resolved-ref
|
|
206
|
+
}
|
|
26
207
|
```
|
|
27
208
|
|
|
28
|
-
|
|
209
|
+
解析采用 fixpoint,而不是“下载时顺手递归”:
|
|
210
|
+
|
|
211
|
+
1. 读取 root `deps.cirru`,产生第一批 requests;
|
|
212
|
+
2. 为每个 repository 解析 refs 并选择当前 revision;
|
|
213
|
+
3. 读取选中 revision 的 `deps.cirru`,加入它的 requests;
|
|
214
|
+
4. 如果新请求改变了某模块的选择,撤销旧 revision 贡献的传递请求,再展开新
|
|
215
|
+
revision;
|
|
216
|
+
5. 重复直到选择和边集合都不再变化;
|
|
217
|
+
6. 检测 dependency cycle,`tree` 展示 cycle 标记但安装不重复展开;
|
|
218
|
+
7. graph 完整后才进入 native build 和项目链接阶段。
|
|
219
|
+
|
|
220
|
+
模块没有 `deps.cirru` 时按空依赖处理并给兼容性提示。文件存在但无法解析,或
|
|
221
|
+
`:dependencies` 类型错误时必须失败,不能静默当作空依赖。
|
|
222
|
+
|
|
223
|
+
### 6.2 冲突规则
|
|
224
|
+
|
|
225
|
+
同一 repository 在项目内只能有一个选择:
|
|
226
|
+
|
|
227
|
+
- 所有请求都是可解析 SemVer 的 tag:选择最高 SemVer;
|
|
228
|
+
- 多个请求指向同一 commit:合并为一个选择;
|
|
229
|
+
- 相同 branch 名:选择该 branch 当前远端 commit,并 warning;
|
|
230
|
+
- tag 与 branch 混合时,仍在所有请求中选择最高 SemVer tag 并给强 warning;
|
|
231
|
+
发布 tag 比可变 branch 更适合作为现有项目的兼容裁决,根项目的较低 tag 也
|
|
232
|
+
不压过传递依赖明确请求的较高 tag;
|
|
233
|
+
- 不同 branch、commit 与其他 ref、或多个不可比较 tag:不能定义“更高”。如果
|
|
234
|
+
root 有直接声明,使用 root 声明并给强 warning;没有 root 直接声明则报错,
|
|
235
|
+
要求 root 在 `deps.cirru` 中显式裁决。
|
|
29
236
|
|
|
30
|
-
|
|
237
|
+
选择较高 SemVer tag 时,即使能自动继续,也必须打印类似:
|
|
31
238
|
|
|
32
|
-
|
|
239
|
+
```text
|
|
240
|
+
warning: selected Respo/respo.calcit@0.16.67
|
|
241
|
+
requested 0.16.65 by Cumulo/cumulo-reel.calcit@0.6.7
|
|
242
|
+
requested 0.16.67 by root
|
|
243
|
+
```
|
|
33
244
|
|
|
34
|
-
|
|
245
|
+
`caps --strict` 可把所有版本提升和不可复现 ref warning 变为错误,适合对依赖
|
|
246
|
+
漂移敏感的 CI。第一阶段不自动寻找远端“最新版本”;最高版本只在依赖图实际
|
|
247
|
+
请求的版本集合中选择。
|
|
35
248
|
|
|
36
|
-
|
|
249
|
+
### 6.3 确定性
|
|
37
250
|
|
|
38
|
-
|
|
251
|
+
- repository、边、warning 和 tree 子节点统一排序后输出;
|
|
252
|
+
- SemVer 比较使用标准 precedence,不用发布时间;
|
|
253
|
+
- build metadata 不参与 SemVer precedence,相同 precedence 但不同 tag 指向不同
|
|
254
|
+
commit 时视为不可裁决冲突;
|
|
255
|
+
- 解析结果中的每个 ref 都保存 resolved commit;
|
|
256
|
+
- 网络并发只能改变耗时,不能改变选择或输出顺序。
|
|
39
257
|
|
|
40
|
-
|
|
258
|
+
## 7. `caps tree` 与命令演进
|
|
259
|
+
|
|
260
|
+
在保留已有命令的基础上增加:
|
|
41
261
|
|
|
42
262
|
```bash
|
|
43
|
-
caps
|
|
44
|
-
caps
|
|
45
|
-
caps
|
|
46
|
-
caps
|
|
47
|
-
caps
|
|
48
|
-
caps
|
|
263
|
+
caps [deps.cirru] # resolve + install + link
|
|
264
|
+
caps [deps.cirru] add owner/repo@0.1.2
|
|
265
|
+
caps [deps.cirru] remove owner/repo
|
|
266
|
+
caps [deps.cirru] tree
|
|
267
|
+
caps [deps.cirru] why owner/repo
|
|
268
|
+
caps [deps.cirru] update [owner/repo]
|
|
269
|
+
caps [deps.cirru] verify
|
|
270
|
+
caps [deps.cirru] status
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
兼容规则:
|
|
274
|
+
|
|
275
|
+
- 现有 `caps add owner/repo --version 0.1.2` 继续工作;
|
|
276
|
+
- 现有 `upgrade` 先作为 `update` 的别名,不立即删除;
|
|
277
|
+
- 现有 `download owner/repo@ref` 可以内部构造临时 root graph,默认也递归;
|
|
278
|
+
- `reset` 只处理 legacy clone 或显式 path/checkout override。不可变 store 不做
|
|
279
|
+
`git reset --hard`,项目链接损坏时由 `caps` 重建。
|
|
280
|
+
|
|
281
|
+
`caps tree` 默认展示实际选择和来源,而不只是 root 声明:
|
|
282
|
+
|
|
283
|
+
```text
|
|
284
|
+
root
|
|
285
|
+
├─ Respo/reel.calcit@0.6.7
|
|
286
|
+
│ └─ Respo/respo.calcit@0.16.67 ↑ requested 0.16.65
|
|
287
|
+
└─ Respo/respo.calcit@0.16.67
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
建议同时支持:
|
|
291
|
+
|
|
292
|
+
- `--depth <n>`:限制展示深度;
|
|
293
|
+
- `--all`:重复展示共享子图,否则使用 `(*)` 引用;
|
|
294
|
+
- `--format json`:供 Agent 和 CI 读取,stdout 必须是单个 JSON;
|
|
295
|
+
- `--offline`:只使用已经解析进 store 的 refs;
|
|
296
|
+
- `--resolve`:没有安装时允许访问远端完成预览。
|
|
297
|
+
|
|
298
|
+
`caps why <module>` 为每个 root dependency 输出到该模块的一条最短路径,并
|
|
299
|
+
列出全部直接版本请求和最终选择理由。稠密依赖图不枚举所有简单路径,避免输出
|
|
300
|
+
组合爆炸。
|
|
301
|
+
|
|
302
|
+
## 8. `cr` 的模块查找兼容层
|
|
303
|
+
|
|
304
|
+
目前多个命令各自拼接 `~/.config/calcit/modules/`。实现项目视图前先把它们
|
|
305
|
+
收敛到共享 resolver,至少覆盖运行、query、config、call-graph、docs 和 wasm
|
|
306
|
+
内部验证路径。
|
|
307
|
+
|
|
308
|
+
对于 snapshot 中的非相对模块路径,例如 `memof/`,查找顺序是:
|
|
309
|
+
|
|
310
|
+
1. `<snapshot-dir>/.calcit/modules/memof/`;
|
|
311
|
+
2. `~/.config/calcit/modules/memof/`(legacy fallback)。
|
|
312
|
+
|
|
313
|
+
`./util.cirru` 这类明确相对路径仍只相对 snapshot,不进入模块 store。项目视图
|
|
314
|
+
存在但单个模块链接缺失时仍允许逐项 fallback,并在 verbose/status 中提示,
|
|
315
|
+
这样迁移不要求一次切换所有模块。
|
|
316
|
+
|
|
317
|
+
模块源码中的 `calcit-dirname` 应解析到项目链接最终指向的完整 module view。
|
|
318
|
+
这保证现有 `get-dylib-path` 拼接 `dylibs/lib...` 的代码无需修改。
|
|
319
|
+
|
|
320
|
+
## 9. native 模块
|
|
321
|
+
|
|
322
|
+
### 9.1 为什么不能直接在 source store 运行 `build.sh`
|
|
323
|
+
|
|
324
|
+
现有脚本会删除并重建 `dylibs/`。如果直接在按 commit 共享的 source 中执行,
|
|
325
|
+
不同平台、Rust toolchain 或 Calcit ABI 的项目会相互覆盖,source 也不再不可变。
|
|
326
|
+
|
|
327
|
+
因此 native 模块分为:
|
|
328
|
+
|
|
329
|
+
- `source/`:按 commit 保存,不运行构建脚本;
|
|
330
|
+
- `realizations/<build-key>/`:从 source 创建的独立构建视图,项目链接指向这里。
|
|
331
|
+
|
|
332
|
+
realization 可以先使用完整工作树保证简单可靠;以后再用 reflink、hardlink 或
|
|
333
|
+
只读 source + artifact view 优化体积,不应在第一版提前增加复杂度。
|
|
334
|
+
|
|
335
|
+
### 9.2 build key
|
|
336
|
+
|
|
337
|
+
build key 至少包含:
|
|
338
|
+
|
|
339
|
+
- canonical repository URL 和 resolved commit;
|
|
340
|
+
- target triple 与 OS/architecture;
|
|
341
|
+
- Calcit FFI ABI version;
|
|
342
|
+
- `cirru_edn` version;
|
|
343
|
+
- Calcit version(第一阶段保守隔离);
|
|
344
|
+
- `rustc -vV` 的 toolchain identity;
|
|
345
|
+
- build command 和显式 build environment 的 hash。
|
|
346
|
+
|
|
347
|
+
同一 build key 的 realization 构建成功后可跨项目复用。失败或未完成的临时目录
|
|
348
|
+
不能被项目链接引用。
|
|
349
|
+
|
|
350
|
+
### 9.3 可选 native manifest
|
|
351
|
+
|
|
352
|
+
已有 `build.sh` 继续识别。新模块建议在自己的 `deps.cirru` 增加:
|
|
353
|
+
|
|
354
|
+
```cirru
|
|
355
|
+
:native $ {}
|
|
356
|
+
:build $ [] |sh |build.sh
|
|
357
|
+
:libraries $ [] |dylibs/libcalcit_std
|
|
358
|
+
:timeout-seconds 600
|
|
49
359
|
```
|
|
50
360
|
|
|
51
|
-
`caps
|
|
361
|
+
`:libraries` 使用不带平台扩展名的路径,`caps` 根据 target 补 `.so`、`.dylib`
|
|
362
|
+
或 `.dll`。manifest 存在时,未产生声明产物是构建失败。只有 `build.sh` 而没有
|
|
363
|
+
manifest 的旧模块仍构建,但给迁移提示,并至少验证 `dylibs/` 下存在当前平台
|
|
364
|
+
动态库。
|
|
365
|
+
|
|
366
|
+
构建脚本是来自依赖的代码执行。`caps` 执行前必须显示 module、ref、commit、
|
|
367
|
+
脚本路径和 hash;CI 日志也不能隐藏。后续可增加 allow-list,但第一阶段不突然
|
|
368
|
+
改变现有默认构建行为。
|
|
369
|
+
|
|
370
|
+
### 9.4 构建回执与验证
|
|
371
|
+
|
|
372
|
+
成功后在 realization 中写 `.calcit-native.cirru`,记录:
|
|
373
|
+
|
|
374
|
+
- build key 的全部输入;
|
|
375
|
+
- 开始/结束时间和 command;
|
|
376
|
+
- 每个产物的相对路径、大小和内容 hash;
|
|
377
|
+
- ABI version、`cirru_edn` version 和验证结果。
|
|
378
|
+
|
|
379
|
+
`caps verify` 检查:
|
|
380
|
+
|
|
381
|
+
1. project link 指向 state 声明的 source/realization;
|
|
382
|
+
2. source commit 与 store identity 一致,且没有用户修改;
|
|
383
|
+
3. native receipt 的 build key 与当前环境一致;
|
|
384
|
+
4. 声明产物存在、未通过 symlink 逃出 realization、hash 匹配;
|
|
385
|
+
5. 能加载动态库,存在 ABI 查询符号,且 ABI/EDN version 匹配;
|
|
386
|
+
6. manifest 声明的业务符号(若未来增加)存在。
|
|
387
|
+
|
|
388
|
+
动态库加载验证应放在短生命周期子进程中。错误库崩溃时只让 verifier 子进程
|
|
389
|
+
失败,`caps` 仍能报告 module、commit、产物路径和退出状态。
|
|
390
|
+
|
|
391
|
+
运行时继续执行 ABI 检查,不能因为 `caps verify` 已通过就跳过。加载错误应尝试
|
|
392
|
+
附带相邻 build receipt 的 module revision、target 和 rebuild 提示。dylib cache
|
|
393
|
+
应使用 canonical path 作为 key;项目链接在 watcher 运行期间切换后,提示重启
|
|
394
|
+
进程,不尝试卸载已加载 library。
|
|
395
|
+
|
|
396
|
+
## 10. 状态、override 与人工修改
|
|
397
|
+
|
|
398
|
+
共享 store 视为不可变。开发某个依赖时不要在 store 中直接编辑,后续使用显式
|
|
399
|
+
override,例如 `.calcit/overrides.cirru` 本机 sidecar 或 CLI 参数指向 path checkout。
|
|
400
|
+
override 的正式语法另开小 RFC,不阻塞 store 和递归解析。
|
|
401
|
+
|
|
402
|
+
在 override 落地前,`caps status` 至少区分:
|
|
403
|
+
|
|
404
|
+
- dependency graph 是否仍能解析;
|
|
405
|
+
- store source 是否完整、commit 是否匹配;
|
|
406
|
+
- project link 是否缺失或指错;
|
|
407
|
+
- 是否使用 legacy global clone;
|
|
408
|
+
- branch 与版本选择 warning;
|
|
409
|
+
- native realization 是否适配当前环境;
|
|
410
|
+
- source 或 realization 是否被手工修改。
|
|
411
|
+
|
|
412
|
+
发现 store 被修改时不自动 reset。重新安装到新的临时目录并原子替换,旧的损坏
|
|
413
|
+
目录留待显式 clean,可以减少误删用户内容的风险。
|
|
414
|
+
|
|
415
|
+
## 11. 渐进实现顺序
|
|
416
|
+
|
|
417
|
+
### Phase A:共享路径解析和元数据
|
|
418
|
+
|
|
419
|
+
- 集中 `cr`/docs/query 的 module resolver;
|
|
420
|
+
- 项目 `.calcit/modules` 优先、legacy global fallback;
|
|
421
|
+
- `PackageDeps` 支持 `:version` 与可选 `:native`;
|
|
422
|
+
- 增加 `caps version`,只管理 `deps.cirru`;
|
|
423
|
+
- 远端 ref 分类,branch/non-SemVer warning;
|
|
424
|
+
- 保持当前单层下载行为作为兼容基线。
|
|
425
|
+
|
|
426
|
+
### Phase B:多版本 store 与项目链接
|
|
427
|
+
|
|
428
|
+
- source 以 canonical repo + commit 入 store;
|
|
429
|
+
- 安装完成后原子创建项目链接和 state;
|
|
430
|
+
- 从干净 legacy clone 导入/复用 commit,不删除旧目录;
|
|
431
|
+
- `caps status` 同时理解 legacy 与 project view。
|
|
432
|
+
|
|
433
|
+
### Phase C:递归依赖图
|
|
434
|
+
|
|
435
|
+
- 带 provenance 的 fixpoint resolver;
|
|
436
|
+
- SemVer tag 最高版本选择和不可比较冲突规则;
|
|
437
|
+
- `caps tree`、`caps why`、JSON 输出;
|
|
438
|
+
- cycle、缺失 `deps.cirru`、损坏子依赖文件的测试。
|
|
439
|
+
|
|
440
|
+
### Phase D:native realization
|
|
441
|
+
|
|
442
|
+
- build key、隔离构建目录和 receipt;
|
|
443
|
+
- legacy `build.sh` 兼容与可选 native manifest;
|
|
444
|
+
- `caps verify` 子进程加载检查;
|
|
445
|
+
- runtime 错误关联 receipt。
|
|
446
|
+
|
|
447
|
+
每个 phase 都可以单独发布,不能要求一次性修改所有模块。Phase A/B 稳定后再让
|
|
448
|
+
默认 `caps` 开启递归解析;此前可用实验 flag 在真实 Respo 依赖链验证。
|
|
449
|
+
|
|
450
|
+
## 12. 测试与验收
|
|
52
451
|
|
|
53
|
-
|
|
452
|
+
除仓库常规 `cargo fmt`、`cargo clippy -- -D warnings`、`cargo test`、
|
|
453
|
+
`yarn compile`、`yarn check-all` 和 `yarn check-agent-interface` 外,依赖管理需覆盖:
|
|
54
454
|
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
455
|
+
- 两项目请求同模块不同 tag,链接到不同 commit;
|
|
456
|
+
- 两项目请求相同 commit,store 只保存一份 source;
|
|
457
|
+
- 菱形依赖选择最高 SemVer,并输出全部 provenance warning;
|
|
458
|
+
- branch 依赖显示 resolved commit,`--strict` 失败;
|
|
459
|
+
- branch/tag 混合时优先 SemVer tag 并强 warning;全是不可比较 ref 且没有 root
|
|
460
|
+
裁决时失败;
|
|
461
|
+
- 依赖环不会无限递归,`tree` 输出稳定;
|
|
462
|
+
- 子模块 `deps.cirru` 损坏时安装失败且旧项目链接不变;
|
|
463
|
+
- standalone `deps.cirru` 在空目录完成安装;
|
|
464
|
+
- basename 冲突不会覆盖链接;
|
|
465
|
+
- native build key 在 target/ABI/toolchain 改变后失效;
|
|
466
|
+
- native 构建中断不会留下可复用的“成功”目录;
|
|
467
|
+
- 产物缺失、hash 改变、错误架构、ABI 不匹配和系统依赖缺失均能定位到具体
|
|
468
|
+
module revision;
|
|
469
|
+
- legacy `~/.config/calcit/modules/<repo>` 项目仍可运行;
|
|
470
|
+
- Respo 等真实项目的 compile、类型查询与 examples 回归通过。
|
|
58
471
|
|
|
59
|
-
|
|
472
|
+
最终验收标准:项目之间不再通过切换全局 checkout 相互影响;依赖图的每个选择
|
|
473
|
+
都可用 `tree/why` 解释;失败安装不破坏现有项目;native 产物不会跨不兼容环境
|
|
474
|
+
复用,并能在运行前通过 `caps verify` 发现主要错误。
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# caps project module store and recursive dependency graph
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
- Added a commit-addressed global module store under
|
|
6
|
+
`~/.config/calcit/modules/.store/` and a per-project module view under
|
|
7
|
+
`.calcit/modules/`.
|
|
8
|
+
- Made runtime module loading prefer the project view while retaining the
|
|
9
|
+
legacy global module directory as a fallback.
|
|
10
|
+
- Added recursive `deps.cirru` resolution with deterministic highest-SemVer
|
|
11
|
+
selection, branch warnings, request provenance, and basename collision
|
|
12
|
+
rejection.
|
|
13
|
+
- Added `caps tree`, `caps why`, `caps verify`, strict warning handling, and
|
|
14
|
+
`caps version get/set/bump`.
|
|
15
|
+
- Isolated native `build.sh` execution in keyed realizations so shared source
|
|
16
|
+
revisions stay clean and incompatible build outputs are not reused.
|
|
17
|
+
- Kept generated project state, links, temporary files, and local ignore rules
|
|
18
|
+
inside `.calcit/`.
|
|
19
|
+
|
|
20
|
+
## Compatibility findings
|
|
21
|
+
|
|
22
|
+
- Older module metadata may omit `:dependencies`; it is treated as an empty
|
|
23
|
+
graph. A present but malformed `:dependencies` still fails the install.
|
|
24
|
+
- Existing projects frequently mix published tags with transitive `main`
|
|
25
|
+
dependencies. Published SemVer tags take precedence over mutable refs and
|
|
26
|
+
produce an explicit warning. Completely incomparable mutable refs still
|
|
27
|
+
require a direct root decision.
|
|
28
|
+
- Dense graphs make exhaustive `why` path enumeration impractical. The command
|
|
29
|
+
reports one shortest path per root dependency and all direct version
|
|
30
|
+
requests instead.
|
|
31
|
+
- Review changed `caps reset` to rebuild project links instead of applying
|
|
32
|
+
`git reset --hard` to shared state. Existing store hits now reject the wrong
|
|
33
|
+
commit or local changes before they are linked.
|
|
34
|
+
- Remote discovery prefers non-interactive HTTPS, falls back to SSH outside CI,
|
|
35
|
+
prints per-module progress, and resolves up to six repositories concurrently.
|
|
36
|
+
Temporary clone names include the repository so equal refs such as `main`
|
|
37
|
+
cannot collide.
|
|
38
|
+
- `cr config modules` now uses the same project-first candidate search as the
|
|
39
|
+
runtime and continues from an invalid `calcit.cirru` to a valid legacy
|
|
40
|
+
`compact.cirru` candidate.
|
|
41
|
+
- Follow-up review fixes use `Path::is_absolute` for module paths, disable
|
|
42
|
+
Git credential prompts in `caps outdated`, and create Windows directory
|
|
43
|
+
junctions before falling back to directory symlinks.
|
|
44
|
+
- The follow-up pass gives isolated commit hashes their own fetch-and-detached
|
|
45
|
+
checkout path, namespaces staging directories with an identity hash, and
|
|
46
|
+
keeps all network Git operations non-interactive with HTTPS-to-SSH fallback
|
|
47
|
+
where supported.
|
|
48
|
+
- Native receipts now record every `dylibs/` artifact's relative path, size,
|
|
49
|
+
and MD5. Reuse and `caps verify` reject malformed receipts, path escapes,
|
|
50
|
+
symlinks, unlisted files, and changed contents. Native staging lives beside
|
|
51
|
+
the destination realization so its final rename stays on one filesystem.
|
|
52
|
+
- On Windows a failed junction and symlink attempt uses a copy fallback. The
|
|
53
|
+
generated state records `:view-mode`, while `caps status` reports a
|
|
54
|
+
non-shared copy rather than treating it as a deduplicated store link.
|
|
55
|
+
|
|
56
|
+
## Real-project verification
|
|
57
|
+
|
|
58
|
+
- Fast-forwarded clean local checkouts of `lilac`, `calcit.std`, `calcit-http`,
|
|
59
|
+
and `guidebook` before validation. `calcit.std` advanced to remote main;
|
|
60
|
+
the other three were already current.
|
|
61
|
+
- Installed and checked standalone dependency files for `lilac`, `calcit.std`,
|
|
62
|
+
`calcit-http`, and the ten-module transitive `guidebook` graph in temporary
|
|
63
|
+
project roots sharing a temporary store.
|
|
64
|
+
- Confirmed project-view loading with a copied `memof` snapshot and
|
|
65
|
+
`cr query ns lilac.core`.
|
|
66
|
+
- Built `calcit.std@0.2.15` as a native realization, reused the cached build on
|
|
67
|
+
the second install, passed `caps verify`, then confirmed a changed ABI build
|
|
68
|
+
key is rejected until a normal `caps` install switches the project link.
|
|
69
|
+
- Installed the release `cr` and `caps` binaries into `~/.cargo/bin`, then
|
|
70
|
+
installed modules directly inside updated `lilac` and `guidebook` checkouts.
|
|
71
|
+
`guidebook` resolved ten modules, reported all conflicts/branch refs, and
|
|
72
|
+
passed `status`, `verify`, and `cr query ns respo.core` using project links.
|
|
73
|
+
|
|
74
|
+
## Repository verification
|
|
75
|
+
|
|
76
|
+
- `cargo fmt -- --check`
|
|
77
|
+
- `cargo clippy -- -D warnings`
|
|
78
|
+
- `cargo test`
|
|
79
|
+
- `yarn compile`
|
|
80
|
+
- `yarn check-all`
|
|
81
|
+
- `yarn check-agent-interface`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# release 0.13.13 from caps module-store branch
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
- Released version `0.13.13` directly from `codex/caps-project-module-store`
|
|
6
|
+
while keeping the feature branch unmerged, as requested.
|
|
7
|
+
- Kept the Rust crate, npm package, and workspace lockfile versions aligned.
|
|
8
|
+
- The branch had already passed PR CI; the release update was additionally
|
|
9
|
+
checked with formatting and the `caps` test suite.
|
package/lib/package.json
CHANGED