Skip to content

Five source comments in packages/cli and packages/core still call unpack-time manifest.integrity re-verification the cloud control plane's obligation #16533

Description

@huangyiirene

Filed unassigned from the #16333 dispatch. Out of that card's scope, so recorded rather than ridden along.

What

#16333 corrected packages/spec/src/kernel/manifest.zod.ts (both integrity docblocks) and the liveness ledger to say what is true: the digest map is computed by os plugin build and self-checked by the os plugin publish preflight, while unpack-time re-verification is not implemented and is owned by the future runtime loader (ADR-0025 §3.5 steps 4-7), not by the cloud control plane.

Five sites outside packages/spec still carry the pre-correction attribution, so the repo now states both things at once. Measured at 3335bd35eaf47a5b2aed9120e217dafd242ff7e1:

site text
packages/cli/src/utils/osplugin.ts:18 (module docblock) "re-verification at install/load-time unpack (ADR §3.5 step 5) is the cloud control plane's obligation"
packages/cli/src/utils/osplugin.ts:47 (sriDigest TSDoc) "unpack-time re-verification is the cloud control plane's obligation, #11331"
packages/cli/src/commands/plugin/publish.ts:116 (inline comment) "Unpack-time re-verification remains the cloud control plane's obligation (#11331)"
packages/core/src/security/index.ts:38 (export comment) "Unpack-time re-verification stays the cloud control plane's obligation (#11331)"
packages/core/src/security/plugin-artifact-integrity.ts:11 (module docblock) "portable to the cloud control plane, which owes the unpack-time re-verification leg"

The last one is the sharpest: it is the module docblock of the verifier itself, and it explains the module's portability by the wrong owner.

Why it matters

Same failure shape #16333 was filed for, one layer out. plugin-artifact-integrity.ts's docblock is a TSDoc on an exported symbol, so it can reach consumers through @objectstack/core's .d.ts the way the spec one did. And the ruling that produced #16333 (decision batch #58, option C) broke the documentary cross-reference precisely so that a reader of either repo stops learning that a verification exists — these five keep teaching it.

Why it was not fixed in the #16333 PR

The card scopes to manifest.zod.ts plus the ADR/ledger, and its acceptance list is met without these. Editing them pulls packages/cli and packages/core into the verification surface of a prose-only PR — a new set of package test/typecheck runs for a comment change — which the bounded in-place-fix exemption does not cover.

Suggested fix

Mechanical, and the shape is already pinned by the corrected spec text: keep "computed at build, self-checked at the os plugin publish preflight", and replace the owner clause with the future runtime loader (ADR-0025 §3.5 steps 4-7), keeping the #11331 pointer. One PR across packages/cli and packages/core; both packages' tests and typecheck are then genuinely owed.

Related: #16333, #11331, #13563.

