Skip to content

feat: Phase 15 cont. — supply chain + tap/scoop auto-update + install docs + smoke matrix (5 tasks, 18 SP)#4

Merged
alfredrc merged 10 commits into
developfrom
milestone/phase-15
May 12, 2026
Merged

feat: Phase 15 cont. — supply chain + tap/scoop auto-update + install docs + smoke matrix (5 tasks, 18 SP)#4
alfredrc merged 10 commits into
developfrom
milestone/phase-15

Conversation

@alfredrc
Copy link
Copy Markdown
Member

🎯 Summary

Continuation of Phase 15 (CLI distribution) for the beeping-cli scope. This PR rolls up 5 task closures (18 SP) layered on top of the earlier Phase 15 squash (077b50d). Together the two PRs close 16 of the 17 beeping-cli-specific Phase 15 tasks (62 / 67 SP, 93 %).

Task SP What
BEE-1781 5 cosign keyless + CycloneDX SBOM + SLSA L3 provenance per artifact (verified e2e on test tag)
BEE-1785 2 Install docs polish + README install section + per-OS Gatekeeper/SmartScreen/ALSA workarounds
BEE-1782 3 Homebrew tap auto-update on release via cross-repo repository_dispatch to beeping-io/tap
BEE-1783 3 Scoop bucket auto-update on release (symmetric mirror of BEE-1782) via beeping-io/scoop-bucket
BEE-1786 5 Post-release smoke matrix across every channel × native OS, aggregated Job Summary

🧱 Files changed

  • .github/workflows/release.yml — new notify-tap + notify-scoop jobs, cosign + SBOM + SLSA L3 wiring, body composition with 🛡️ Supply chain section.
  • .github/workflows/verify-supply-chain.yml (new) — exercises cosign + slsa-verifier + cyclonedx-cli on every published release.
  • .github/workflows/post-release-smoke.yml (new) — 5-target × 4-channel install + smoke matrix with aggregated summary.
  • docs/supply-chain.md (new) — canonical verify recipe per OS, trust roots, threat model.
  • docs/installation.md — rewritten with per-OS sections, workarounds, channel status matrix, troubleshooting table.
  • README.md — prominent 📥 Install section, post-release-smoke badge, refreshed Distribution channels table.
  • docs/ROADMAP.md + docs/ROADMAP_CHANGELOG.md — recomputes per closure (6 new History entries, 6 scope-clarification moves).
  • external/tap/Formula/beeping-cli.rb, external/scoop-bucket/bucket/beeping-cli.json, external/README.md — header comments + status updates.

🌐 Cross-repo changes (already pushed)

  • beeping-io/tap@developauto-update.yml workflow + regen-formula.py + README + .markdownlint.json. (881db922a5c4a2)
  • beeping-io/scoop-bucket@developauto-update.yml + regen-manifest.py + README + .markdownlint.json. (3b29f7f0c18d7c)

⏭️ Deferred (still open in Linear under Phase 15)

10 tasks (33 SP) — kept in Phase 15 Backlog state, removed from active tracker:

  • beeping-cli specific: BEE-2222 (Windows FFI runtime crash, 5 SP) — requires Windows debugging marathon.
  • beepbox-cli shared scope: BEE-1778 (ADR, 2), BEE-1779 (CI release matrix, 8), BEE-1784 (AppImage, 5), BEE-1787 (winget, 3), BEE-1788 (Chocolatey, 3), BEE-1789 (Homebrew core, 3), BEE-1790 (Cloudsmith .deb/.rpm, 8), BEE-1791 (Apple Developer ID, 3, budget-blocked), BEE-1792 (Authenticode, 3, budget-blocked).

The Linear Phase 15 ProjectMilestone stays unstarted until those land — its status is derived from issue completion, not manual.

