Skip to content

feat(labeler): verified artifact acquisition (W7.2)#2069

Merged
ascorbic merged 3 commits into
feat/plugin-registry-labelling-servicefrom
feat/labeler-artifact-acquisition
Jul 16, 2026
Merged

feat(labeler): verified artifact acquisition (W7.2)#2069
ascorbic merged 3 commits into
feat/plugin-registry-labelling-servicefrom
feat/labeler-artifact-acquisition

Conversation

@ascorbic

@ascorbic ascorbic commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Implements verified artifact acquisition (plan W7.2, spec §9.3/§9.4) for the labeler pipeline. Given a verified release, it resolves the package artifact from the preferred source, fetches it under @emdash-cms/registry-verification's SSRF-hardened controls, verifies the bytes against the signed checksum, and unpacks the canonical bundle into the code-analysis file set.

The module composes the W7.1 verification package rather than reimplementing any of it — guarded fetch, multihash verification, and bundle validation are the shared foundation. It adds the labeler-specific layer on top: mirror-first source preference, declared-URL fallback, and classification of every failure into the four ratified acquisition categories.

The classification is the security-load-bearing part. It enforces the §9.4 discipline that a transport or capability fault on unverified bytes must never become a public block label:

  • Network/origin failures, timeouts, a transport size cap tripped mid-fetch (before any checksum), URL-safety/redirect refusals, and a malformed/unsupported declared checksum → retry → assessment-error. No public label.
  • Only genuine integrity faults on verified/authoritative inputs (CHECKSUM_MISMATCH, coordinate drift) and content-policy bundle rejections (decompression bomb, structurally-invalid archive, non-UTF-8 code file) become deterministic blocking findings.

Non-UTF-8 code files are rejected as invalid-bundle rather than silently dropped, so the set the AI analyzes stays a superset of the set that actually executes (a lenient runtime would still run a file the strict decoder discards).

Mirror-ready seam: v1 ships no mirror binding, so the mirror source always misses and every acquisition resolves via the publisher's declared URL. Injecting a future aggregator mirror binding activates mirror-first ordering with no contract change.

Also extends validatePluginBundle with a validated file inventory (files) so consumers extract analysis inputs without re-parsing the bundle.

Part of the plugin-registry labelling service (RFC #694, umbrella #1909). Targets the integration branch.

Type of change

Covered by the approved RFC #694 umbrella.

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes (zero diagnostics in changed files; pre-existing baseline unchanged)
  • pnpm test passes (labeler workerd 596, registry-verification node 94)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable) — n/a, no admin UI in this PR
  • I have added a changesetregistry-verification minor for the files inventory; the labeler app is unpublished
  • New features link to an approved Discussion — RFC RFC: Decentralized Plugin Registry #694

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 4.8 (implementation and adversarial review)

Screenshots / test output

Classification table validated against every VerificationErrorCode the composed package can emit; +20 acquisition tests (18 acquisition, 2 orchestrator) plus the pre-existing suites. An Opus adversarial pass caught three misclassifications (two of which produced public block labels on unverified/capability faults, one enshrined in a passing test) before this PR; all fixed and covered by new tests.


Try this PR

Open a fresh playground →

A full working EmDash site, deployed from this branch. Each visit gets its own session-scoped sandbox: no login needed and no shared state. Try the admin, edit content, hit the public site.

Tracks feat/labeler-artifact-acquisition. Updated automatically when the playground redeploys.

Resolves a verified release's package artifact from the preferred source,
fetches it under the shared SSRF-hardened controls, verifies the bytes against
the signed checksum, and unpacks the canonical bundle into the analysis file
set. Composes @emdash-cms/registry-verification (guarded fetch, multihash
verification, bundle validation) and adds the labeler's mirror-first source
preference, declared-URL fallback, and acquisition-category classification.

Every failure is classified so that transport and capability faults on
unverified bytes retry into assessment-error and never a public label, while
only checksum/coordinate integrity faults and content-policy bundle rejections
become deterministic blocking findings (spec §9.4). Non-UTF-8 code files are
rejected rather than silently dropped, keeping the analyzed set a superset of
the executable set. Mirror-ready seam: v1 ships no mirror binding, so every
acquisition resolves via the publisher's declared URL.

Extends validatePluginBundle with a validated file inventory (files) so
consumers extract analysis inputs without re-parsing the bundle.
@github-actions github-actions Bot added the review/needs-review No maintainer or bot review yet label Jul 16, 2026
@changeset-bot