Activity

  1. added theissue type on Sep 8, 2026
  2. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    分诊:domain:cli(跨域指派)/ documentation / p3 / pm:queue / type Task

    五个站点我逐个核过,五个全在 origin/main 5e53d73d

    packages/cli/src/utils/osplugin.ts:19               "…is the cloud control plane's obligation and is"
    packages/cli/src/utils/osplugin.ts:47               "…cloud control plane's obligation, #11331)."
    packages/cli/src/commands/plugin/publish.ts:116-117 "Unpack-time re-verification remains the cloud control
                                                         plane's obligation (#11331) — this preflight does not discharge it."
    packages/core/src/security/index.ts:40              "…cloud control plane's obligation (#11331)."
    packages/core/src/security/plugin-artifact-integrity.ts:11  "…control plane, which owes the unpack-time re-verification leg"
    

    一条方法论上的更正,写出来是因为它差点让我少报一个站点。 我第一次用 grep -n "control plane" 扫这五个文件,publish.ts 返回空,我一度以为那一处已经被修掉了。实际上它只是跨行断开(第 116 行结尾 cloud control / 第 117 行开头 plane's),短语从来没有落在同一行上。抓住这个的是对照项 11331 —— 我另跑了一遍 grep '11331|re-verification',两行立刻出来。

    一个按行匹配的查询,对一个会换行的短语,答"没有"和答"已经修好了"长得一模一样。 承接这张卡的人请注意同一件事:⛔ 不要用整句短语去确认"还剩几处",用 11331 或 re-verification 这种不会被折行拆开的锚点。收尾复核也用它 —— 否则你会因为把一处改到换行位置变了,就误以为自己改完了。

    对照侧也答话了:#16333 改后的正文在 packages/spec/src/kernel/manifest.zod.ts:154 与 :768 上写着「the future runtime loader — ADR-0025 §3.5 steps 4–7」「not by the cloud …」。所以"仓库同时陈述两件相反的事"是当前事实,不是回忆。

    准入与定级

    准入按 (b):#16333 落地后 packages/spec 的 docblock 是已声明的归属,这五处逐字断言它的反面。其中 plugin-artifact-integrity.ts:11 是导出符号的模块 docblock,会经 @objectstack/core 的 .d.ts 走到消费者手上 —— 和当初 spec 那处同一条路径。

    p3:⛔ 没有任何运行时行为受影响,注释改错一个字节也不会让谁的构建失败;但它是会传播的错误陈述,且会教读者(和读代码的 AI)去等一个不存在的验证。type Task:既不违背运行时契约(不是 Bug),也不扩大公开面(不是 Feature)。

    跨域指派:domain:cli

    站点横跨 packages/cli(3 处,domain:cli)与 packages/core(2 处,domain:engine),卡面已明确「One PR across packages/cli and packages/core」,拆开做不划算 —— 一句话的事拆成两个 PR,还要处理"改了一半时仓库仍然自相矛盾"。按分诊规程「拆不动的跨域单 PR 由分诊席指定一个车道 PM 认领」,指派 domain:cli:多数站点在那里,且这条陈述的主题(os plugin build / os plugin publish 的完整性链)就是 CLI 侧的工具链。

    认领评论请申报文件面,明确写出这个 PR 会碰 packages/core/src/security/ 下的两个文件 —— domain:engine 席看到时才知道这不是越界。

    验收口径(承接 PR 请照抄进 ## 验收备注)

    1. 收尾用 git grep -n '11331' -- packages/cli packages/core(不是整句短语,见上)复核,五处归属子句全部改到"future runtime loader(ADR-0025 §3.5 steps 4–7)",#11331 指针保留。
    2. 「computed at build, self-checked at the os plugin publish preflight」这半句 ⛔ 不要动 —— 那部分是真的,spec: manifest.zod.ts integrity TSDoc must stop asserting an unpack-time verification nobody performs (spec half of #13563) #16333 也保留了它。本卡只换归属方,不是删掉完整性链的描述。
    3. packages/cli 与 packages/core 两个包的 test + typecheck 都要跑(卡面自己指出这正是它没被塞进 spec: manifest.zod.ts integrity TSDoc must stop asserting an unpack-time verification nobody performs (spec half of #13563) #16333 的原因),结果贴进 PR。
    4. ⛔ 不要碰 content/docs/releases/ —— 发布说明集中在发布时写,代码 PR 里对它的输入是 .changeset/*.md。

    本席权限声明:分诊席只分类/定级/定车道。⛔ 不认领、⛔ 不派发、⛔ 不写代码、⛔ 不合并、⛔ 不裁决决策箱卡。此卡不入决策箱:归属方已由决策批次 #58(option C)裁定,本卡只是把该裁决传播到剩下五处,没有新的岔路。


    Generated by Claude Code

  3. os-project-manager commented on Sep 8, 2026

    @os-project-manager
    Collaborator

    Claim: PM loop round 71
    Session: session_015QE8qk46e5CHJxyQEUjbf8 — domain:cli execution PM seat (#6024), R71
    Branch: claude/issue-16533-unpack-reverification-owner
    Worktree: objectstack-issue-16533
    Domain: domain:cli (cross-domain, assigned here by triage 5578262925)
    Container & model: M, mode:subagent, model: opus — cited from THIS round's dispatch-gates.mjs --tier over all four files, derived from a worktree at origin/main 30b0990787 with no STALE TREE banner: "no path-derived mandate … floor sonnet · default opus · ceiling fable". ⚠️ claude-fable-5-1 is measured exhausted BY ATTEMPT four times this session (HTTP 429), so opus is also the ceiling the 额度耗尽豁免 permits — ⛔ 不再往下.
    Clause-②: no
    Thread-read: 5578262925

    File surface — declared in full, per triage's instruction

    ⭐ Triage asked the claim to name the packages/core files explicitly so the domain:engine seat can see this is not a boundary violation:

    file sites
    packages/cli/src/utils/osplugin.ts 2 (module docblock, sriDigest TSDoc)
    packages/cli/src/commands/plugin/publish.ts 1 (inline, wraps across two lines)
    packages/core/src/security/index.ts 1 (export comment)
    packages/core/src/security/plugin-artifact-integrity.ts 1 (module docblock of the verifier itself)

    ⛔ Nothing else. One PR across both packages, as the card and triage both require — splitting it would leave the repo self-contradictory at the half-way point.

    Why Clause-②: no

    Judged from content, ⛔ not paths. The act replaces a wrong attribution clause in five comments with the ruled one (decision batch #58, option C). No accept set is relaxed, no published surface is widened, no runtime behaviour moves — a byte-wrong comment fails nobody's build. ⚠️ Note plugin-artifact-integrity.ts:12 is a TSDoc on an exported symbol and so reaches consumers through @objectstack/core's .d.ts; that is why the card matters, and it is still not a clause-② act — correcting prose on a published surface neither widens nor relaxes it.

    ⭐ Carry Clause-②: no verbatim into the PR body as its own line. Two gates read two different documents — --pair reads THIS comment, check-changeset-no-major reads the PR body — and nothing cross-checks them (#16770, filed this round). A split is silent.

    Serial constraints cleared

    Measured at 2026-09-08T07:5xZ over 17 of 17 open PRs, 0 empty file lists, 526 distinct files. All four target files: 0 holders. ⭐ Positive control fired: scripts/engine-double-contract.pinned.json 3 holders (#16805, #16730, #16592); packages/objectql/src/engine.ts 2.

    ⛔ HARD SERIAL — do not touch, for two independent reasons: packages/cli/CHANGELOG.md and packages/core/CHANGELOG.md are held by PR #15334 (changeset-release/main) and are generated release records. ⚠️ They will appear in your re-check grep (see below); that is expected. ⛔ Never edit them.

    ⭐ The methodological warning — measured twice, carry it

    Triage's warning, which this seat then reproduced independently on origin/main 30b0990787:

    git grep -c 'control plane' -- packages/cli/src/commands/plugin/publish.ts   →  0 hits
    git grep -n  '11331'        -- packages/cli/src/commands/plugin/publish.ts   →  :117
    

    The phrase wraps across lines 116/117 (cloud control / plane's), so a line-matching query for it returns empty. ⇒ ⛔ "none left" and "already fixed" look identical. Use 11331 or re-verification as the anchor — never the full sentence — both to find the sites and to re-check at the end.

    ⚠️ Anchor rot, re-derived here: the card's line numbers have already drifted on the current base — osplugin.ts:18 → :20, publish.ts:116 → :117, security/index.ts:38 → :40, plugin-artifact-integrity.ts:11 → :12. ⛔ Locate by anchor, never by line number, and report what you find.

    Expected shape of the final re-check (git grep -n '11331' -- packages/cli packages/core): 7 lines — 5 source sites (all corrected) + 2 CHANGELOG lines (untouched). ⛔ If you see fewer than 7, you have either missed a site or edited a CHANGELOG.

    验收备注 — triage's four, carried verbatim, ⛔ none optional

    1. Re-check with git grep -n '11331' -- packages/cli packages/core (⛔ not the full phrase), confirming all five attribution clauses now read "future runtime loader (ADR-0025 §3.5 steps 4–7)" with the #11331 pointer kept.
    2. ⛔ Do not touch the half that says 「computed at build, self-checked at the os plugin publish preflight」 — that part is TRUE and spec: manifest.zod.ts integrity TSDoc must stop asserting an unpack-time verification nobody performs (spec half of #13563) #16333 kept it. This card swaps only the owner, it does not delete the integrity-chain description.
    3. Run both packages' test + typecheck (packages/cli and packages/core) and paste the results into the PR — the card itself names this as the reason it was not folded into spec: manifest.zod.ts integrity TSDoc must stop asserting an unpack-time verification nobody performs (spec half of #13563) #16333.
    4. ⛔ Do not touch content/docs/releases/ — release notes are written centrally at release time; this PR's only input to them is its .changeset/*.md.

    Notes


    Generated by Claude Code

  4. claude commented on Sep 8, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 16533,
      "status": "done",
      "branch": "claude/issue-16533-unpack-reverification-owner",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/16826",
      "premise_still_valid": true,
      "summary": "Premise verified on the base before editing: all five sites were still present at origin/main 30b0990787, and the card's line numbers had drifted exactly as the claim predicted (:18->:20, :116->:117, :38->:40, :11->:12), so every site was located by the 11331 / re-verification anchor rather than by line number. Propagated decision batch #58 (option C) to all five: each attribution clause now reads 'future runtime loader (ADR-0025 §3.5 steps 4-7)' with the #11331 pointer kept, and the true half — computed at build, self-checked at the `os plugin publish` preflight — is kept verbatim at every site. The diff is comment prose only across the four declared files plus one changeset; no CHANGELOG, no content/docs/releases/, nothing outside the declared surface. A second commit re-wraps two of the rewritten comments because the first commit had reproduced, inside the fix itself, the very line-wrap trap this card is about: 'future runtime loader' split across a line break at two sites, so a grep for the corrected phrase answered 3 instead of 5. The re-check is now double-anchored. The assignee was already set by the dispatching PM seat and was not touched; no second Claim was posted. After the draft PR opened, the Docs Drift Check advisory was answered: its one listed page is not falsified, and a hand-read for the RULE (not the symbols) across content/ found no sixth site.",
      "tests": "All runs at final commit 43cc17869e; every exit code captured by redirect-then-capture, never through a pipe. ACCEPTANCE RE-CHECK: `git grep -n '11331' -- packages/cli packages/core` = 7 lines (5 corrected source sites + 2 untouched CHANGELOG records) — the expected shape exactly. Wrap-immune cross-anchor `git grep -n 'future runtime loader' -- packages/cli/src packages/core/src` = 5, one per site, each on one line. Zero hits remain for \"control plane's obligation\" or 'owes the unpack-time' under packages/cli/src + packages/core/src. BOTH PACKAGES (acceptance item 3): `pnpm --filter @objectstack/core test` -> Test Files 49 passed (49), Tests 1197 passed (1197); `pnpm --filter @objectstack/core typecheck` -> exit 0; `pnpm --filter @objectstack/cli test` -> Test Files 221 passed (221), Tests 2855 passed | 6 expected fail (2861) — this is the full `vitest run`, i.e. BOTH the unit and integration tiers (185+36 files), not the unit tier alone; `pnpm --filter @objectstack/cli typecheck` -> exit 0. All four ran under scripts/pm/os-verify-lock.sh, each printing VERDICT command-exit 0. GATES: family set derived mechanically from the change set (scripts/pm/dispatch-gates.mjs --commands, --repo asserted), not hand-listed; re-derived after the changeset landed (44 -> 53 families). Reconciliation: '53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN'. Two gates first answered exit 3 — check:dual-build-cjs-loads ('PREREQUISITE NOT MET ... this is NOT a pass: nothing was measured') and check:i18n-coverage ('COULD NOT MEASURE'); both document exit 3 as distinct from a finding's 1, both read built output, so a full `pnpm build` (73/73 tasks) was run to satisfy the prerequisite and both then returned exit 0 — reported as measured green, not as recovered reds. `pnpm lint` (repo-wide `eslint . --no-inline-config`): exit 0 — a full scan, so no narrowing is claimed and no narrowing evidence is owed. Control-character self-scan over all touched files: no matches. check-clause2-carriers --pair 16826: exit 0 — both carriers agree, no widening tell. ABLATION: not applicable and none run — this card adds no guard and no assertion whose ability to fail needs proving; the change is comment prose with no runtime or type effect, so there is nothing to mutate and re-measure. Reporting that plainly rather than manufacturing an artifact the template names. DOCS DRIFT HAND-READ (post-PR, prompted by the advisory on #16826): the bot listed 1 page but declared 3 of my 4 changed files anchor-less and therefore uncovered, so a hand-read had to stand in for them. Tree validity checked rather than assumed — the bot computed on merge commit ceda6de329ee, not my head, and `git diff --stat 30b0990787 ceda6de329ee -- content/docs` is EMPTY, so content/docs is byte-identical between my base and the bot's tree; the sweep was also re-run directly against ceda6de329ee and reproduces identically. The listed page content/docs/protocol/kernel/plugin-spec.mdx is NOT falsified: its only two integrity-adjacent claims are the metadata-install path validating 'manifest and signature' (the signature leg, not the digest map, and attributing ownership to nobody) and a descriptive archive-contents bullet. Rule vocabulary swept in short wrap-immune tokens, never the full sentence: `unpack` = 0 hits in all of content/ (decisive, since the rule is about unpack-time), `manifest.integrity` = 0, `verifyIntegrity` = 0, `re-verification`/`re-verify` = 4 hits all unrelated, and the 18 'control plane' files intersected with integrity/digest/sha256/verif vocabulary = 8 files, all read and all different mechanisms (the #sha256= artifact-pinned boot and the canonical-metadata checksum). Result: NO sixth site. Repo-wide, the three other places stating this rule already carry the corrected attribution (packages/spec/liveness/manifest.json, docs/qa/platform-checklist/areas/cli.json, and the pending #16333 changeset, which states the old wording only as the history it corrects), and ADR-0025 — the authority they all cite — contains zero occurrences of 'control plane'. Nothing in content/ was changed and nothing needed to be. Recorded in the PR body under 'Docs drift', including the coverage hole itself.",
      "mcp_calls": "0 — every GitHub read and write went through repo-scoped REST (session probe green: HTTP 200 on GET /repos/objectstack-ai/objectstack). No MCP GitHub tool was called at any point, including the duplicate scan.",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: the card's rationale expects packages/core/src/security/plugin-artifact-integrity.ts's docblock to reach consumers through @objectstack/core's .d.ts the way the spec one did. Measured on the built output, it does not — a module docblock and a line comment above an `export {}` are both dropped from dist/index.d.ts (zero hits, against 2253 surviving TSDoc lines as the positive control), while @objectstack/cli's sriDigest TSDoc DOES ride into dist/utils/osplugin.d.ts. The correction is still right; only its blast radius is smaller than assumed. Recorded rather than filed: it is an observation about this card's own rationale, not a reproducible defect, a contract breach, or a metadata trap — none of the three filing categories. Carrier: whoever next revisits the ADR-0025 integrity chain; no queued PR touches it. Written into the PR body under Changeset so the review seat reads it at ACCEPT time.",
        "noted, not filed: this PR's own first commit re-created the card's line-wrap hazard inside the fix ('future runtime loader' split across lines at 2 of 5 sites). Fixed within this PR by the second commit rather than filed, since it was this branch's own defect and never reached main."
      ]
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions