Skip to content

test(cli): json-stdout-purity drives os plugin install and os plugin trust list (nightly red) - #27621

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27114-json-purity-plugin-family
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27114-json-purity-plugin-family

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

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 feat(cli, runtime, core): os serve loads the plugins os plugin install installed, re-verified and dispatched by runtime tier; os plugin disable | enable | uninstall (#27123, slice 2 of 3) #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

Reproduction on origin/main ad3a640: red, 1 failed / 70 passed

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.

After, at merged head b743a63: both files green
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.

Hand probe: install reaches its success face, not a refusal

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.
Teeth: one member removed from FAMILY goes red, then restored

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 60a3d4db4207 -> 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  60a3d4db42077a1e9a3a2f1f1bc576e00a22095c
ablation-replace:   blob at HEAD        60a3d4db42077a1e9a3a2f1f1bc576e00a22095c

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.

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

…in trust list`

The nightly-only family pin went red on both #27123 commands. `plugin trust
list` calls `bootSchemaStack(` itself; `plugin install` boots only through
`utils/plugin-trust-read.ts`, so the discovery now follows src/utils modules
that boot the stack (to a fixed point) instead of dropping a member that
still boots. Install is driven with an artifact built, signed and trusted the
way #27335's tests do, under an OS_HOME of its own; trust list in its bare
read-only form.

Claude-Session: https://claude.ai/code/session_01QSeKYoZarrfSp6eFqVaxPo
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 29, 2026
@github-actions github-actions Bot added the tests label Oct 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 77e993ea29f1a96126f46a5e3748847ce5eb5dd3 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#2 · os-justin · session_01QSeKYmTYfaPbLQD4BJfomW

席位核对 — ACCEPT · domain:devx#2 · head b743a63197 · 2026-10-29T15:17Z

维护者速读

  • 改了什么:夜间测试 json-stdout-purity 现在实际驱动 os plugin install --json 和 os plugin trust list --json 这两条命令。命令发现也会顺着 src/utils 里替命令启动内核的工具模块去找成员。
  • 为什么改:这两条命令随插件安装功能上线后,这个只在夜间跑的测试把它们识别为新成员,却没有驱动它们,所以 main 的夜间检查一直是红的。
  • 风险与回滚:只改一个测试文件(+92/−9),不动产品代码,不发布任何包。回滚 = 还原本 PR。
  • 先看: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)。
  • 需要你做的:无。席位落地;卡片等到夜间检查转绿后再关。

席位意见:合入。dev 选择让命令发现顺着工具模块找成员,而没有把命令手工列进清单。这守住了本文件「发现集 == FAMILY」的契约,下一条经工具模块启动的命令也会被自动纳入。plugin install 驱动的是完整安装的结果,制品经过签名、密钥已受信,准备步骤失败就直接抛错,不会悄悄落到别的输出上。

Shape: draft → main, Part of #27114 (the card stays open until a scheduled Nightly tiers run is green). 1 file, packages/cli/test/json-stdout-purity.e2e.test.ts, +92/−9. Labels tests, size/m, skip-changeset; no assignees and no reviewers requested (non-governed; the seat lands it). The seat opened this PR through the relay pr_create on the maintainer's authorisation 「授权本席位打开这个草稿 PR」, because the dev's classifier denied it. The report is 6500193300 (posted on the dev's behalf); the claim is 6496940965.

Premise measured: holds. On main, utils/plugin-trust-read.ts carries plugin install's boot (since #27374), so the command-text probe misses it. The dev's repro at ad3a640e shows the red (23) vs (22) with + plugin trust list.

Seat's own read of the diff:

  • bootingUtils() seeds from src/utils modules whose masked text calls bootSchemaStack(, with the definition excluded. It closes over relative ./X.js imports to a fixed point.
  • discoverFamily() admits a command that calls it directly or imports a booting util ((../)+utils/X.js), and still requires json: Flags.boolean(.
  • Both new FAMILY rows carry a comment naming the face driven.
  • PREPARE runs os plugin trust add into the member's own DB and throws on a non-zero exit. The install gets its own OS_HOME inside the fixture.
  • Teeth: the dev's ablation of the plugin trust list row reds (24) vs (23).
  • config-miss-stdout-purity is unchanged (174/174), since neither member refuses before boot.

Gates: on head b743a63197, 53 check-runs: 34 success, 19 skipped, 0 failure; mergeable_state: clean. check-expected-skips --pr 27621: OK, all 19 skips are in main's roster (exit 0). check-governed-merges --pr 27621: NOT governed, 101 changed lines. This file runs only in the nightly tier, so the PR checks don't execute it. The dev's runs at this head are 77/77 (nightly invocation) and CLI unit 5054/5054. dispatch-gates --ran: 48 derived, 48 run.

Open questions, answered by the seat: OQ1 → A (teach the discovery the util; a hand-listed member breaks discovered == FAMILY). OQ2 → A (full signed install; it is the command's real answer and the riskier stdout path).

Accepted deviations: the dev detached the shared checkout to host its worktree. Two writes were classifier-denied and not re-routed; the seat posted the report and opened the PR.

Out of scope: none reported. Skills-docs: n/a (Metadata-protocol: none, test-only).

Landing: non-governed, 101 changed lines. In this act the seat readies the PR and arms auto-merge. On merge, the seat verifies the merged diff and posts the landing note on #27114, leaving the card open until a green Nightly tiers run. It also archives cloud session session_01QSeKYoZarrfSp6eFqVaxPo.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 29, 2026 15:19
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit a888ba5 Oct 29, 2026
54 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-27114-json-purity-plugin-family branch October 29, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant