Files
Claude Opus 5andbdeshi 061ae098da Sign builds and releases with a stable code identity
swiftc linker-signs only the inner binary, leaving the bundle unsigned
and its codesign identifier as "launcher" rather than the bundle id. More
importantly it leaves the app ad-hoc signed, and macOS pins an ad-hoc
app's Accessibility grant to its exact cdhash instead of to a designated
requirement. Every build mints a new cdhash, so each rebuild-and-replace
silently revoked the permission while the app stayed listed and ticked
under Privacy & Security — and every release did the same to everyone who
updated. That was the root cause of the window tags never appearing.

- build.sh signs the bundle with its real identifier, honours
  SHANNONCOAT_SIGN_IDENTITY, and fails outright rather than falling back
  to ad-hoc when an identity was asked for explicitly.
- The identity is read from a gitignored .env, so it doesn't have to be
  retyped every build. Parsed rather than sourced, so a stray command in
  the file can't execute as a side effect of building, and so an existing
  environment variable still wins. .env.example carries the full one-time
  setup.
- release.yml imports the certificate into a throwaway keychain, builds,
  verifies, and deletes the keychain on if: always(). It stays inert
  until the three secrets exist, and fails the release rather than
  shipping ad-hoc.
- Guards the empty-password case explicitly: macOS cannot import an
  OpenSSL-produced PKCS#12 with an empty password, and reports it as "MAC
  verification failed (wrong password?)", which sends you hunting for a
  wrong password rather than a missing one. Nothing local catches this,
  since the login keychain imports the PEM pair and needs no password.
- Ignores *.p12 and *.pem as a backstop; the certificate belongs outside
  the working tree entirely.

Verified end-to-end: two from-scratch builds produce byte-identical
designated requirements where ad-hoc differs every time, and six
rebuild-reinstall cycles under a real certificate kept the Accessibility
grant with no System Settings interaction.

This buys permission persistence, not Gatekeeper approval — a
self-signed certificate isn't notarized, so downloads still need
System Settings -> Privacy & Security -> Open Anyway.
2026-08-05 13:23:09 +06:00

157 lines
3.5 KiB
Plaintext

# Icon generation: raw Claude.app icon assets extracted as source material
# for icon/generate-icon.swift — the derived composite (icon/AppIcon.icns)
# is committed, but Anthropic's own unmodified icon files aren't.
icon/claude-src/
icon/AppIcon.iconset/
# Session handoff notes — local only, never committed
CHECKPOINT.md
# Local build configuration, read by build.sh — holds the code-signing
# identity and, optionally, the certificate password. See .env.example for
# the shape of it. Never committed.
.env
# Belt and braces: private key material must never land in the repo, even
# gitignored. Keep the certificate itself outside the working tree (the
# setup notes in .env.example use ~/.shannoncoat-signing/) — this pattern
# only exists to catch a stray copy before it becomes a commit.
*.p12
*.pem
# Local reference material (e.g. nested checkouts of other projects) — not
# part of this project, never meant to be committed.
.scratch/
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings
xcuserdata/
## Obj-C/Swift specific
*.hmap
## App packaging
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build/
# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# AI agents and assistants
#
# Some common agent instruction and project configuration files are listed
# below as commented-out examples. They are often intentionally committed and
# shared with a team, so only uncomment them if they are local-only in your
# project.
# GEMINI.md
# WARP.md
# CRUSH.md
# QWEN.md
# OpenAI Codex
# AGENTS.md
# .codex/
# Aider
# .aider.input.history
# .aider.chat.history.md
# .aider.llm.history
# .aider.tags.cache.v*
# .aiderignore
# Claude Code
.claude/*.local.json
.claude/**/*.log
CLAUDE.local.md
# .claude/
# Gemini CLI
# gemini-debug.log
# .gemini-clipboard/
# .gemini/
# Cursor AI
# .cursorrules
# .cursor/
# .cursor.json
# .cursor-settings.yaml
# Continue
# .continue/
# .continuerc.json
# Cline
# .cline/
# .clinerules
# cline.json
# Other agent/editor project config
# .warp/
# .crush/
# .codeium/
# .deepseek/
# .amazon-codewhisperer/
# .tabnineignore
# .tabnine/
# GitHub Copilot
# .github/copilot-instructions.md
# Windsurf Editor
# .windsurfrules
# .windsurf/
# Replit AI Development
# .replit
# replit.nix