Repository navigation
fix(registry): actually read the plugin pins and fail on unreachable or unhashed pins - #124
Merged
Merged
Conversation
Honour a non-shipping exemption only when the entry has no submodule or recorded gitlink; an exempt name that still ships is now a hard error instead of skipping reachability and manifest verification. Require a sha256 manifest_hash for every shipping official pin. Bound both manifest sources to 256 KiB: the raw fetch uses the existing Content-Length/streaming cap, and local git objects are size-checked with cat-file before git show. Oversized manifests are errors. Wrap local git spawns in try/catch so a missing checkout or git binary returns the local fallback path instead of throwing; readPinnedManifest keeps local failures out of the network-error classification. Add regression tests for the exemption conflict, oversized local and raw manifests, spawn failures, local-first/raw fallback, and --skip-network pin planning.
Enforce the official `sha256:<64 lowercase hex>` manifest_hash shape in planPinChecks, so --skip-network rejects a wrong algorithm or digest length instead of deferring it to the online phase. Tighten the shared integrity pattern and schema to the same notation. Update the canonical integrity claims: official shipping pins require and verify the digest at the pin, while community entries may omit it and signatures stay advisory. Refresh the 11 official entry headers and the README/schema descriptions accordingly. Keep the oversized-manifest error authoritative when Response.cancel() or ReadableStreamDefaultReader.cancel() rejects, and derive the --skip-network pin count in the regression test instead of hardcoding 11.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The pin-reachability check was a no-op:
readSubmodulePins()rangit ls-tree HEAD plugins, which returns the tree entry (040000 tree ... plugins), not the 11 gitlinks. Every official entry logged "no recorded pin; skipping reachability", sojust registry-validateexited 0 even if a plugin was pinned to an unreachable commit or the manifest at the pin did not match the registry hash.Proof:
Fix
readSubmodulePins()readsgit ls-tree HEAD plugins/and is exported/testable.planPinChecks():manifest_hashis an error;sha256:<64 lowercase hex>digest is an error in both modes, including--skip-network;NON_SHIPPING_PIN_EXEMPTIONSentry is a notice with its reason, but only when the entry has no submodule and no recorded gitlink; an exempt name that still ships is an error;checkManifestHashes()verifiessha256:<64 hex>against the manifest at the pin (local object first, pinnedraw.githubusercontent.comfallback); a mismatch or 404 is an error.Content-Lengthpre-check plus a streaming cap, and the local git object is size-checked withcat-file -sbeforegit show. An oversized manifest is an error, and a rejectingcancel()cannot mask that error.readPinnedManifest()keeps local failures out of the "network unavailable" classification.git ls-treefailure now fails closed.--skip-networkstill enforces pin presence, exemptions, and thesha256:<64 hex>shape; only the network phases are skipped.checkSubmoduleConsistency()honors the same exemptions, so the two gates cannot contradict each other.manifest_hash; signatures remain optional and advisory.registry/schema.json, the README, and all 11registry/official/*.tomlheaders were updated, and the schema regex is^sha256:[0-9a-f]{64}$.Before / after
Tests
tests/registry.test.ts: 11-gitlink fixture, missing-pin failure for a shipping plugin, unreachable (diverged) pin failure, exemption with/without reason and exemption-vs-shipping conflict, missing/non-sha256manifest_hashoffline, manifest hash match/mismatch/missing, oversized local and raw manifests, rejecting streamcancel(), local git spawn failures, local-first/raw fallback, and--skip-networkpin planning with a derived count.186 pass,0 failacross both suites (142registry tests);tscexit 0.just checkpasses in the worktree (fmt, lint, type-check, tests, validator, index freshness, app build). Validator result:0 error(s), 11 reachability checks and 11 manifest bindings planned. Remaining warnings are the 11 signature advisories plus environmental skips: the audit worktree has no submodules checked out, and the unauthenticated GitHub compare API returns 403 once its hourly quota is exhausted.