Skip to content

feat: sign gro darwin binaries with a stable code-signing identity#155

Merged
rianjs merged 3 commits into
mainfrom
feat/154-sign-gro-darwin
Jun 3, 2026
Merged

feat: sign gro darwin binaries with a stable code-signing identity#155
rianjs merged 3 commits into
mainfrom
feat/154-sign-gro-darwin

Conversation

@rianjs

@rianjs rianjs commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Gives gro a stable macOS code-signing identity so the Keychain "Always Allow" grant survives brew upgrade (convention: cli-common distribution.md §2A; infra on @v1). Same pattern proven by the slck canary (v3.2.60, DR verified).

  • .goreleaser.yaml: darwin hooks.post on gro-darwin → centralized codesign-darwin.sh via absolute $CODESIGN_DARWIN_SCRIPT.
  • release.yml: forward the four macos-cert-* secrets (explicit pass-through).
  • version.txt1.1: trips the dual-gate auto-release → signed release.

darwin-gate check-signature enforces certificate leaf = H"42e1afd0…" / no cdhash before publish. One-time final re-prompt expected for existing macOS users.

Closes #154

rianjs added 2 commits June 3, 2026 16:35
Add the darwin hooks.post to the gro-darwin build (centralized codesign-darwin.sh
via $CODESIGN_DARWIN_SCRIPT), forward the four macos-cert-* secrets, and bump
version.txt to 1.1 so the merge cuts a signed release.

Closes #154
@rianjs

rianjs commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Codex PR review (9a). STATUS: blockers=0 majors=0 minors=0 nits=1 — the nit (stale 'unsigned' cask comment) is fixed in the follow-up commit.

Findings

Nit: .goreleaser.yaml:104 still says the cask handles quarantine removal “for unsigned binaries.” After this PR, the darwin Homebrew binary is signed but still non-notarized, so the comment is stale and diverges from the wording we settled on in the convention. Suggested wording: “auto-quarantine removal for non-notarized binaries” or “quarantine metadata removal if present.”

No release-blocking issues found. The hook is on gro-darwin, which is the CGO-enabled darwin-only build, and matches the proven slck hook. The caller forwards all four macos-cert-* secrets explicitly with the correct names. packaging/identity.yml has binary: gro plus keychain_probe, so shared @v1 should derive org.open-cli-collective.gro and enforce the DR. version.txt is a real 1.0 -> 1.1 minor bump, and goreleaser check -f .goreleaser.yaml passes.

@monit-reviewer monit-reviewer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated PR Review

Reviewed commit: d4cd180

Summary

Reviewer Findings
harness-engineering:harness-architecture-reviewer 1
harness-engineering:harness-enforcement-reviewer 1
harness-engineering:harness-knowledge-reviewer 1
harness-engineering:harness-architecture-reviewer (1 findings)

💡 Suggestion - .goreleaser.yaml:48

The codesign hook exits 0 and prints a skip message when CODESIGN_DARWIN_SCRIPT is unset, so a misconfigured CI runner produces an unsigned binary with no build failure. The darwin-gate check-signature step is the only backstop. Consider emitting a non-zero exit when CI=true and CODESIGN_DARWIN_SCRIPT is unset, making the gate redundant rather than load-bearing.

harness-engineering:harness-enforcement-reviewer (1 findings)

💡 Suggestion - .goreleaser.yaml:50

The post hook fires once per built artifact. If gro-darwin targets multiple architectures (e.g., darwin/amd64 and darwin/arm64), CODESIGN_DARWIN_SCRIPT will be invoked once per arch binary in sequence. Verify that the shared signing script is designed for per-arch invocation (not a one-shot aggregator expecting a single call).

harness-engineering:harness-knowledge-reviewer (1 findings)

⚠️ Should Fix - .goreleaser.yaml:50

The hook silently skips signing when CODESIGN_DARWIN_SCRIPT is set but points to a missing or non-executable path. The condition [ -n "$f" ] && [ -x "$f" ] treats a set-but-broken variable identically to an unset one, so a misconfigured CI runner (wrong path, wrong permissions) would fall through to the 'skip codesign' echo and exit 0 — publishing an unsigned binary without any build failure. When the variable is non-empty, a missing or non-executable script should be a hard error (exit 1) rather than a silent skip. Suggested fix: split the condition — if the variable is unset/empty, skip with a message; if it is set but not executable, fail with an error.

