Your first playbook
Write a playbook the second time you do something. The first time you do not yet know which parts were hard; the second time you do, and you still remember.
1. The shape
Section titled “1. The shape”A playbook is a directory: a playbook.yaml plus an optional assets/ folder.
That directory is the unit Speccify hashes, pins and distributes.
macos-notarize-tauri/├── playbook.yaml└── assets/ └── entitlements.plist2. Write the steps
Section titled “2. Write the steps”schema_version: 1id: "@org/macos-notarize-tauri"version: 1.0.0title: Notarize a Tauri app for macOSsummary: | Sign, notarize and staple a Tauri app so it opens without a Gatekeeper warning on a machine that has never seen it.
applies_to: platforms: [macos] keywords: [tauri, notarization, gatekeeper]
prerequisites: - An Apple Developer ID Application certificate in the login keychain.
steps: - id: entitlements title: Declare the entitlements the hardened runtime needs detail: | Notarization requires the hardened runtime, which blocks the JIT and unsigned memory Tauri's webview needs. Without these two keys the app notarizes and then crashes on launch — which is worse than failing. assets: [assets/entitlements.plist] sources: [hardened_runtime] verify: codesign -d --entitlements - Speccify.app lists both keys.
sources: - id: hardened_runtime title: Hardened Runtime entitlements url: https://developer.apple.com/documentation/security/hardened-runtime retrieved: 2026-08-06Three things carry the weight:
detailsays why, not just what. “Add these entitlements” is something an agent can already guess. “Without them it notarizes and then crashes” is the thing you paid for the first time.sourcescarry aretrieveddate. That is what makes rot detectable later.verifyis how you know it worked — a command or an observation, not a feeling.
A step either describes itself with detail or delegates to another playbook
with uses — never both, because then it is unclear which one to follow:
- id: certificate title: Get a Developer ID certificate uses: "@org/apple-developer-id-cert@^1.0"3. Check it
Section titled “3. Check it”uv run speccify lint playbooks/org/macos-notarize-tauriuv run speccify check playbooks/org/macos-notarize-tauri --linkslint is structure. check adds source age, and --links asks whether every
URL still resolves. Run it again in six months — that is the point.
4. Look at it
Section titled “4. Look at it”./scripts/dev-up.sh # → http://localhost:5173The viewer shows the workflow as a diagram and every source with its age. There is no edit mode: select a step, ask the agent beside it, and apply what it proposes as a diff.
5. Share it
Section titled “5. Share it”Publishing is git tag + git push — no registry account:
dependencies: "git+https://github.com/acme/notarize-playbook": "^1.0"More: Git sources & discovery.