🚧 Founder actions queued post-merge

  1. Create fine-grained PAT scoped to beeping-io/tap (metadata:read + contents:write) → add as TAP_DISPATCH_TOKEN GH Actions secret.
  2. Create second fine-grained PAT scoped to beeping-io/scoop-bucket (same scopes) → add as SCOOP_DISPATCH_TOKEN.
  3. Cut the first real v0.0.x stable tag to exercise the full pipeline + auto-updates + post-release smoke matrix end-to-end.

Without the PATs, both notify-* jobs emit a warning and exit 0; the manual workflow_dispatch fallback on each downstream repo is verified working.

🧪 Test plan

  • cargo fmt --check clean
  • cargo clippy --all-targets -- -D warnings -W clippy::pedantic clean
  • cargo test --all-targets green (190+ tests)
  • cargo deny check clean
  • actionlint on all workflows clean (only pre-existing SC2193/SC2016 warnings inherited from BEE-150 + BEE-1780)
  • markdownlint on all touched docs clean
  • CI green on milestone HEAD d609ac4 (run 25720532516)
  • BEE-1781 e2e verified on v0.0.0-test3: cosign + SLSA L3 + SBOM + SHA256 all Verified OK
  • BEE-1782 e2e verified on v0.0.0-test4: tap auto-update workflow regenerated formula cleanly, committed to develop, then reverted
  • BEE-1783 e2e verified on v0.0.0-test5: scoop-bucket auto-update workflow regenerated manifest cleanly
  • BEE-1786 structural validation: actionlint + manual review (e2e gated on first stable release post-merge since workflow_dispatch + release.published triggers require default-branch presence)

Closes BEE-1781, BEE-1782, BEE-1783, BEE-1785, BEE-1786

🤖 Generated with Claude Code

alfredrc and others added 10 commits May 11, 2026 07:04
…venance

Every release artifact now ships with a complete supply-chain
attestation:

- cosign keyless signature (.sig) + Fulcio cert (.pem) tied to the
  workflow OIDC identity at this commit. Sigstore Rekor records the
  signing event in its transparency log.
- CycloneDX SBOM (.cdx.json) per artifact via syft, listing component
  + license + version metadata.
- SLSA L3 build provenance (.intoto.jsonl) covering every artifact in
  the release, generated by
  slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
  on an isolated hermetic builder.

Pipeline wiring:

- New per-matrix step emits each archive's SHA256 + uploads as a
  hash sidecar.
- New combine-hashes job aggregates per-target hashes into the
  base64 subject blob expected by the SLSA reusable workflow.
- New provenance job consumes the blob, uploads the resulting
  intoto.jsonl to the release.
- release job: cosign-installer + sign-blob loop + syft SBOM step
  + permissions: id-token: write for keyless OIDC.
- Body composition adds a 🛡️ Supply chain section with verify
  snippets and a cross-link to docs/supply-chain.md.

New: .github/workflows/verify-supply-chain.yml — runs on every
published release (and manual dispatch) to exercise the same
verification recipe a downstream consumer would, catching drift
between signing pipeline and documented verify steps.

New: docs/supply-chain.md — canonical install + verify recipe per
OS, trust-root reference, threat model.

External scaffolding (external/tap + external/scoop-bucket) gets
comment-only mentions of cosign + SLSA so the transplanted files
in beeping-io/tap and beeping-io/scoop-bucket carry the same
context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move BEE-1781 from Phase 15 shared scope to beeping-cli specific
  (+5 SP to Phase 15 specific). Same precedent as BEE-1780 on
  2026-05-06: entire implementation lives in this repo's release
  pipeline + docs, no beepbox-side work.
- Phase 15 specific now 54 SP; 49/54 done (91 %), 1 remaining
  (BEE-2222).
- Append History entry covering: pipeline jobs added (combine-hashes,
  provenance), cosign + SBOM steps, verify-supply-chain.yml + docs;
  end-to-end verification on test tag v0.0.0-test3 across all four
  layers (SHA256, cosign keyless, SLSA L3, CycloneDX schema).