3 info-level observations excluded. Run with --verbose to include.

1 PR discussion thread considered.


Completed in 1m 16s | $0.44 | sonnet | daemon 0.2.121 | Glorfindel
Field Value
Model sonnet
Reviewers hybrid-synthesis, harness-engineering:harness-architecture-reviewer, harness-engineering:harness-enforcement-reviewer, harness-engineering:harness-knowledge-reviewer
Engine claude · sonnet
Reviewed by pr-review-daemon · monit-pr-reviewer
Duration 1m 16s wall · 2m 58s compute (Reviewers: 58s · Synthesis: 16s)
Cost $0.44
Tokens 117.1k in / 15.0k out
Turns 7

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost
hybrid-synthesis sonnet 30.9k 1.2k 18.6k 12.3k (1h) $0.07
harness-engineering:harness-architecture-reviewer sonnet 28.7k 4.7k 16.3k 12.3k (1h) $0.12
harness-engineering:harness-enforcement-reviewer sonnet 29.8k 5.7k 16.3k 13.5k (1h) $0.14
harness-engineering:harness-knowledge-reviewer sonnet 27.7k 3.5k 16.3k 11.4k (1h) $0.10

Re-reviews only run when @monit-reviewer is re-requested as a reviewer — push as many commits as you need, then re-request when ready. PRs targeting branches other than main, master are skipped, even when @monit-reviewer is re-requested.

Comment thread .goreleaser.yaml
Comment thread .goreleaser.yaml
Comment thread .goreleaser.yaml
Keep unset CODESIGN_DARWIN_SCRIPT a no-op (local builds), but if it is set yet
missing/non-executable, fail the build with a clear message instead of silently
skipping and shipping an unsigned binary (caught later by darwin-gate).
@monit-reviewer monit-reviewer dismissed their stale review June 3, 2026 20:42

Superseded by updated review

@monit-reviewer monit-reviewer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated PR Review

Reviewed commit: d11897f | Previous: d4cd180 (incremental)

Summary

No issues found.

4 PR discussion threads considered.


Completed in 34s | $0.33 | sonnet | daemon 0.2.121 | Glorfindel
Field Value
Model sonnet
Mode Re-review · Cycle 2 · Session resumed
Reviewers hybrid-synthesis, harness-engineering:harness-architecture-reviewer, harness-engineering:harness-enforcement-reviewer, harness-engineering:harness-knowledge-reviewer
Engine claude · sonnet
Reviewed by pr-review-daemon · monit-pr-reviewer
Duration 34s wall · 30s compute (Reviewers: 5s · Synthesis: 11s)
Cost $0.33
Tokens 119.2k in / 1.5k out
Turns 4

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost
hybrid-synthesis sonnet 35.1k 546 18.6k 16.5k (1h) $0.08
harness-engineering:harness-architecture-reviewer sonnet 19.2k 91 4.0k 15.2k (1h) $0.06
harness-engineering:harness-enforcement-reviewer sonnet 20.2k 97 4.0k 16.2k (1h) $0.06
harness-engineering:harness-knowledge-reviewer sonnet 18.1k 72 4.0k 14.0k (1h) $0.05
discussion-summarizer 26.5k 731 17.8k 4.0k (1h) $0.08

Re-reviews only run when @monit-reviewer is re-requested as a reviewer — push as many commits as you need, then re-request when ready. PRs targeting branches other than main, master are skipped, even when @monit-reviewer is re-requested.

@rianjs

rianjs commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Codex final pass (9e): blockers=0 majors=0 minors=0 nits=0 — no findings. Post-daemon hook (fail-loud on set-but-broken CODESIGN_DARWIN_SCRIPT) preserves the architecture; goreleaser check passes.

@rianjs rianjs merged commit d61bbc2 into main Jun 3, 2026
11 checks passed
@rianjs rianjs deleted the feat/154-sign-gro-darwin branch June 3, 2026 20:44
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.

Sign gro darwin binary with a stable code-signing identity

2 participants