changeset-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3811016

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@emdash-cms/registry-verification Minor
@emdash-cms/labeler Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 1,115 lines across 10 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-playground 3811016 Jul 16 2026, 08:55 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-do 3811016 Jul 16 2026, 08:55 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-cache 3811016 Jul 16 2026, 08:55 AM

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the right change for W7.2: it builds the labeler’s artifact-acquisition stage on top of the existing @emdash-cms/registry-verification package rather than reimplementing fetch/checksum/validation, adds a clean mirror-first seam for W0.6, and keeps the §9.4 security invariant that transport/capability faults on unverified bytes must not become public block labels. The failure-classification taxonomy, the mirror CHECKSUM_MISMATCH fallback, and the orchestrator adapter all line up, and the bundle inventory extension to validatePluginBundle is additive with a proper minor changeset.

I checked the acquisition code against the VerificationErrorCode set, traced the orchestrator integration (including how StageTransientError is thrown for retryable failures and how permanent findings map onto the policy resolver), and verified the bundle changes and AGENTS.md conventions: the changeset is present and well-worded, no admin UI/i18n/SQL changes were introduced, and the dependency additions are scoped to the labeler app and registry-verification. Test coverage looks comprehensive.

The only clear issue is a misleading docstring that says an oversized artifact is "classified as an invalid bundle," while the actual code (and the PR’s stated §9.4 intent) classifies it as retryable/transient. There is also minor comment imprecision around whether the mirror key is content-addressed. The unrelated pnpm-lock.yaml snapshot churn is noted but not flagged as a defect since I cannot verify whether it was intentional deduplication from adding modern-tar/registry-verification to the workspace.

Comment on lines +56 to +60
* Fetch budgets for a declared-URL artifact download. The byte budget equals
* the compressed-bundle cap, so an artifact larger than any valid bundle is
* rejected during streaming (the earliest point) and classified as an invalid
* bundle. Timeouts bound a slow or stalled origin.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[needs fixing] The docstring for the declared-URL fetch limits says an artifact that hits maxBytes is "classified as an invalid bundle." That contradicts both the implementation and spec §9.4: RESOURCE_SIZE_EXCEEDED from fetchVerifiedResource is in TRANSIENT_CODES, so the orchestrator retries and finalizes it as assessment-error — it never becomes a public block label. A misleading security-level comment is a real risk because a future maintainer could rely on it.

Suggested change
* Fetch budgets for a declared-URL artifact download. The byte budget equals
* the compressed-bundle cap, so an artifact larger than any valid bundle is
* rejected during streaming (the earliest point) and classified as an invalid
* bundle. Timeouts bound a slow or stalled origin.
*/
/**
* Fetch budgets for a declared-URL artifact download. The byte budget equals
* the compressed-bundle cap, so an artifact larger than any valid bundle is
* rejected during streaming (the earliest point) and classified as a transient
* failure (retry assessment-error), never as a public block label per
* spec §9.4. Timeouts bound a slow or stalled origin.
*/

Comment on lines +161 to +166
/**
* Deterministic mirror object key derived from release coordinates. The mirror
* is a content-addressed copy of the exact signed artifact, so the key is
* stable across acquisitions and independent of the declared URL.
*/
export function mirrorObjectKey(target: AcquisitionTarget): string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] The comment calls the mirror "a content-addressed copy" but the key below is derived from release coordinates (slug/version/artifactId), not from the artifact’s checksum. This is harmless today but confusing: if a future mirror actually uses content-addressing, the comment will be wrong; if it stays coordinate-based, the comment should say so.