- No timeline impact; estimated end stays 2026-05-19.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rewrite docs/installation.md: quick install table, supply-chain verify
  section (cross-link to docs/supply-chain.md), per-OS sections
  (macOS / Linux / Windows) with manual tarball recipes + Gatekeeper /
  SmartScreen workarounds (deferred BEE-1791 / BEE-1792), ALSA runtime
  prereq for Linux, BEE-2222 Windows runtime caveat, channel status
  matrix, troubleshooting table.
- README.md: add a prominent 📥 Install section right after the intro
  with 4 one-liners + cross-link to installation.md + supply-chain.md.
- README.md: remove duplicate install commands from the "Target CLI"
  section now that they live in the Install section.
- README.md: refresh "Distribution channels" table to reflect the
  channels that landed (BEE-150 / 151 / 152 / 1780 / 1781) and the
  ones still queued.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move BEE-1785 from Phase 15 shared scope to beeping-cli specific
  (+2 SP to Phase 15 specific). Third closure of this shape this
  milestone (BEE-1780 + BEE-1781 + BEE-1785) — pattern is now
  well-established.
- Phase 15 specific now 56 SP; 51/56 done (91 %), 1 remaining
  (BEE-2222).
- Append History entry covering install.md rewrite + README Install
  section + per-OS workarounds (Gatekeeper / SmartScreen / ALSA /
  BEE-2222 caveat) + lychee 32 OK link check.
- No timeline impact; estimated end stays 2026-05-19.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a new `notify-tap` job to release.yml that runs after the
`release` job succeeds. On stable `v*` tags (pre-release tags
`-rc`/`-test`/`-alpha` are excluded with the same predicate used
by publish-crates), the job fires a `repository_dispatch` event
of type `beeping-cli-released` to `beeping-io/tap` with the new
tag as `client_payload.tag`.

The tap repo's `.github/workflows/auto-update.yml` (committed in
`beeping-io/tap@881db92`) listens for that dispatch, downloads
SHA256SUMS, regenerates `Formula/beeping-cli.rb` via
`scripts/regen-formula.py`, and commits to develop.

Founder action required after this merges: create a fine-grained
PAT scoped to `beeping-io/tap` with metadata:read +
contents:write, then add it as the `TAP_DISPATCH_TOKEN` secret in
this repo. Until that lands, the notify-tap step emits a warning
and exits 0 — release itself still publishes, and the tap can
be updated manually via workflow_dispatch on the tap side.

Also:
- external/tap/Formula/beeping-cli.rb header rewritten to document
  that this in-repo copy is the canonical structure while the
  deployed copy in beeping-io/tap carries the real hashes.
- external/README.md moves BEE-1782 from "What's NOT here yet"
  to "What's now present" + documents the TAP_DISPATCH_TOKEN
  founder action.
- docs/installation.md drops the "until BEE-1782 lands" caveat
  for the Homebrew tap (Scoop still pending BEE-1783).
- README.md distribution channels table flips Homebrew status
  to "live + auto-updated per release".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move BEE-1782 from Phase 15 shared scope to beeping-cli specific
  (+3 SP). Fourth move of this shape this milestone (after
  BEE-1780, BEE-1781, BEE-1785).
- Phase 15 specific now 59 SP; 54/59 done (92 %), 1 remaining
  (BEE-2222).
- Append History entry covering release.yml notify-tap job + tap
  repo auto-update.yml + regen-formula.py + end-to-end test cycle
  on v0.0.0-test4.
- No timeline impact; estimated end stays 2026-05-19.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ease

Add `notify-scoop` job to release.yml, symmetric to `notify-tap`
from BEE-1782. Same predicate (stable v* tags only, pre-release
skip), same dispatch pattern (gh api POST .../dispatches with
jq-built JSON body), same fall-through behaviour when the secret
is missing (warning + exit 0).

Per-repo least-privilege: SCOOP_DISPATCH_TOKEN is a separate
fine-grained PAT scoped to beeping-io/scoop-bucket. The matching
scoop-bucket-side workflow + regen script were committed at
beeping-io/scoop-bucket@3b29f7f.

