This repository was archived by the owner on Jul 18, 2026. It is now read-only.
Fix published index: restore signatures on retained connector versions, gate unsigned publishes - #95
Merged
Conversation
…s, gate unsigned publishes The 2026-07-13 05:13Z publish (first success since Jun 11) shipped a connector-index.json where 10 retained (superseded) connector versions carry no artifactSignature. The installer hard-fails on missing Sigstore metadata, so every consumer install broke — all unity-surfaces Vercel deploys and fresh `pnpm install`s die on `chatgpt-playwright@2.0.0 is missing Sigstore bundle metadata`. Mechanism: signatures are attached at publish time, and only along two paths — rebuilt current versions, and retained versions of a connector being bumped in that same publish (materializeRetainedArtifact). When a connector is NOT bumped, its retained versions are carried verbatim from the committed index, which never stores signatures. The Jun 25/29 publishes (which would have materialized the retained entries at bump time) failed on a real checksum drift: retained tarballs are not byte-reproducible, so the raw.githubusercontent copies no longer match the recorded artifactSha256 (github-playwright@1.2.0: committed sha, raw bytes, and signed release bytes are three different values). Only the last published release assets are both signed and self-consistent. Fix: - connector-index.json: point the 9 restorable retained entries back at the connectors-3f944c668395 release (artifactUrl, artifactSha256, releaseId, sourceCommit/sourceTag, artifactSignature) — those assets are live and their sha256s verify. Drop github-playwright@1.4.0: it was added while publishing was broken, never appeared in a successful release, and no bundle exists anywhere for it (same precedent as #87). - generate-connector-index.mjs: run retained versions through materializeRetainedArtifact on the preserved-current-version path too, so retention handling is symmetric with the bump path (no-op in local mode; inert for entries that already carry release URLs + signatures). - generate-connector-index.mjs + connector-artifact-contract.mjs: refuse to emit an index with unsigned entries when sigstore metadata is enabled (assertConnectorIndexSigned). A future regression fails the publish loudly instead of shipping a broken index. Verification: - node --test contract tests: 18/18 (2 new for the signature gate). - Local regen is byte-stable; `--check` and the full contract-guardrails battery pass. - Publish simulation (CONNECTOR_USE_RELEASE_ASSETS=1 + CONNECTOR_ENABLE_SIGSTORE_METADATA=1): 26/26 entries signed; all 52 artifact+bundle URLs return 200. - End-to-end: unity-surfaces' installer-core flow (generateLock + installFromLock) against the simulated published index resolves, downloads, and Sigstore-verifies all 13 pinned connectors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Schema Health Check — Non-blocking inherited issues44/50 scopes consistent | 6 inherited Gateway gap(s) | no new blocking issues in this PR |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Problem
The 2026-07-13 05:13Z publish (first success since Jun 11, revived by #93) shipped a
connector-index.jsonwhere 10 retained (superseded) connector versions have noartifactSignature. The installer hard-fails on missing Sigstore metadata, so every consumer install is broken: all unity-surfaces Vercel deploys and any freshpnpm installdie on(unity-surfaces pins 5 of the 10 affected versions; GH Actions only stay green because they set
SKIP_CONNECTOR_FETCH=1.)Root cause
Signatures are attached at publish time, and only along two paths: rebuilt current versions, and retained versions of a connector being bumped in that same publish (
materializeRetainedArtifact). When a connector is not bumped, its retained versions are carried verbatim from the committed index — which never stores signatures. Today's publish took that path for all 10.The bump-time materialization also hides a second landmine (very likely why the Jun 25/29 publish runs failed): retained tarballs aren't byte-reproducible, so the
raw.githubusercontentcopies no longer match the recordedartifactSha256. Forgithub-playwright@1.2.0the committed sha, the pinned raw bytes, and the signed June release bytes are three different values. Only the last published release assets are both signed and self-consistent.Fix
connector-index.json— point the 9 restorable retained entries back at theconnectors-3f944c668395release (artifactUrl,artifactSha256,releaseId,sourceCommit/sourceTag,artifactSignature); all those assets are live (HTTP 200) and their sha256s verify. Dropgithub-playwright@1.4.0: added while publishing was broken, never in any successful release, no signature bundle exists anywhere for it (same precedent as Fix publish: drop retained claude-export 1.0.0 #87's drop of retained claude-export 1.0.0). Nothing pins it.generate-connector-index.mjs— run retained versions throughmaterializeRetainedArtifacton the preserved-current-version path too, making retention handling symmetric with the bump path (no-op in local/commit mode; inert for entries that already carry release URLs + signatures).assertConnectorIndexSigned(inconnector-artifact-contract.mjs, called from the generator whenCONNECTOR_ENABLE_SIGSTORE_METADATA=1): refuse to emit an index with unsigned entries. A future regression fails the publish loudly instead of shipping a broken index to every consumer.Verification
node --testcontract tests: 18/18 (2 new for the signature gate)--check+ the full contract-guardrails battery pass locallyCONNECTOR_USE_RELEASE_ASSETS=1+CONNECTOR_ENABLE_SIGSTORE_METADATA=1): 26/26 entries signed, all 52 artifact+bundle URLs return 200loadConnectorIndex→generateLock→installFromLock) against the simulated published index resolves, downloads, and Sigstore-verifies all 13 pinned connectorsNotes / follow-ups
releaseIdcomes out asgithub-<full-sha>(workflow setsrelease_id=github-${GITHUB_SHA}) while everything else usesconnectors-<sha12>— intentional? Left untouched here.🤖 Generated with Claude Code