Suggested change
/**
* Deterministic mirror object key derived from release coordinates. The mirror
* is a content-addressed copy of the exact signed artifact, so the key is
* stable across acquisitions and independent of the declared URL.
*/
export function mirrorObjectKey(target: AcquisitionTarget): string {
/**
* Deterministic mirror object key derived from release coordinates. The mirror
* stores the exact signed artifact, so the key is stable across acquisitions
* and independent of the declared URL.
*/

@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-review No maintainer or bot review yet labels Jul 16, 2026
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Jul 16, 2026
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Jul 16, 2026

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This remains the right shape for W7.2: it composes @emdash-cms/registry-verification instead of reimplementing fetch/checksum/validation, adds a clean mirror-first seam, and keeps the §9.4 invariant that transport/capability faults on unverified bytes do not become public block labels. The bundle inventory extension is additive with a proper minor changeset, and the orchestrator integration tests cover the happy path, integrity-failure, and transient-exhaustion flows.

The previous review's two findings are both addressed: the oversized-artifact comment now correctly calls the pre-checksum abort transient, and the mirrorObjectKey comment no longer implies content-addressing.

One new inaccuracy remains: the crossCheckCoordinates docstring claims a malformed declared checksum is a "permanent integrity fault," but the code maps the decodeMultihash failure (INVALID_MULTIHASH / UNSUPPORTED_MULTIHASH) to TRANSIENT_CODES, the PR description says malformed/unsupported declared checksums are retryable assessment-error, and artifact-acquisition.test.ts has a passing test that asserts exactly that transient classification. The implementation is correct and safe; the comment is the only thing out of sync.

AGENTS.md conventions otherwise check out: the changeset is present and user-facing, there are no admin UI / i18n / RTL / SQL / API-route changes, dependency additions are scoped, and the new files inventory export is additive. Test coverage is comprehensive.

Comment on lines +213 to +215
/** Cross-checks the pinned coordinates and the declared checksum before any
* network work: a drift between what discovery pinned and what the release
* declares, or a malformed declared checksum, is a permanent integrity fault. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] This docstring is still misleading in the same way the prior review flagged: it says a malformed declared checksum is a "permanent integrity fault," but the implementation passes decodeMultihash errors to classifyFailure, where INVALID_MULTIHASH/UNSUPPORTED_MULTIHASH live in TRANSIENT_CODES and map to kind: "transient" / assessment-error. The PR description and the test "treats a malformed declared checksum as transient, never a public block" both agree the classification is transient, so the comment contradicts the code.

Suggested change
/** Cross-checks the pinned coordinates and the declared checksum before any
* network work: a drift between what discovery pinned and what the release
* declares, or a malformed declared checksum, is a permanent integrity fault. */
/** Cross-checks the pinned coordinates and the declared checksum before any
* network work: a drift between what discovery pinned and what the release
* declares is a permanent integrity fault. A malformed or unsupported declared
* checksum is a transient record/capability fault (spec §9.4), not tampering,
* and is classified via the decode error. */

@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Jul 16, 2026
@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-rereview Author pushed changes since the last review labels Jul 16, 2026
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Jul 16, 2026
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Jul 16, 2026

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the right shape for W7.2: it composes @emdash-cms/registry-verification for fetch/checksum/bundle validation, adds a clean mirror-first seam, and keeps the §9.4 invariant that transport/capability faults on unverified bytes do not become public block labels.

The only outstanding issue from the previous review — the crossCheckCoordinates docstring incorrectly characterizing a malformed declared checksum as a permanent integrity fault — is now fixed. The comment distinguishes coordinate drift (permanent COORDINATE_MISMATCH) from malformed/unsupported declared checksums (decodeMultihashINVALID_MULTIHASH/UNSUPPORTED_MULTIHASH, mapped to TRANSIENT_CODES and retried as assessment-error), which matches both the implementation and the passing tests.

I re-checked every changed hunk and traced the new code against the composed verification package:

  • Classification is sound: MIRROR_MISS/TRANSIENT_CODES/URL_POLICY_CODES all retry; INTEGRITY_CODES produce artifact-integrity-failure; everything else from verified bytes maps to invalid-bundle.
  • buildCodeFileSet correctly rejects non-UTF-8 files with code extensions as NON_UTF8_CODE_FILE / invalid-bundle, so a lenient runtime cannot execute something the code AI never sees.
  • SSRF hardening remains delegated to fetchVerifiedResource (HTTPS-only, IP-literal/private-host rejection, redirect validation).
  • Mirror CHECKSUM_MISMATCH falls through to the authoritative declared URL; mirror binding errors are treated as misses, never authoritative failures.
  • The bundle inventory addition in registry-verification is additive, has a minor changeset, and is exported through the public barrel.
  • Tests cover happy path, integrity mismatch, transport/policy failures, mirror fallback, non-UTF-8 executable rejection, and orchestrator integration.

No AGENTS.md conventions are violated: the changeset is present and user-facing, there are no admin UI/i18n/RTL/SQL/API-route changes, dependency additions are scoped, and there are no drive-by refactors.

Approving.

@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Jul 16, 2026
@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-rereview Author pushed changes since the last review labels Jul 16, 2026
@ascorbic
ascorbic merged commit 7c28520 into feat/plugin-registry-labelling-service Jul 16, 2026
11 checks passed
@ascorbic
ascorbic deleted the feat/labeler-artifact-acquisition branch July 16, 2026 09:59
@ascorbic ascorbic mentioned this pull request Jul 16, 2026
81 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: signed review/approved Approved; no new commits since size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant