Skip to content

Latest commit

 

History

History
154 lines (125 loc) · 8.51 KB

distribution.md

File metadata and controls

154 lines (125 loc) · 8.51 KB

Distribution Plan

These items require release infrastructure, registry credentials, domains, or GitHub repository settings. They are tracked here so the project has a clear path beyond source installs.

Package Channels

Line Carries Install Promises Cadence
Advisory diff, check, audit --host, drift, advisory PR comments a v* release declared advisory — v1.2.0 is one, on PyPI — or an unqualified preview pre-release plain-language capability rows; no blocking authority unless an adopter configures a blocking policy 14 days
Qualified gate blocking verdicts backed by qualification evidence, receipts, attestations a v* release on the qualified line every bar in release-evidence-policy-decision.md on evidence only

A v* tag's shape does not say which line it is on. Each release version is declared once, in .github/release-channels.json, as advisory or qualified (Amendment 5 of the policy decision); a tag whose own tree has no declaration predates advisory v* releases and is on the qualified line.

The two cadences are measured separately by scripts/release_cadence.py, which reads each v* tag's declared channel: qualified tags count for the gate line, and advisory v* releases and preview-* pre-releases for the advisory line. Counting advisory releases in the gate metric would let the channel that exists because the release cadence slipped report that cadence as kept.

For previews, the offline script uses the UTC build date stamped into the version, and labels it as a build-date proxy. Lightweight Git tags expose the source commit time, not publication time; GitHub publication records are still needed to prove the shipping cadence.

  • agents-shipgate is published on PyPI.
  • Pinned GitHub Action release tags are published, including v1.2.0.
  • A qualified v* GitHub Release attaches the independently qualified wheel, SBOM, safety-qualification.json, and their Sigstore bundles.
  • An advisory v* GitHub Release attaches the wheel, a wheel-scoped SBOM, provenance.json, candidate-manifest.json and a signed advisory-statement.json, with Sigstore bundles for the wheel, SBOM and statement, and no qualification artifact. v1.0.0, v1.1.0 and v1.2.0 are published this way; each statement records advisory defaults, blocking opt-in and no qualification claim.
  • The tag workflow does not rebuild or publish an unqualified sdist.
  • Unqualified previews are published as GitHub pre-releases at preview-<version>, carrying one wheel and no qualification artifact. They exist so merged work is installable while a tag is blocked, and they reach no index: the version carries a PEP 440 local segment, which a public index must refuse. See release-runbook.md § The unqualified preview channel, and the admissibility finding in release-evidence-policy-decision.md § Amendment 2.
  • Evaluate a container image later only if it has an exercised build-and-test path.
  • Evaluate Homebrew once CLI usage warrants it.

The GitHub Action installs from its tagged source by default. A shipgate_version input is available for release flows that intentionally need to install a published PyPI version.

Supply Chain

  • Generate a wheel-scoped SBOM from an isolated runtime-only install of the published wheel, bound to its SHA-256.
  • Sign release artifacts with Sigstore.
  • Publish to PyPI through Trusted Publishing from .github/workflows/release.yml.
  • Keep GitHub Actions pinned by SHA.
  • Pin the build backend in constraints/release-build.txt so release wheels are byte-reproducible.
  • Use Dependabot for Python and GitHub Actions updates.
  • Use the existing hash-locked development, build, sealing and publication closures listed in the release runbook.

PyPI Trusted Publishing is configured for this repository's tag-triggered release workflow and protected pypi environment.

The operational procedure — mandatory rehearsal, the two-job publication transaction, and the recovery path when PyPI succeeds but release finalization fails — is in release-runbook.md.

Protected qualification inputs

Qualification configuration is split by trust level. The values that authenticate the evidence — the Sigstore signer identity and OIDC issuer — live in reviewed code at .github/release-trust-roots.json, never in variables: an actor able to set variables could otherwise substitute fabricated qualification evidence and replace the identity that vouches for it, in one step with no diff to review.

Only the content-addressed locations are variables, at repository scope so the unattended verification job can read them. Values must be populated by the independent benchmark-owner promotion flow after it runs the frozen corpus against the exact wheel and signs safety-qualification.json:

Variable Required value
SAFETY_QUALIFICATION_WHEEL_URL HTTPS URL for the exact qualified wheel
SAFETY_QUALIFICATION_WHEEL_FILENAME Safe wheel basename, for example agents_shipgate-0.16.0b6-py3-none-any.whl
SAFETY_QUALIFICATION_JSON_URL HTTPS URL for the qualified JSON artifact
SAFETY_QUALIFICATION_SIGSTORE_BUNDLE_URL HTTPS URL for that JSON artifact's Sigstore bundle

The verification job checks the signature identity first, then validates the artifact against the policy the tag's version requires — the 80-case beta policy, or, for a 0.x tag, the 38-case pre_1_0 policy approved in release-evidence-policy-decision.md — together with the tag/version and wheel SHA-256. Which policy governs is derived from the version, never read from the artifact, and a 0.x tag may also publish on the stronger beta artifact.

It then rebuilds a wheel from the tagged checkout and requires byte equality with the qualified wheel, which is the binding that ties the published artifact to the tagged commit. The rebuilt wheel is only ever a comparison reference: the artifact published to PyPI remains the exact qualified wheel.

Missing variables, non-HTTPS URLs, an unsafe filename, an invalid signature, a result whose tier the tag's version does not admit, or any binding mismatch stops before PyPI publication.

Because a tampered wheel URL now fails the source-binding gate rather than reaching PyPI, variable ACLs are no longer the primary control over what gets published. The required-reviewer gate on the pypi environment protects the publication step itself.

This is a configured trust root, not proof of organizational independence. The promotion job trusts the signed qualification summary and does not replay its underlying verifier receipts. The four-week, three-design-partner rollout is likewise an external beta stop condition; the machine gate enforces only the qualification artifact's combined origin minimum — 32 real-history, rejected/reverted, or design-partner cases under the production policy and 16 under the pre-1.0 one, the same 40% share of each corpus. The current policy table keeps these machine floors separate from external rollout and pilot evidence.

Marketplace And Site

  • ThreeMoonsLab/agents-shipgate is listed on GitHub Marketplace.
  • Create a small landing page with install instructions, trust model, and findings gallery.
  • Consider a local-only playground later; do not accept private customer manifests into a hosted service without a separate privacy review.

Release Fan-Out Checklist

The tag-triggered release workflow publishes PyPI artifacts and creates the GitHub release. After each release tag, verify the external surfaces that live outside this repository:

  • PyPI shows the new package version.
  • GitHub Marketplace shows the new release tag as Latest.
  • The website header, footer, /llms.txt, and /.well-known/agents-shipgate.json show the new version.
  • Website discovery metadata points at the current report schema and GitHub Action pin.
  • /sitemap.xml resolves to the current sitemap or redirects to /sitemap-index.xml.

Marketplace Repository Notes

The repository keeps a root action.yml for GitHub Marketplace publication and a minimal .github/workflows/ci.yml for project validation plus a tag-triggered release workflow. The action remains a composite action; there is no Docker action entrypoint in the current release.