diff --git a/.changeset/unpack-reverification-owner-runtime-loader.md b/.changeset/unpack-reverification-owner-runtime-loader.md new file mode 100644 index 0000000000..6500bbb7e9 --- /dev/null +++ b/.changeset/unpack-reverification-owner-runtime-loader.md @@ -0,0 +1,17 @@ +--- +"@objectstack/cli": patch +"@objectstack/core": patch +--- + +Five source comments in `@objectstack/cli` and `@objectstack/core` stop attributing unpack-time `manifest.integrity` re-verification to the cloud control plane and name the owner this repo has already ruled: the **future runtime loader** (ADR-0025 §3.5 steps 4–7). The enforce leg stays tracked on #11331. + +`packages/spec`'s `manifest.zod.ts` was corrected to that owner in an earlier change, and these five sites were left behind — so the repo stated both things at once. A comment that names the wrong owner costs nobody a build, but it teaches a reader (and a reading AI) to expect a verification that no component performs and that ADR-0025's own status line records as unimplemented. + +- `packages/cli/src/utils/osplugin.ts` — the `.osplugin` packaging docblock, and the `sriDigest` TSDoc. +- `packages/cli/src/commands/plugin/publish.ts` — the integrity-preflight comment. +- `packages/core/src/security/index.ts` — the `verifyIntegrity` export comment. +- `packages/core/src/security/plugin-artifact-integrity.ts` — the verifier's own module docblock, which 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 does NOT change.** The other half of every one of these comments — the digest map is computed by `os plugin build` and self-checked by the `os plugin publish` preflight — is true and is kept verbatim. No accept set, export, signature or runtime behaviour moves; the diff is comment prose only. + +**What moves for consumers, measured on the built output.** `@objectstack/cli` ships `dist/`, and the `sriDigest` TSDoc rides into `dist/utils/osplugin.d.ts`, so an editor's hover on `sriDigest` stops naming the control plane. `@objectstack/core`'s two sites do **not** reach its published bundle — a module docblock and a line comment above an `export {}` are both dropped from `dist/index.d.ts` — so nothing in that package's shipped bytes moves. It is declared here anyway because the pre-correction attribution is quoted in `packages/core/CHANGELOG.md`, a generated record that may not be hand-edited; a changeset naming the package is the only way the correction reaches that published record. diff --git a/packages/cli/src/commands/plugin/publish.ts b/packages/cli/src/commands/plugin/publish.ts index 6d353c0133..edfef0169b 100644 --- a/packages/cli/src/commands/plugin/publish.ts +++ b/packages/cli/src/commands/plugin/publish.ts @@ -113,8 +113,9 @@ export default class PluginPublish extends Command { // bytes against the manifest's own declared per-file digests before // upload. Absent map = permissive by contract (the field is // `.optional()`; artifacts built before integrity computation stay - // publishable). Unpack-time re-verification remains the cloud control - // plane's obligation (#11331) — this preflight does not discharge it. + // publishable). Unpack-time re-verification is owned by the + // future runtime loader (ADR-0025 §3.5 steps 4–7), not by the cloud + // control plane (#11331) — this preflight does not discharge it. const declaredIntegrity = manifest.integrity; if ( declaredIntegrity !== undefined && declaredIntegrity !== null diff --git a/packages/cli/src/utils/osplugin.ts b/packages/cli/src/utils/osplugin.ts index 7e7ab77413..d988177d8a 100644 --- a/packages/cli/src/utils/osplugin.ts +++ b/packages/cli/src/utils/osplugin.ts @@ -16,9 +16,10 @@ * The control plane (cloud) stores this blob opaquely. The per-file * `integrity` map is computed here at build time and self-checked by the * `os plugin publish` preflight; re-verification at install/load-time - * unpack (ADR §3.5 step 5) is the cloud control plane's obligation and is - * not implemented in this repo (#11331). This module owns the two - * contracts the runtime and cloud must agree on byte-for-byte: + * unpack is not implemented in this repo and is owned by the + * future runtime loader (ADR-0025 §3.5 steps 4–7), not by the cloud + * control plane (#11331). This module owns the two contracts the + * runtime and cloud must agree on byte-for-byte: * * 1. The integrity digest STRING FORMAT — Subresource-Integrity style * `sha256-` (matches ADR-0025 §3.2's example). See @@ -43,8 +44,9 @@ export interface ArchiveFile { * Subresource-Integrity-style digest of `bytes`: `sha256-`. * This is the canonical per-file integrity string written into the * compiled manifest's `integrity` map and checked back at the - * `os plugin publish` preflight (unpack-time re-verification is the - * cloud control plane's obligation, #11331). + * `os plugin publish` preflight (unpack-time re-verification is owned + * by the future runtime loader — ADR-0025 §3.5 steps 4–7 — not by the + * cloud control plane, #11331). */ export function sriDigest(bytes: Uint8Array): string { return 'sha256-' + createHash('sha256').update(bytes).digest('base64'); diff --git a/packages/core/src/security/index.ts b/packages/core/src/security/index.ts index d8691e426f..f0258c3ac0 100644 --- a/packages/core/src/security/index.ts +++ b/packages/core/src/security/index.ts @@ -36,8 +36,9 @@ export { // Per-file artifact integrity verification (ADR-0025 §3.2) — pure and // portable like the signature contract above; consumed by the -// `os plugin publish` preflight. Unpack-time re-verification stays the -// cloud control plane's obligation (#11331). +// `os plugin publish` preflight. Unpack-time re-verification is owned by +// the future runtime loader (ADR-0025 §3.5 steps 4–7), not by the cloud +// control plane (#11331). export { verifyIntegrity, formatIntegrityViolation, diff --git a/packages/core/src/security/plugin-artifact-integrity.ts b/packages/core/src/security/plugin-artifact-integrity.ts index 329b3c123f..a3989a4013 100644 --- a/packages/core/src/security/plugin-artifact-integrity.ts +++ b/packages/core/src/security/plugin-artifact-integrity.ts @@ -7,11 +7,12 @@ * `integrity` map (artifact-relative path → SRI-style `sha256-` * digest, the format `os plugin build` writes). Like its sibling * `plugin-artifact-signature.ts`, this module is pure and dependency-free - * (node:crypto only) so it stays byte-for-byte portable to the cloud - * control plane, which owes the unpack-time re-verification leg - * (ADR-0025 §3.5 step 5 — tracked on #11331, NOT discharged by this - * module). The framework caller is the `os plugin publish` preflight: the - * publisher self-checks its own artifact before upload. + * (node:crypto only) so it stays byte-for-byte portable to whatever runs + * the unpack-time re-verification leg — the future runtime loader + * (ADR-0025 §3.5 steps 4–7), not the cloud control plane (tracked on + * #11331, NOT discharged by this module). The framework caller is the + * `os plugin publish` preflight: the publisher self-checks its own + * artifact before upload. * * Verdict semantics: * - absent map (`undefined` / `null`) → ok, `skipped: true` — the field