Repository navigation
Commit a888ba5
test(cli): json-stdout-purity drives
domain:devx#2 · os-justin · session_01QSeKYoZarrfSp6eFqVaxPo
Part of #27114 (the card stays open until a scheduled `Nightly tiers`
run is green)
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:夜间测试 `json-stdout-purity` 现在实际驱动 `os plugin install --json` 与 `os
plugin trust list --json` 两条新命令,并且命令发现会顺着 `src/utils` 里替命令启动内核的工具模块找成员。
- 为什么改:两条命令随插件安装功能上线后,这个只在夜间跑的测试把它们识别为新成员却没人驱动,`main` 的夜间检查因此一直是红的。
- 风险与回滚:只改一个测试文件,不动任何产品代码,不发布任何包;回滚就是撤掉这一个提交。
- 先看:`packages/cli/test/json-stdout-purity.e2e.test.ts` 里的
`bootingUtils()` 与 `discoverFamily()`,其次是 `PREPARE['plugin install']`。
- 两分钟验证:`OS_TEST_TIERS=nightly pnpm --filter @objectstack/cli exec
vitest run --maxWorkers=2 test/json-stdout-purity.e2e.test.ts`,应看到
`Tests 77 passed (77)`。
- 需要你做的:无,席位落地。
## What changes
`packages/cli/test/json-stdout-purity.e2e.test.ts` only. It is a
nightly-tier file, so no pull request or queue run executes it.
- **Discovery follows boot utilities.** `bootingUtils()` collects the
`src/utils` modules that call `bootSchemaStack(`, plus the modules that
import one of them, until nothing new joins. The function's own
definition in `schema-migrate.ts` does not count. A command joins the
family if it boots directly or imports one of those modules, and it
declares `--json`. Before this change, the discovery was a probe of the
command's own text. Since #27374, `os plugin install` boots only through
`utils/plugin-trust-read.ts`, so that probe had dropped it from the
family while it still boots and still has a `--json` face. Today the
closure is `plugin-trust-read` and `installed-plugins-boot`. The only
commands that import them are `plugin install` and `serve`, and `serve`
has no `--json`. The discovered set is 25.
- **`plugin install` is driven to its full install.** A new `PREPARE`
map holds per-member setup. For this member it builds the artifact and
signature the way the command's own integration tests do (`createTarGz`
+ `computeIntegrity`, `generateEd25519KeyPair` + `signPayload`). It then
trusts the key in this member's database with `os plugin trust add`, and
throws if that exits non-zero. The member runs under an `OS_HOME` inside
the fixture directory. The face driven is the `installed` document,
emitted after the read-only trusted-key boot has shut down.
- **`plugin trust list` is driven bare.** It boots read-only against a
database file that does not exist yet, so the face driven is its empty
listing.
- `config-miss-stdout-purity.e2e.test.ts` is unchanged. Neither member
imports `utils/config.js`, neither refuses before boot, and that file
stays green (below).
## Tests
<details><summary>Reproduction on origin/main ad3a640: red, 1 failed /
70 passed</summary>
`OS_TEST_TIERS=nightly pnpm --filter @objectstack/cli exec vitest run
--maxWorkers=2 test/json-stdout-purity.e2e.test.ts`
```
AssertionError: expected [ 'db orphans', …(23) ] to deeply equal [ 'db orphans', …(22) ]
+ "plugin trust list",
Tests 1 failed | 70 passed (71)
os-verify-lock: VERDICT command-exit 1
```
The 2026-10-29 scheduled run showed `…(24)` vs `…(22)` with `plugin
install` too. #27374 landed afterwards, which is why `plugin install` is
absent here: its boot moved into the util.
</details>
<details><summary>After, at merged head b743a63: both files
green</summary>
```
json-stdout-purity.e2e.test.ts Test Files 1 passed (1) · Tests 77 passed (77) · VERDICT command-exit 0
config-miss-stdout-purity.e2e.test.ts Test Files 1 passed (1) · Tests 174 passed (174) · VERDICT command-exit 0
```
The count goes from 71 to 77: two members, three cases each.
</details>
<details><summary>Hand probe: install reaches its success face, not a
refusal</summary>
I ran the same fixture by hand through `bin/run-dev.js`:
- `plugin trust add` exits 0.
- `plugin install --json purity.osplugin` exits 0. stdout parses as one
document with keys `installed, replaced, integrity, boot`,
`installed.signature.keyId = purity-2026` and `boot.loads = true`.
stderr carries the boot diagnostics.
- `plugin trust list --json` exits 0 with one `{"keys":[…]}` document.
</details>
<details><summary>Teeth: one member removed from FAMILY goes red, then
restored</summary>
`node scripts/ablation-replace.mjs --file
packages/cli/test/json-stdout-purity.e2e.test.ts --anchor "'plugin trust
list': []," --delete -- …` (the same nightly invocation):
```
ablation-replace: ok mutation landed: anchor 1 -> 0, blob 60a3d4d -> 5cd1f1c7f07f
AssertionError: expected [ 'db orphans', …(24) ] to deeply equal [ 'db orphans', …(23) ]
+ "plugin trust list",
Tests 1 failed | 73 passed (74)
ablation-replace: blob after restore 60a3d4d
ablation-replace: blob at HEAD 60a3d4d
```
The discovery half has its own control: the reproduction on main is that
same discovery without the util hop, and it does not find `plugin
install`.
</details>
## Acceptance notes
- `skip-changeset`: tests only. No published file changes.
- Route taken for `plugin install`: teach the discovery the util, rather
than listing the command by hand, which note 6490929251 offered as the
other route. A hand-listed member would break the file's own `discovered
== FAMILY` equality. It would also leave the next command that boots
through a util silently outside the pin.
- Opened by the seat (`session_01QSeKYmTYfaPbLQD4BJfomW`) on the
maintainer's authorisation 「授权本席位打开这个草稿 PR」, from the dev's prepared
title, body and labels, because the dev session's classifier refused its
own `pr_create` (card note 6499909922).
## Verification
Derived gates (`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`) were run locally at b743a63. The readings
are in the dev report on #27114. CI runs the required set on this PR.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QSeKYoZarrfSp6eFqVaxPo)_
Co-authored-by: Claude <noreply@anthropic.com>os plugin install and os plugin trust list (nightly red) (#27621)1 parent 178b523 commit a888ba5
1 file changed
Lines changed: 92 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
22 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
63 | | - | |
| 64 | + | |
64 | 65 | | |
| 66 | + | |
65 | 67 | | |
| 68 | + | |
66 | 69 | | |
67 | 70 | | |
68 | 71 | | |
69 | 72 | | |
70 | 73 | | |
71 | 74 | | |
72 | 75 | | |
| 76 | + | |
73 | 77 | | |
74 | 78 | | |
75 | 79 | | |
76 | 80 | | |
77 | 81 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
82 | 86 | | |
83 | 87 | | |
84 | 88 | | |
| |||
146 | 150 | | |
147 | 151 | | |
148 | 152 | | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
149 | 163 | | |
150 | 164 | | |
151 | 165 | | |
| |||
165 | 179 | | |
166 | 180 | | |
167 | 181 | | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
168 | 217 | | |
169 | 218 | | |
170 | 219 | | |
| |||
180 | 229 | | |
181 | 230 | | |
182 | 231 | | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
183 | 261 | | |
184 | 262 | | |
185 | 263 | | |
186 | 264 | | |
187 | 265 | | |
188 | 266 | | |
189 | 267 | | |
| 268 | + | |
190 | 269 | | |
191 | 270 | | |
192 | 271 | | |
| |||
195 | 274 | | |
196 | 275 | | |
197 | 276 | | |
198 | | - | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
199 | 280 | | |
200 | 281 | | |
201 | 282 | | |
| |||
256 | 337 | | |
257 | 338 | | |
258 | 339 | | |
| 340 | + | |
| 341 | + | |
259 | 342 | | |
260 | 343 | | |
261 | 344 | | |
262 | | - | |
| 345 | + | |
263 | 346 | | |
264 | 347 | | |
265 | 348 | | |
| |||
0 commit comments