docs(cli,core): attribute unpack-time integrity re-verification to the future runtime loader, not the cloud control plane - #16826
Conversation
…egrity re-verification owner Five source comments still said unpack-time `manifest.integrity` re-verification was the cloud control plane's obligation. That attribution was corrected in `packages/spec/src/kernel/manifest.zod.ts`, so the repo stated both things at once. Swap the owner clause at all five sites to the future runtime loader (ADR-0025 §3.5 steps 4-7), keeping the `#11331` pointer and the true build/preflight half. Comment prose only: no accept set, export, signature or runtime behaviour moves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
…site Two of the five rewritten comments wrapped `future runtime loader` across a line break, which re-creates the exact hazard this change is about: a line-matching grep for the phrase answers "3 sites", and "none left" is indistinguishable from "already fixed". Pure re-wrap of lines this branch already rewrote; no wording changes. The re-check is now double-anchored — `11331` finds 7 lines (5 source + 2 generated CHANGELOG records) and `future runtime loader` finds all 5 source sites on their own lines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
📓 Docs Drift CheckThis PR changes 2 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 40 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ceda6de329ee4e9771eb01ef9ce8c04e5ef035e4 && git checkout ceda6de329ee4e9771eb01ef9ce8c04e5ef035e4
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d4401f75bbe2e9e1b6f52f9bad83e377c5c33277 43cc17869e7defa0d5949f878853812669dc2506 && git checkout -B drift-repro d4401f75bbe2e9e1b6f52f9bad83e377c5c33277 && git merge --no-ff 43cc17869e7defa0d5949f878853812669dc2506
node scripts/docs-audit/affected-docs.mjs --json d4401f75bbe2e9e1b6f52f9bad83e377c5c33277
|
Accepted by the Gate ① — CI39 raw check runs → 33 after latest-per-name collapse: 30 success, 3 skipped, 0 red, 0 pending; Gate ② — clause ②
Acceptance — the card's four, verified in the diffItem 1 — the re-check shape.
⭐ The anchor is right for FINDING sites; it is ⛔ not sufficient for JUDGING them. The rubric says "confirm the clauses now read…", and a clause is not a line. Only reading the whole comment settles it. Keeping the phrase in negation is also the better call than deleting it: a reader who remembers the old attribution gets it explicitly corrected rather than silently dropped. Item 2 — the true half kept. 「computed at build, self-checked at the Item 3 — both packages run. Reported: Item 4 — ⭐ Controlled zero on the claim that matters: the old possessive attribution ( Serial — re-measured at accept time with FULL pagination22 open PRs, all four target files → 0 other holders. Control fired:
⭐ Two things the delivery did that are worth naming
Docs drift — answered, and the caveat was measured rather than assumedThe bot listed 1 page but declared 3 of the 4 changed files anchor-less and therefore uncovered — "not a clean bill of health for those files." So the hand-read was the only coverage they got. ⭐ The delivery tested the bot's tree caveat instead of repeating it:
|
Fixes #16533
Clause-②: no
Five source comments in
packages/cliandpackages/corestill attributed unpack-timemanifest.integrityre-verification to the cloud control plane. That attribution was ruled wrong (decision batch #58, option C) and was already corrected inpackages/spec/src/kernel/manifest.zod.ts, which names the future runtime loader (ADR-0025 §3.5 steps 4–7). Until this PR the repo stated both things at once. This propagates the ruling to the remaining five sites and does nothing else.The five sites
packages/cli/src/utils/osplugin.tspackages/cli/src/utils/osplugin.tssriDigestTSDocpackages/cli/src/commands/plugin/publish.tspackages/core/src/security/index.tsverifyIntegrityexport commentpackages/core/src/security/plugin-artifact-integrity.tsEvery site was located by the
11331/re-verificationanchor, never by line number — the card's line numbers had already drifted on the base (:18→:20,:116→:117,:38→:40,:11→:12), exactly as the claim predicted.The last site is the sharpest: it had explained the module's byte-for-byte portability by the wrong owner. It now explains it by the leg itself — the module stays portable to whatever runs unpack-time re-verification.
What is deliberately NOT changed
The other half of every one of these comments — 「computed at build, self-checked at the
os plugin publishpreflight」 — is true, was kept by #16333, and is kept verbatim here. This card swaps the owner only; it does not delete the integrity-chain description. Proof: every deleted line in the diff is an attribution clause, and theos plugin publishpreflight sentence still appears at all five sites.The two
CHANGELOG.mdfiles quote the pre-correction sentence and are untouched — they are generated release records and are held by open PR #15334. They appear in the re-check grep below; that is expected.The line-wrap trap — and a note on this PR's own output
grep 'control plane'onpublish.tsreturned 0 hits at the merge-base while the site was plainly there: the phrase wrapped across lines 116/117 (cloud control/plane's). "None left" and "already fixed" look identical to a line-matching query.The first commit here reproduced that hazard in the fix itself —
future runtime loaderwrapped at two of the five sites, so a grep for the corrected phrase answered "3". The second commit re-wraps those two comments so the phrase sits on one line at all five. The re-check is now double-anchored and neither anchor can be split.Verification
All runs at the final commit
43cc17869e.Acceptance re-check —
git grep -n '11331' -- packages/cli packages/core, 7 lines (5 corrected source sites + 2 untouched CHANGELOG records):Wrap-immune cross-anchor —
git grep -n 'future runtime loader' -- packages/cli/src packages/core/srcreturns 5, one per source site, each on a single line.Both packages' test + typecheck (the card names this as exactly why it was not folded into #16333):
@objectstack/cli'stestis the fullvitest run, i.e. both theunitandintegrationtiers (185 + 36 files), not the unit tier alone.Gates — the family set was derived from the actual change set with
scripts/pm/dispatch-gates.mjs, not hand-listed:pnpm lint(repo-wideeslint . --no-inline-config): exit 0, no findings — a full scan, so no narrowing is claimed.Two gates first answered
exit 3—check:dual-build-cjs-loads(PREREQUISITE NOT MET … this is NOT a pass: nothing was measured) andcheck:i18n-coverage(COULD NOT MEASURE). Both document exit 3 as distinct from a finding's 1. Both read built output, a fullpnpm buildwas run to satisfy the prerequisite, and both then returned exit 0. They are reported as measured green, not as recovered reds.Changeset
.changeset/unpack-reverification-owner-runtime-loader.md,patchfor both packages. Measured on the built output rather than assumed:@objectstack/cli— thesriDigestTSDoc does ride into the shippeddist/utils/osplugin.d.ts, so an editor hover stops naming the control plane. Published content moves.@objectstack/core— its two sites do not reach the published bundle. A module docblock and a line comment above anexport {}are both dropped fromdist/index.d.ts(measured: zero hits, against 2253 surviving TSDoc lines as the positive control). It is declared anyway because the pre-correction sentence is quoted inpackages/core/CHANGELOG.md, which may not be hand-edited — a changeset naming the package is the only way the correction reaches that published record.This slightly qualifies the card's rationale, which expected the
plugin-artifact-integrity.tsdocblock to reach consumers through@objectstack/core's.d.tsthe way the spec one did. On the built output it does not. The correction is still right and still worth making; only the blast radius is smaller than the card assumed.Docs drift — the advisory, and the hand-read that stands in for its blind spot
The Docs Drift Check on this PR lists 1 page, but states itself that 3 of my 4 changed files yielded no anchor (
osplugin.ts,security/index.ts,plugin-artifact-integrity.ts), so the pages documenting those are not covered by that run. ⛔ The "1 page" is therefore not a near-clean bill of health — three quarters of the diff got no automated coverage, and the hand-read below is what stands in for it.Tree validity first. The bot computed on the merge commit
ceda6de329ee(head43cc17869einto based4401f75bbe2), not on my head, and a worktree cut from an oldermaincan legitimately hold a differentcontent/docs. Checked rather than assumed:git diff --stat 30b0990787 ceda6de329ee -- content/docsis empty —content/docsis byte-identical between my base and the bot's tree, so the reading below is valid on the tree the bot actually judged. The sweep was additionally re-run againstceda6de329eedirectly and reproduces identically.1. The listed page —
content/docs/protocol/kernel/plugin-spec.mdx, NOT falsified. It was listed via theos plugin publishcommand anchor offpublish.ts. It makes exactly two integrity-adjacent claims, and neither states this change's rule:registry.installPackage()), which the page itself distinguishes from the.osplugintarball a few lines later; it concerns the signature leg, not the per-file digest map, and it attributes ownership to nobody.sha256-BASE64integrity map)" — a descriptive list of what the archive contains. No verification claim, no owner.2. Hand-read for the RULE, not the symbols. This is the bot's declared permanent blind spot: a page stating a rule by its inputs shares no identifier with the emitter. The rule this change carries is unpack-time re-verification is owned by the future runtime loader (ADR-0025 §3.5 steps 4–7), not the cloud control plane, so
content/was searched for the rule's own vocabulary in short, wrap-immune tokens — never the full sentence, which is the trap that nearly cost a site in the source tree:content/unpackre-verification/re-verifymanifest.integrityverifyIntegrityintegrity.describe()tables, or archive-content descriptionscontrol planeThe 8-file intersection carries no instance of the defect:
#sha256=artifact-pinned boot (publish-and-preview,self-hosting,cli) and the canonical-metadatachecksum(north-star,environment-artifact) are different mechanisms; the rest are unrelated. Release notes were read but are never editable here.Result: no sixth site. Repo-wide, the three other places that state this rule already carry the corrected attribution —
packages/spec/liveness/manifest.json("owned by the future runtime loader … NOT by the cloud control plane"),docs/qa/platform-checklist/areas/cli.json("nothing re-verifies it at unpack — #11331 is open on exactly that", no owner claimed), and the pending.changeset/manifest-integrity-unpack-tsdoc-truth.md, which states the old wording only as the history it is correcting.ADR-0025, the authority all of them cite, contains zero occurrences of "control plane".Nothing was changed in
content/by this PR, and nothing needed to be.验收备注
git grep -n '11331' -- packages/cli packages/core→ 7 lines: the 5 source sites, all now reading "future runtime loader (ADR-0025 §3.5 steps 4–7)" with the#11331pointer kept, plus the 2 CHANGELOG lines left alone. Output pasted above. Cross-checked with the wrap-immunefuture runtime loaderanchor → 5 source lines. Zero hits remain forcontrol plane's obligationorowes the unpack-timeunderpackages/cli/srcandpackages/core/src.os plugin publishpreflight」 is kept verbatim at every site; every removed line in the diff is an attribution clause. The diff is comment prose only — no accept set, export, signature or runtime behaviour moves.@objectstack/core1197 tests,@objectstack/cli2855 tests across both tiers; both typechecks exit 0.content/docs/releases/untouched. The complete changed-file list is the 4 source files plus one.changeset/*.md— no releases page, noCHANGELOG.md, nothing outside the surface declared in the claim comment.Out-of-scope findings
noted, not filed:the@objectstack/coredocblock does not reach the package's published.d.ts(detailed under Changeset above). 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. Carrier: whoever next revisits the ADR-0025 integrity chain — no PR is queued that would touch it.Nothing else was found. No new fork appeared, so this did not go to the decision box: the owner was already ruled.
Generated by Claude Code