Also:
- external/scoop-bucket/bucket/beeping-cli.json _comment rewritten
  to document the auto-update flow.
- external/README.md moves BEE-1783 from "What's NOT here yet"
  to "What's now present" + adds the SCOOP_DISPATCH_TOKEN
  founder action alongside TAP_DISPATCH_TOKEN.
- docs/installation.md drops the "until BEE-1783 lands" caveat
  for Scoop (both Homebrew + Scoop now auto-update); Channel
  status row flipped; Troubleshooting row simplified.
- README.md distribution channels table flips Scoop status to
  "live + auto-updated per release".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move BEE-1783 from Phase 15 shared scope to beeping-cli specific
  (+3 SP). Fifth consecutive move of this shape this milestone
  (after BEE-1780, BEE-1781, BEE-1785, BEE-1782).
- Phase 15 specific now 62 SP; 57/62 done (92 %), 1 remaining
  (BEE-2222).
- Append History entry covering release.yml notify-scoop job +
  scoop-bucket auto-update.yml + regen-manifest.py + end-to-end
  test cycle on v0.0.0-test5.
- No timeline impact; estimated end stays 2026-05-19.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n channel

New `.github/workflows/post-release-smoke.yml` fires on
`release.published` (and manual `workflow_dispatch` for testing).
Exercises every distribution channel against its native OS:

- 📦 Direct tarball/zip per target (5 platforms, native runners
  including the new macos-15-intel + ubuntu-24.04-arm). Downloads
  the artifact from the release, extracts, runs --version assertion
  matching the release tag, `doctor --mode offline`, and an offline
  encode→WAV→decode round-trip (skipped on Windows pending
  BEE-2222).
- 📦 `cargo install beeping-cli --version <tag>` on ubuntu + macos
  + windows (skipped on pre-release per crates.io publish predicate).
- 🍺 `brew install beeping-io/tap/beeping-cli` on macos-latest
  (arm64) + macos-15-intel + ubuntu-latest (Linuxbrew). Skipped on
  pre-release per BEE-1782 tap auto-update predicate.
- 🥄 `scoop install beeping-cli` on windows-latest after adding the
  bucket. Skipped on pre-release per BEE-1783 bucket auto-update
  predicate.

Final `summary` job (always runs, gated on `!cancelled()`) reads
`needs.*.result`, emits a markdown table to `$GITHUB_STEP_SUMMARY`
mapping channel→✅/❌/⏭️/🚫, and fails the workflow if any active
channel failed. Skipped channels (pre-release path) don't fail.

Pre-release runs (e.g. `v0.0.0-test*`) execute only the
direct-tarball path — the other three channels skip themselves
because their feeder pipelines also skip pre-releases. This keeps
the smoke matrix testable with throwaway tags while still
representing the real release contract.

Adds the post-release-smoke badge to README and links to it from
docs/installation.md.

external/README.md: BEE-1786 moves to "What's now present"; the
distribution scaffolding `NOT here yet` list is now empty for
`beeping-cli`-scope work — remaining BEE-178x is external registry
submissions + AppImage/.deb/.rpm packaging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move BEE-1786 from Phase 15 shared scope to beeping-cli specific
  (+5 SP). Sixth consecutive move of this shape this milestone
  (BEE-1780/1781/1785/1782/1783/1786) — every task whose
  implementation lives in this repo has been pulled here.
- Phase 15 specific now 67 SP; 62/67 done (93 %), 1 remaining
  (BEE-2222 — Windows FFI runtime crash).
- Append History entry covering the smoke matrix workflow + 6 jobs
  + e2e CI execution gated on milestone PR merge to develop.
- No timeline impact; estimated end stays 2026-05-19.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alfredrc alfredrc merged commit 670de18 into develop May 12, 2026
24 of 26 checks passed
@alfredrc alfredrc deleted the milestone/phase-15 branch May 12, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant