{"id":39425807,"url":"https://github.com/felixgeelhaar/specular","last_synced_at":"2026-01-18T04:00:07.727Z","repository":{"id":323752381,"uuid":"1090835873","full_name":"felixgeelhaar/specular","owner":"felixgeelhaar","description":"AI-native development framework with specification-driven workflows, built-in drift detection, and multi-LLM provider support","archived":false,"fork":false,"pushed_at":"2026-01-16T23:25:32.000Z","size":21718,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-16T23:58:25.014Z","etag":null,"topics":["ai","anthropic","automation","ci-cd","code-generation","devops","docker","drift-detection","go","golang","llm","openai","policy-enforcement","specification","tdd"],"latest_commit_sha":null,"homepage":"https://github.com/felixgeelhaar/specular","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/felixgeelhaar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-06T07:47:38.000Z","updated_at":"2026-01-16T23:25:35.000Z","dependencies_parsed_at":"2026-01-02T22:09:12.332Z","dependency_job_id":null,"html_url":"https://github.com/felixgeelhaar/specular","commit_stats":null,"previous_names":["felixgeelhaar/specular"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/felixgeelhaar/specular","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fspecular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fspecular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fspecular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fspecular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/felixgeelhaar","download_url":"https://codeload.github.com/felixgeelhaar/specular/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fspecular/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28529455,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","anthropic","automation","ci-cd","code-generation","devops","docker","drift-detection","go","golang","llm","openai","policy-enforcement","specification","tdd"],"created_at":"2026-01-18T04:00:06.788Z","updated_at":"2026-01-18T04:00:07.670Z","avatar_url":"https://github.com/felixgeelhaar.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/specular_logo.png\" alt=\"Specular Logo\" width=\"400\"\u003e\n\u003c/p\u003e\n\n# Specular\n\n**AI-Native Spec and Build Assistant with Governance**\n\nA Go-based CLI tool that enables spec-first, policy-enforced software development using AI. Transform natural language product requirements into structured specifications, executable plans, and production-ready code while maintaining traceability and enforcing organizational guardrails.\n\n## Why Specular?\n\nMost teams are adopting AI for ideation, planning, code generation, and automation. But they lack:\n\n- **Governance** for what AI may do and how decisions are made\n- **Policy enforcement** across providers and environments\n- **Drift detection** between requirements, plans, and implementation\n- **Cost and risk controls** for AI usage\n- **Auditable artifacts** with cryptographic integrity\n- **Reproducible workflows** from spec to production\n\n**Specular solves this** by providing:\n\n✅ **Spec-First Development**: Transform requirements into formal specifications with AI-assisted interview mode\n✅ **Governance \u0026 Policy**: Enterprise-grade policy engine with cryptographic approvals and bundle workflows\n✅ **Multi-Provider AI**: Intelligent routing across local (Ollama) and cloud (OpenAI, Anthropic, Gemini) models\n✅ **Drift Detection**: Continuous validation of spec → plan → code alignment with SARIF reporting\n✅ **Docker Sandboxing**: Secure isolated execution with resource limits and image allowlisting\n✅ **Autonomous Mode**: Checkpoint/resume for long-running workflows with full state preservation\n✅ **Audit \u0026 Compliance**: Cryptographic attestations, trace logging, and approval workflows\n\n\u003e **Specular is the control plane and audit layer for AI-driven development.**\n\u003e It replaces \"wild west prompting\" with structured, governed, policy-compliant workflows.\n\n## Quick Links\n\n📚 **[Getting Started](docs/getting-started.md)** – Quickstart plus common workflows\n🛠️ **[Installation Guide](docs/installation.md)** – Package, binary, and Docker installs\n🔧 **[Provider Guide](docs/provider-guide.md)** – Configure local/cloud AI providers\n📘 **[CLI Reference](docs/CLI_REFERENCE.md)** – Command/flag reference\n📐 **[Spec Schema Reference](docs/spec-schema.md)** – Complete spec.yaml format guide\n📦 **[Bundle User Guide](docs/BUNDLE_USER_GUIDE.md)** – Governed bundle workflows\n🚀 **[Production Guide](docs/PRODUCTION_GUIDE.md)** – Production deployment, security, monitoring\n🔌 **[Plugin Development](docs/plugin-development/README.md)** – Build custom plugins\n\n---\n\n## What's New in v1.6.0 🎉\n\n### 🚀 GitHub Action for CI/CD Integration\n\nSeamless integration with GitHub Actions for automated drift detection and policy enforcement:\n\n```yaml\n- uses: felixgeelhaar/specular@v1\n  with:\n    command: drift\n    anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}\n```\n\n**Key Features:**\n- Four commands: `drift`, `eval`, `build`, `plan`\n- Multi-provider AI support (Anthropic, OpenAI, Google)\n- Automatic SARIF upload to GitHub Code Scanning\n- Platform auto-detection (Linux/macOS, AMD64/ARM64)\n- Rich job summaries and PR comment integration\n- Comprehensive [Action documentation](.github/ACTION_README.md)\n\n### 🎨 Interactive Plan Review TUI\n\nFull-featured terminal UI for reviewing execution plans before approval:\n\n- **Two-view system**: List view for overview, detail view for task inspection\n- **Vim-style navigation**: j/k, h/l, Enter, Esc for efficient interaction\n- **Approve/reject workflow**: Rejection reason prompts with full audit trail\n- **Auto-approve**: Empty plans auto-approved for convenience\n- **Styled interface**: Professional appearance with lipgloss theming\n- **11 comprehensive tests**: Ensuring reliability across all scenarios\n\n### 🌐 Platform API Client v2.0\n\nProduction-grade HTTP client for Specular Platform integration:\n\n- **Configurable retry logic**: Exponential backoff with smart retry strategy\n- **Intelligent routing**: Retries 5xx errors, fails fast on 4xx\n- **Context propagation**: Request cancellation and timeout handling\n- **Structured errors**: APIError type with request ID tracking\n- **Three endpoints**: Health, GenerateSpec, GeneratePlan\n- **14 comprehensive tests**: Including retry scenarios and edge cases\n\n### 🔌 Plugin System Enhancements\n\nExtended plugin capabilities for maximum flexibility:\n\n- **Local installation**: Install plugins from directories\n- **GitHub installation**: Direct plugin installation from repositories\n- **Automatic resolution**: Dependency resolution for plugin chains\n- **Five plugin types**: Provider, validator, formatter, hook, notifier\n\n### 📦 Distribution \u0026 Availability\n\n**Homebrew Installation:**\n```bash\nbrew tap felixgeelhaar/specular\nbrew install specular\n```\n\n**Shell Completions:** Bash, Zsh, Fish completions included in all releases\n\n**Multi-platform Binaries:** Linux/macOS/Windows on AMD64/ARM64\n\n### 📚 Enhanced Documentation\n\n- **ACTION_README.md**: Complete GitHub Action integration guide (9.7KB)\n- **Tutorial guides**: Step-by-step PRO feature walkthroughs\n- **Advanced workflows**: Production-grade deployment patterns\n- **300KB+ docs**: Comprehensive coverage of all features\n\n---\n\n**Previous Release: v1.2.0** introduced governance-first CLI redesign with policy management, approval workflows, and backward-compatible command structure. [View details in CHANGELOG](CHANGELOG.md#120---2025-11-17).\n\n[View Full Changelog](CHANGELOG.md)\n\n---\n\n## Features\n\n### Core Capabilities\n\n- **AI Provider Plugin System**: Pluggable architecture for local models (Ollama), cloud APIs (OpenAI, Anthropic, Gemini), and custom providers\n- **CLI Provider Protocol**: Language-agnostic protocol for creating custom AI providers (covered in the [Provider Guide](docs/provider-guide.md))\n- **Intelligent Model Routing**: Smart model selection based on task complexity, budget, and performance constraints\n- **Interview Mode**: Guided Q\u0026A with interactive TUI to generate best-practice specifications\n- **Enhanced Error System**: Structured errors with error codes, suggestions, and documentation links\n- **SpecLock**: Canonical, hashed specification snapshots for drift detection\n- **Plan Generator**: Converts specs into task DAGs with dependencies\n- **Drift Detection**: Multi-level drift detection (plan, code, infrastructure)\n- **Docker-Only Sandbox**: Secure isolated execution environment\n\n### Advanced Features\n\n- **Governance Workflows** (v1.2.0): Enterprise-grade governance with workspace initialization, health checks, and status monitoring\n- **Policy Management** (v1.2.0): Full policy lifecycle with init, validate, approve, list, and diff commands\n- **Approval Workflows** (v1.2.0): Role-based approvals for plans, builds, and drift with audit trails\n- **Cryptographic Attestations** (v1.2.0): ECDSA P-256 signatures for build artifacts and policy changes\n- **Autonomous Mode** (v1.0.0): Checkpoint/resume capabilities for long-running sessions with full state preservation\n- **Routing Intelligence** (v1.0.0): Provider selection optimization with cost tracking and task-type routing\n\n### Testing \u0026 Quality Assurance\n\n- **Eval Gate**: Automated tests, linting, coverage, and security checks\n- **Policy Engine**: YAML-based guardrail enforcement\n- **Approval Workflows**: SHA256-based governance signatures for artifacts\n\n## Installation\n\n### macOS / Linux (Homebrew)\n\n```bash\n# Add the tap\nbrew tap felixgeelhaar/tap\n\n# Install specular\nbrew install specular\n\n# Verify installation\nspecular version\n```\n\n### Linux Packages\n\n#### Debian/Ubuntu (.deb)\n\n```bash\n# Download the latest .deb package\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_amd64.deb\n\n# Install the package\nsudo dpkg -i specular_linux_amd64.deb\n\n# Or for ARM64\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_arm64.deb\nsudo dpkg -i specular_linux_arm64.deb\n```\n\n#### RedHat/Fedora/CentOS (.rpm)\n\n```bash\n# Download the latest .rpm package\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_amd64.rpm\n\n# Install the package\nsudo rpm -i specular_linux_amd64.rpm\n\n# Or for ARM64\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_arm64.rpm\nsudo rpm -i specular_linux_arm64.rpm\n```\n\n#### Alpine Linux (.apk)\n\n```bash\n# Download the latest .apk package\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_amd64.apk\n\n# Install the package\nsudo apk add --allow-untrusted specular_linux_amd64.apk\n\n# Or for ARM64\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_arm64.apk\nsudo apk add --allow-untrusted specular_linux_arm64.apk\n```\n\n### Direct Binary Download\n\nDownload pre-built binaries from the [releases page](https://github.com/felixgeelhaar/specular/releases):\n\n```bash\n# Linux AMD64\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_linux_amd64.tar.gz\ntar -xzf specular_linux_amd64.tar.gz\nsudo mv specular /usr/local/bin/\n\n# macOS AMD64 (Intel)\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_darwin_amd64.tar.gz\ntar -xzf specular_darwin_amd64.tar.gz\nsudo mv specular /usr/local/bin/\n\n# macOS ARM64 (Apple Silicon)\nwget https://github.com/felixgeelhaar/specular/releases/latest/download/specular_darwin_arm64.tar.gz\ntar -xzf specular_darwin_arm64.tar.gz\nsudo mv specular /usr/local/bin/\n\n# Windows AMD64\n# Download specular_windows_amd64.zip from releases page\n# Extract and add to PATH\n```\n\n### Docker\n\n```bash\n# Pull the latest image\ndocker pull ghcr.io/felixgeelhaar/specular:latest\n\n# Run with current directory mounted\ndocker run -v $(pwd):/workspace ghcr.io/felixgeelhaar/specular:latest version\n```\n\n### Build from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/felixgeelhaar/specular.git\ncd specular\n\n# Build from source\nmake build\n\n# Or install to GOPATH/bin\nmake install\n```\n\n## AI Provider System \u0026 Generate Command\n\nThe AI provider system enables flexible integration with multiple AI providers (local models, cloud APIs, custom executables) through a pluggable architecture. The `generate` command provides immediate access to AI capabilities with intelligent model routing.\n\n### Quick Setup\n\n```bash\n# 1. Add an AI provider (example: Anthropic)\nspecular provider add anthropic --api-key $ANTHROPIC_API_KEY\n\n# Or add other providers:\n# specular provider add openai --api-key $OPENAI_API_KEY\n# specular provider add gemini --api-key $GEMINI_API_KEY\n# specular provider add ollama  # For local Ollama (requires ollama installed)\n\n# 2. List configured providers\nspecular provider list\n\n# 3. Check provider health\nspecular provider doctor\n\n# 4. Set default provider\nspecular provider set-default anthropic\n```\n\n### Generate Command Examples\n\n```bash\n# Simple generation with automatic model selection\nspecular generate \"What is 2 + 2?\"\n\n# Fast response with model hint\nspecular generate \"Count from 1 to 10\" --model-hint fast\n\n# Code generation with appropriate model\nspecular generate \"Write a Go function to reverse a string\" --model-hint codegen\n\n# High complexity task with P0 priority (uses most capable model)\nspecular generate \"Explain microservices architecture\" --complexity 8 --priority P0\n\n# With system prompt and temperature control\nspecular generate \"Tell me a story\" \\\n  --system \"You are a creative writer. Keep responses concise.\" \\\n  --temperature 0.9 \\\n  --max-tokens 500\n\n# Verbose mode shows metadata (model, tokens, cost, latency)\nspecular generate \"What is Go?\" --model-hint fast --verbose\n\n# Example verbose output:\n# Go is a statically typed, compiled programming language...\n#\n# ------------------------------------------------------------\n# Model:          llama3.2 (ollama)\n# Tokens:         42 (in: 12, out: 30)\n# Cost:           $0.000000\n# Latency:        2.4s\n# Selection:      Selected llama3.2: fast model for low complexity task\n# Finish Reason:  stop\n#\n# Budget:         $0.00 spent, $20.00 remaining (0.0% used)\n```\n\n### Model Hints\n\nThe router automatically selects the best model based on your hints:\n\n- `fast` - Quick responses (llama3.2, claude-haiku, gpt-4o-mini, gemini-flash)\n- `codegen` - Code generation (codellama, claude-sonnet, gpt-4o, gemini-flash)\n- `agentic` - Complex reasoning (llama3, claude-sonnet-4, gpt-4o, gemini-pro)\n- `cheap` - Cost-optimized (local models first, then cloud)\n- `long-context` - Large context windows (claude-sonnet, gpt-4-turbo, gemini-pro [1M tokens])\n\n### Provider Management\n\n```bash\n# List all configured providers with status\nspecular provider list\n\n# Example output:\n# NAME         TYPE   ENABLED   SOURCE    VERSION\n# ----         ----   -------   ------    -------\n# ollama       cli    yes       local     1.0.0\n# openai       api    yes       builtin   1.0.0\n# anthropic    api    yes       builtin   1.0.0\n# gemini       api    no        builtin   1.0.0\n# claude-code   cli    no        local     1.0.0\n\n# Check health of all configured providers\nspecular provider doctor\n\n# Check specific provider\nspecular provider doctor ollama\n\n# Example output:\n# PROVIDER   STATUS      MESSAGE\n# --------   ------      -------\n# ollama     ✅ HEALTHY   Executable provider: ./providers/ollama/ollama-provider\n\n# Remove a provider\nspecular provider remove gemini\n```\n\n### Provider Configuration\n\nProviders are configured in `.specular/providers.yaml`:\n\n```yaml\nproviders:\n  # Local Ollama provider (free, requires ollama installed)\n  - name: ollama\n    type: cli\n    enabled: true\n    source: local\n    config:\n      path: ./providers/ollama/ollama-provider\n      capabilities:\n        streaming: false\n        tools: false\n        multi_turn: true\n        max_context_tokens: 8192\n    models:\n      fast: llama3.2\n      codegen: codellama\n      agentic: llama3\n\n  # OpenAI API provider (requires OPENAI_API_KEY)\n  - name: openai\n    type: api\n    enabled: false\n    config:\n      api_key: ${OPENAI_API_KEY}\n      base_url: https://api.openai.com/v1\n    models:\n      fast: gpt-4o-mini\n      codegen: gpt-4o\n      long-context: gpt-4-turbo\n\n# Provider selection strategy\nstrategy:\n  preference:\n    - ollama      # Try local first (fastest, free)\n    - anthropic   # Then cloud APIs\n    - openai\n\n  budget:\n    max_cost_per_day: 20.0  # USD\n    max_cost_per_request: 1.0\n\n  performance:\n    max_latency_ms: 60000  # 60 seconds\n    prefer_cheap: true     # Prefer cheaper models when quality is similar\n```\n\nFor detailed provider documentation, see [internal/provider/README.md](internal/provider/README.md).\n\n## Quick Start\n\n### Step 1: Initialize Governance Workspace\n\nSpecular uses a governance-first approach. Start by initializing your workspace:\n\n```bash\n# Initialize governance workspace structure\nspecular governance init\n\n# This creates:\n# .specular/approvals/  - Approval records for plans, builds, drift\n# .specular/bundles/    - Build bundles with metadata\n# .specular/traces/     - Execution trace logs\n# .specular/policies.yaml   - Policy configuration\n# .specular/providers.yaml  - Provider configuration\n```\n\n### Step 2: Configure AI Providers\n\nAdd an AI provider to generate specifications and plans:\n\n```bash\n# Check available providers\nspecular provider list\n\n# Add a provider (example: Anthropic)\nspecular provider add anthropic --api-key $ANTHROPIC_API_KEY\n\n# Verify provider health\nspecular provider doctor\n\n# Set as default provider\nspecular provider set-default anthropic\n```\n\n### Step 3: Generate Specification\n\nCreate a specification using interview mode:\n\n```bash\n# List available presets (web-app, api-service, cli-tool, microservice, data-pipeline)\nspecular spec new --list\n\n# Run interactive TUI interview (recommended)\nspecular spec new --preset cli-tool --out .specular/spec.yaml --tui\n\n# Review the generated specification\ncat .specular/spec.yaml\n\n# Validate the specification\nspecular spec validate --in .specular/spec.yaml\n\n# Generate SpecLock with blake3 hashes for drift detection\nspecular spec lock --in .specular/spec.yaml --out .specular/spec.lock.json\n```\n\n### Step 4: Create Execution Plan\n\nGenerate an execution plan from your specification:\n\n```bash\n# Create execution plan from spec\nspecular plan create --in .specular/spec.yaml --lock .specular/spec.lock.json --out plan.json\n\n# Visualize task dependencies\nspecular plan visualize --plan plan.json\n\n# Validate plan structure\nspecular plan validate --plan plan.json\n```\n\n### Step 5: Execute with Policy Enforcement\n\nRun the build in a sandboxed Docker environment:\n\n```bash\n# Execute build with policy enforcement (dry-run first)\nspecular build run --plan plan.json --policy .specular/policies.yaml --dry-run\n\n# Run actual build\nspecular build run --plan plan.json --policy .specular/policies.yaml\n\n# Verify build quality gates\nspecular build verify --bundle .specular/bundles/latest.tar\n\n# Approve build for deployment\nspecular build approve --bundle .specular/bundles/latest.tar\n```\n\n### Step 6: Detect and Manage Drift\n\nMonitor drift between spec, plan, and implementation:\n\n```bash\n# Run drift detection (plan + code + infrastructure)\nspecular eval drift --plan plan.json --lock .specular/spec.lock.json \\\n  --spec .specular/spec.yaml --policy .specular/policies.yaml \\\n  --report drift.sarif\n\n# Approve detected drift with justification\nspecular drift approve --report drift.sarif --justification \"Approved architectural change\"\n```\n\n### Alternative: Quick Example Workflow\n\nIf you prefer to start with example files:\n\n```bash\n# Use example files\ncp .specular/spec.yaml.example .specular/spec.yaml\ncp .specular/policy.yaml.example .specular/policies.yaml\n\n# Follow Steps 4-6 above with the example spec\n```\n\n### Core Features\n\n✅ **Interactive TUI Mode**\n- Beautiful terminal UI powered by bubbletea\n- Real-time progress tracking with progress bars\n- Visual question navigation\n- Answer validation with immediate feedback\n- Answer history with up/down arrow navigation\n- Strict and non-strict validation modes\n- Seamless integration with interview command (`--tui` flag)\n\n✅ **Enhanced Error System**\n- Structured errors with hierarchical error codes (CATEGORY-NNN format)\n- 8 error categories: SPEC, POLICY, PLAN, INTERVIEW, PROVIDER, EXEC, DRIFT, IO\n- Actionable suggestions for every error\n- Documentation links for detailed guidance\n- Fluent API for error building with method chaining\n- Go 1.13+ error wrapping support for `errors.Is()` and `errors.As()`\n- Beautiful formatted error messages with bullet points\n\n✅ **CLI Provider Protocol**\n- Language-agnostic JSON-based stdin/stdout protocol\n- Three required commands: generate, stream, health\n- Support for streaming with newline-delimited JSON (NDJSON)\n- Protocol specification and examples in the [Provider Guide](docs/provider-guide.md)\n- Example router configuration in `.specular/router.example.yaml`\n- Reference implementation with ollama provider\n- Easy integration with ExecutableProvider adapter\n\n✅ **AI Provider Plugin System** (Phase 1 Complete)\n- Pluggable provider architecture (CLI executables, API clients, gRPC, native Go plugins)\n- Provider registry with lifecycle management\n- Support for local models (Ollama), cloud APIs (OpenAI, Anthropic, Gemini), and custom providers\n- Full streaming support for all API providers via Server-Sent Events (SSE)\n- Native Go HTTP clients for all three major cloud providers\n- Provider health checking and capability discovery\n- YAML-based provider configuration with environment variable expansion\n- Automatic provider loading from configuration\n- Trust levels (builtin, verified, community) for security\n\n✅ **Intelligent Model Router**\n- Multi-model selection based on task complexity, priority, and hints\n- Budget tracking and cost management ($0.00 for local models)\n- Model selection by hint (codegen, agentic, long-context, fast, cheap)\n- Latency-aware routing with configurable constraints\n- Provider preference ordering (try local first, then cloud)\n- Dynamic model availability based on loaded providers\n- Usage statistics and detailed reporting\n- **Retry with exponential backoff** - Automatic retry of failed requests with increasing delays\n- **Provider fallback** - Cascades to alternative providers when primary fails\n- **Context window management** - Validates requests fit model limits, optional auto-truncation with 4 strategies\n\n✅ **Generate Command**\n- Direct AI content generation from CLI\n- Automatic model selection based on task characteristics\n- Support for system prompts and temperature control\n- Verbose mode with detailed metadata (model, tokens, cost, latency, selection reason)\n- Streaming support for compatible providers\n- Error handling with helpful messages\n\n✅ **Interview Mode**\n- Guided Q\u0026A to generate specifications\n- 5 preset templates (web-app, api-service, cli-tool, microservice, data-pipeline)\n- Automatic spec generation from answers\n- Question skip logic based on previous answers\n- Strict validation mode\n\n✅ **Spec Management**\n- Validate YAML specifications\n- Generate SpecLock with blake3 hashes\n- Load/save specs and locks\n\n✅ **Plan Generation**\n- Convert specs to task DAGs\n- Automatic dependency inference based on priority (P0 → P1 → P2)\n- Skill assignment (go-backend, ui-react, infra, database, testing)\n- Model hints (long-context, agentic, codegen)\n- Complexity estimation (1-10 scale)\n\n✅ **Build Execution**\n- Docker-only sandbox execution\n- Policy enforcement (image allowlist, network isolation, resource limits)\n- Dependency-aware task execution\n- Run manifest generation with SHA-256 hashes\n- Dry-run mode for validation\n- Real Docker execution with image pulling\n\n✅ **Drift Detection**\n- Plan drift (hash mismatches)\n- Code drift (test coverage, API conformance, file tracking)\n- Infrastructure drift (policy compliance, resource validation)\n- OpenAPI 3.x contract validation\n- Endpoint and method verification\n- Path parameter matching\n- Docker image allowlist validation (exact, wildcard, prefix matching)\n- Execution policy validation (network, resources, tests, security)\n- Run manifest validation\n- SARIF 2.1.0 report generation\n- Error/warning/info severity levels\n- CI/CD integration ready\n\n✅ **Policy Engine**\n- YAML-based policy configuration\n- Docker-only enforcement\n- Image allowlist with wildcard patterns (e.g., `golang:*`)\n- Network mode validation (default: none)\n- Resource limits (CPU, memory)\n- Tool configuration validation\n\n✅ **Eval Gate**\n- Automated quality gate with policy enforcement\n- Test execution with race detection and coverage analysis\n- Coverage threshold validation (enforce minimum coverage requirements)\n- Multi-language linter integration (Go, JavaScript, Python)\n- Secrets scanning with gitleaks\n- Dependency vulnerability scanning\n- Comprehensive reporting with pass/fail status\n- Early failure detection (fail fast on quality issues)\n\n✅ **Test Coverage**\n- 81.4% - 100% across packages (policy: 100%, drift: 92.4%, plan: 91.6%, interview: 89.1%, spec: 87.8%, exec: 87.1%, eval: 85.0%, provider: 81.4%, router: 80.4%)\n- Race detection enabled\n- Table-driven test patterns\n- End-to-end integration test\n- Interview flow testing\n- Model selection and budget tests\n- Code drift and OpenAPI validation tests\n- Infrastructure drift and policy compliance tests\n- SARIF report generation and round-trip verification tests\n- Eval gate integration tests (RunEvalGate with tests, coverage, Go/JavaScript/Python linters, secrets scan, dependency scan, multi-linter scenarios, failing linter scenarios)\n- Eval test runner tests (Go test execution, coverage validation, linter integration, secrets scanning with gitleaks integration)\n- Exec package tests (executor orchestration, Docker runner, policy enforcement, manifest generation, image pulling with automatic image pull on first use, image existence checks)\n- Policy package tests (YAML loading, validation, default policy, error handling)\n- Interview package tests (spec generation, answer helpers, goals/features/milestones builders, completion flow)\n- Spec package tests (spec loading/saving, lock generation/loading/saving, round-trip verification, Hash and sortKeys function tests with nested maps and slices, canonicalize with multiple APIs and edge cases)\n- Router package tests (config loading/validation/saving, model selection helpers, budget tracking, cheaper model search, provider integration, model availability, SelectModel with providers)\n- Provider package tests (configuration loading/validation/saving, registry operations, executable provider lifecycle, OpenAI, Anthropic, and Gemini API providers with mock HTTP servers, streaming support with SSE, role mapping, error handling, health checks, integration tests for all four provider types - CLI/OpenAI/Anthropic/Gemini, multi-provider registry, config round-trip)\n- Plan package tests (plan loading/saving, round-trip verification, JSON parsing, file I/O error handling)\n\n## Exit Codes\n\nSpecular uses specific exit codes to communicate different types of errors, making it easier to handle errors programmatically in scripts and CI/CD pipelines.\n\n| Code | Name | Description |\n|------|------|-------------|\n| 0 | Success | Execution completed successfully |\n| 1 | General Error | Unexpected runtime error occurred |\n| 2 | Usage Error | Invalid CLI usage (bad flags, missing arguments) |\n| 3 | Policy Violation | Operation blocked by policy rules |\n| 4 | Drift Detected | Specification drift detected, requires intervention |\n| 5 | Authentication Error | Authentication or permission failure |\n| 6 | Network Error | Network connectivity issue |\n\n### Usage in Scripts\n\n```bash\n#!/bin/bash\nspecular auto \"Build REST API\"\nEXIT_CODE=$?\n\ncase $EXIT_CODE in\n  0)\n    echo \"✅ Success\"\n    ;;\n  2)\n    echo \"❌ Usage error - check your command\"\n    exit 1\n    ;;\n  3)\n    echo \"❌ Policy violation - operation not allowed\"\n    exit 1\n    ;;\n  4)\n    echo \"⚠️  Drift detected - manual intervention required\"\n    exit 1\n    ;;\n  5)\n    echo \"❌ Authentication error - check credentials\"\n    exit 1\n    ;;\n  6)\n    echo \"❌ Network error - check connectivity\"\n    exit 1\n    ;;\n  *)\n    echo \"❌ Unexpected error (code: $EXIT_CODE)\"\n    exit 1\n    ;;\nesac\n```\n\n### CI/CD Integration\n\nExit codes enable intelligent error handling in CI/CD pipelines:\n\n```yaml\n# GitHub Actions example\n- name: Run Specular\n  id: specular\n  run: specular auto \"Deploy application\"\n  continue-on-error: true\n\n- name: Handle Specular errors\n  if: failure()\n  run: |\n    EXIT_CODE=${{ steps.specular.outputs.exit_code }}\n    if [ \"$EXIT_CODE\" = \"3\" ]; then\n      echo \"Policy violation - requires approval\"\n      # Trigger approval workflow\n    elif [ \"$EXIT_CODE\" = \"4\" ]; then\n      echo \"Drift detected - requires manual intervention\"\n      # Create issue for manual review\n    elif [ \"$EXIT_CODE\" = \"6\" ]; then\n      echo \"Network error - retrying...\"\n      # Retry logic\n    fi\n```\n\n## Per-Step Policy Enforcement\n\nSpecular's autonomous mode includes per-step policy checking to enforce safety guardrails and organizational constraints before each workflow step executes.\n\n### Policy Checking Architecture\n\nPolicy checks run automatically before each action step in the autonomous workflow. The policy system supports:\n\n- **Cost Limits** - Per-step and total budget enforcement\n- **Timeouts** - Workflow and per-step duration limits\n- **Step Type Control** - Whitelist/blacklist for step types (spec:update, plan:gen, build:run)\n- **Step Count Limits** - Maximum number of steps allowed\n- **Retry Limits** - Maximum retries per failed step\n\n### Profile-Based Policies\n\nPolicies are configured per profile, allowing different constraints for different environments:\n\n```yaml\n# .claude/profiles/strict.yaml\nname: strict\ndescription: Maximum safety profile with strict limits\n\nsafety:\n  max_cost_usd: 5.0          # Total workflow budget\n  max_cost_per_task: 1.0     # Per-step cost limit\n  max_steps: 10              # Maximum number of steps\n  max_retries: 2             # Maximum retries per step\n  timeout: 30m               # Total workflow timeout\n\n  # Step type restrictions\n  allowed_step_types:        # Whitelist (empty = all allowed)\n    - \"spec:update\"\n    - \"spec:lock\"\n    - \"plan:gen\"\n  blocked_step_types:        # Blacklist (takes precedence)\n    - \"build:run\"            # Block execution steps\n```\n\n### Built-in Policy Checkers\n\n**CostLimitChecker**: Enforces budget constraints\n- Checks per-step cost estimates against limits\n- Tracks total cost across workflow execution\n- Warns when approaching 80% of budget\n\n**TimeoutChecker**: Enforces duration constraints\n- Validates sufficient time remains for steps\n- Checks total workflow duration\n- Warns when approaching 80% of timeout\n\n**StepTypeChecker**: Controls allowed operations\n- Whitelist-based step type validation\n- Blacklist overrides whitelist\n- Prevents unauthorized step types from executing\n\n**MaxStepsChecker**: Limits workflow complexity\n- Enforces maximum step count\n- Prevents runaway workflows\n- Warns when approaching limit\n\n**MaxRetriesChecker**: Controls failure retry behavior\n- Tracks retries per step ID\n- Prevents infinite retry loops\n- Enforced per-step across workflow\n\n### Policy Check Flow\n\n```\n1. Orchestrator prepares to execute step\n2. Policy context created (completed steps, cost, time elapsed)\n3. All configured policy checkers run sequentially\n4. If ANY checker denies:\n   - Execution stops for that step\n   - Error returned with exit code 3 (Policy Violation)\n   - Audit event logged with denial reason\n5. If ALL checkers allow:\n   - Warnings collected and logged\n   - Step execution proceeds\n```\n\n### Policy Violation Handling\n\nWhen a policy check fails:\n\n```bash\n# Policy violation example\n$ specular auto \"Build complex system\"\n\nStep 3: Generate implementation plan\n❌ Policy violation: maximum step count exceeded: 11 \u003e 10 limit\n\n# Returns exit code 3\n$ echo $?\n3\n```\n\nPolicy violations return exit code 3 and include:\n- **Checker name** - Which policy failed (e.g., \"max_steps\")\n- **Reason** - Clear explanation of violation\n- **Metadata** - Additional context (current count, limits, etc.)\n- **Audit trail** - All policy checks logged for compliance\n\n### Using Policies\n\n**Default profile** (balanced):\n```bash\nspecular auto \"Create REST API\"\n# Uses default profile with moderate limits\n```\n\n**Strict profile** (maximum safety):\n```bash\nspecular auto --profile strict \"Create REST API\"\n# Enforces strict cost, step, and timeout limits\n```\n\n**CI profile** (automated):\n```bash\nspecular auto --profile ci \"Run automated workflow\"\n# Non-interactive, auto-approve, JSON output\n```\n\n**Custom profile**:\n```bash\n# Create custom profile\ncat \u003e .claude/profiles/custom.yaml \u003c\u003cEOF\nname: custom\nsafety:\n  max_cost_usd: 10.0\n  max_steps: 20\n  timeout: 1h\n  blocked_step_types:\n    - \"build:run\"  # Only planning, no execution\nEOF\n\nspecular auto --profile custom \"Plan system architecture\"\n```\n\n**CLI Overrides** (override profile settings):\n```bash\n# Override max steps limit\nspecular auto --max-steps 15 \"Create REST API\"\n\n# Override multiple safety limits\nspecular auto --max-steps 20 --max-cost 15.0 --timeout 90 \"Complex workflow\"\n\n# Override with profile\nspecular auto --profile ci --max-steps 10 \"Quick deployment\"\n```\n\nAvailable CLI overrides:\n- `--max-steps \u003cn\u003e` - Maximum number of workflow steps\n- `--max-cost \u003cusd\u003e` - Maximum total cost in USD\n- `--max-cost-per-task \u003cusd\u003e` - Maximum cost per individual task\n- `--max-retries \u003cn\u003e` - Maximum retries per failed task\n- `--timeout \u003cminutes\u003e` - Total workflow timeout in minutes\n\n### Policy Bypass\n\nPolicies cannot be bypassed in autonomous mode for security. To execute steps that violate policy:\n\n1. **Adjust profile limits** - Increase cost/step/timeout limits\n2. **Remove restrictions** - Clear blocked_step_types list\n3. **Manual mode** - Use non-autonomous commands without policy enforcement\n\n### Testing Policy Checks\n\n```go\n// Example: Testing custom policy checker\nfunc TestCustomPolicy(t *testing.T) {\n    checker := \u0026CustomPolicyChecker{}\n\n    step := \u0026auto.ActionStep{\n        ID:   \"test-step\",\n        Type: auto.StepTypeBuildRun,\n    }\n\n    result, err := checker.CheckStep(context.Background(), step)\n    if err != nil {\n        t.Fatal(err)\n    }\n\n    if !result.Allowed {\n        t.Errorf(\"Expected step to be allowed: %s\", result.Reason)\n    }\n}\n```\n\n## Interactive TUI Mode\n\nSpecular's autonomous mode features an interactive terminal UI (TUI) powered by Bubble Tea, providing real-time visualization of workflow execution with progress tracking, step history, and hotkey navigation.\n\n### Enabling TUI Mode\n\nEnable interactive TUI with the `--tui` flag:\n\n```bash\n# Run with interactive TUI\nspecular auto --tui \"Create REST API\"\n\n# Combine with profiles\nspecular auto --tui --profile strict \"Build microservice\"\n```\n\n### TUI Features\n\n**Real-Time Progress Tracking**:\n- Live progress bar showing completion percentage\n- Current step display with status icons\n- Execution statistics (completed, pending, failed tasks)\n- Real-time cost tracking\n- Elapsed time display\n\n**Multiple Views**:\n- **Main View** (`default`) - Progress overview with current step and statistics\n- **Step List View** (`s` key) - All steps with status icons and types\n- **Help View** (`?` key) - Hotkey reference and navigation guide\n- **Approval View** (automatic) - Interactive approval prompts\n\n**Interactive Hotkeys**:\n- `?` - Toggle help view\n- `s` - Toggle step list view\n- `v` - Toggle verbose mode\n- `y` / `Enter` - Approve plan (during approval)\n- `n` / `Esc` - Reject plan (during approval)\n- `q` - Quit TUI\n- `Ctrl+C` - Force quit\n\n### TUI Output Example\n\n```\n🤖 Specular Auto Mode\n\nGoal:  Create REST API with authentication\n\nProfile: default\n\n┌──────────────────────────────────────────────┐\n│ ⟳ Progress                                   │\n│                                              │\n│ [████████████████████░░░░░░░░░░] 12/15 (80%)│\n│                                              │\n│ Completed: 12                                │\n│ Pending:   3                                 │\n│ Cost:      $2.5000                           │\n│ Elapsed:   2m 15s                            │\n└──────────────────────────────────────────────┘\n\nCurrent Step: Generate authentication middleware\n\n? help • s steps • v verbose • q quit\n```\n\n### TUI Architecture\n\nThe TUI integrates with the orchestrator through the hooks system:\n\n1. **Hook Registration** - TUI hook registered with orchestrator's hook registry\n2. **Event Forwarding** - Orchestrator lifecycle events forwarded to TUI adapter\n3. **Real-Time Updates** - Step start/complete/fail events update TUI state\n4. **Approval Flow** - Interactive approval requests handled through TUI\n\nSupported orchestrator events:\n- `on_workflow_start` - Workflow initialization\n- `on_step_before` - Step execution begins\n- `on_step_after` - Step execution completes\n- `on_step_failed` - Step execution fails\n- `on_workflow_complete` - Workflow succeeds\n- `on_workflow_failed` - Workflow fails\n\n### TUI Best Practices\n\n1. **Use for Interactive Sessions** - TUI is ideal for development and debugging\n2. **Combine with Profiles** - Use `--tui --profile strict` for safe exploration\n3. **Step List Navigation** - Press `s` to review all steps and their statuses\n4. **Verbose Mode** - Toggle `v` for detailed execution logs\n5. **CI/CD Pipelines** - Use `--json` instead of `--tui` for automation\n\n### TUI vs Text Mode\n\n| Feature | TUI Mode | Text Mode |\n|---------|----------|-----------|\n| **Interface** | Interactive UI with navigation | Sequential log output |\n| **Progress** | Real-time progress bar | Periodic status updates |\n| **Navigation** | Hotkeys to switch views | N/A |\n| **Approval** | Interactive prompt with hotkeys | Terminal input prompt |\n| **Best For** | Interactive dev sessions | CI/CD, scripting, logs |\n\n## Trace Logging\n\nSpecular's autonomous mode provides detailed trace logging to `~/.specular/logs/` for debugging, auditing, and compliance. Trace logs capture all workflow events with timestamps, context, and structured data in JSON format.\n\n### Enabling Trace Logging\n\nEnable trace logging with the `--trace` flag:\n\n```bash\n# Run with trace logging\nspecular auto --trace \"Create REST API\"\n\n# Combine with other flags\nspecular auto --trace --profile strict --tui \"Build microservice\"\n\n# Output shows log file location\n📝 Trace logging enabled: /Users/user/.specular/logs/trace_auto-1234567890.json\n```\n\n### Trace Log Format\n\nTrace logs are written as newline-delimited JSON (NDJSON) with one event per line:\n\n```json\n{\n  \"id\": \"20240115120000.123456\",\n  \"type\": \"workflow_start\",\n  \"timestamp\": \"2024-01-15T12:00:00Z\",\n  \"workflow_id\": \"auto-1234567890\",\n  \"message\": \"Workflow started\",\n  \"level\": \"info\",\n  \"data\": {\n    \"goal\": \"Create REST API\",\n    \"profile\": \"default\"\n  }\n}\n```\n\n### Event Types\n\nThe trace logger captures 12 types of events:\n\n**Workflow Events**:\n- `workflow_start` - Workflow execution begins\n- `workflow_complete` - Workflow finishes successfully\n\n**Step Events**:\n- `step_start` - Step execution begins\n- `step_complete` - Step finishes successfully (includes duration and cost)\n- `step_fail` - Step fails with error details\n\n**Policy Events**:\n- `policy_check` - Policy checker evaluates a step (includes allowed/denied reason)\n\n**Approval Events**:\n- `approval_request` - Approval requested from user\n- `approval_response` - User approves or rejects plan\n\n**Budget Events**:\n- `budget_check` - Budget limits checked\n\n**General Events**:\n- `error` - Error occurred during execution\n- `warning` - Warning issued\n- `info` - Informational message\n\n### Event Structure\n\nEach trace event contains:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `id` | string | Unique event identifier (timestamp-based) |\n| `type` | string | Event type (see above) |\n| `timestamp` | string | ISO 8601 timestamp when event occurred |\n| `workflow_id` | string | Workflow identifier (e.g., `auto-1234567890`) |\n| `step_id` | string | Step identifier (for step-related events) |\n| `message` | string | Human-readable description |\n| `level` | string | Severity level: `info`, `warning`, or `error` |\n| `data` | object | Event-specific structured data |\n| `duration` | number | Duration in nanoseconds (for timed events) |\n| `error` | string | Error message (for error events) |\n| `context` | object | Workflow context (goal, profile, progress, cost) |\n\n### Event Context\n\nStep and workflow events include rich context:\n\n```json\n{\n  \"context\": {\n    \"goal\": \"Create REST API\",\n    \"profile\": \"default\",\n    \"completed_steps\": 3,\n    \"total_steps\": 5,\n    \"total_cost\": 1.25,\n    \"elapsed_time\": 120000000000\n  }\n}\n```\n\n### Log Rotation\n\nTrace logs automatically rotate when they reach 10MB:\n\n- **Max File Size**: 10MB (configurable)\n- **Max Files**: 5 rotated files kept (configurable)\n- **Rotation Format**: `trace_\u003cworkflow_id\u003e_\u003ctimestamp\u003e.json`\n- **Cleanup**: Oldest files automatically removed\n\nExample rotated files:\n```\n~/.specular/logs/\n├── trace_auto-1234567890.json           # Current log\n├── trace_auto-1234567890_20240115_120000.json  # Rotated\n└── trace_auto-1234567890_20240115_110000.json  # Rotated\n```\n\n### Use Cases\n\n**1. Debugging Failed Workflows**\n```bash\n# Run with trace logging\nspecular auto --trace \"Complex task\"\n\n# Analyze trace log if something fails\ncat ~/.specular/logs/trace_auto-*.json | \\\n  jq 'select(.level == \"error\" or .level == \"warning\")'\n```\n\n**2. Performance Analysis**\n```bash\n# Extract step durations\ncat ~/.specular/logs/trace_auto-*.json | \\\n  jq 'select(.type == \"step_complete\") | {step: .step_id, duration: .duration}'\n\n# Calculate total cost per step\ncat ~/.specular/logs/trace_auto-*.json | \\\n  jq 'select(.data.cost) | {step: .step_id, cost: .data.cost}'\n```\n\n**3. Compliance Auditing**\n```bash\n# Extract all policy checks\ncat ~/.specular/logs/trace_auto-*.json | \\\n  jq 'select(.type == \"policy_check\") | {step: .step_id, allowed: .data.allowed, reason: .data.reason}'\n\n# Extract approval decisions\ncat ~/.specular/logs/trace_auto-*.json | \\\n  jq 'select(.type == \"approval_response\") | {approved: .data.approved, timestamp}'\n```\n\n**4. Cost Tracking**\n```bash\n# Sum total workflow cost\ncat ~/.specular/logs/trace_auto-*.json | \\\n  jq 'select(.type == \"step_complete\") | .data.cost' | \\\n  awk '{sum+=$1} END {printf \"Total Cost: $%.2f\\n\", sum}'\n```\n\n### Best Practices\n\n1. **Enable for Debugging** - Use `--trace` when investigating issues or unexpected behavior\n2. **Combine with TUI** - Use `--trace --tui` for visual monitoring + detailed logs\n3. **Archive Important Runs** - Copy trace logs for production deployments or critical workflows\n4. **Parse with jq** - Use jq for powerful log analysis and filtering\n5. **Monitor Disk Usage** - Trace logs can grow large; rotation limits disk usage\n6. **CI/CD Integration** - Enable `--trace` in CI/CD pipelines for build failure analysis\n\n### Programmatic Access\n\nAccess trace events programmatically in Go:\n\n```go\nimport \"github.com/felixgeelhaar/specular/internal/trace\"\n\n// Create logger\nconfig := trace.DefaultConfig()\nconfig.Enabled = true\nlogger, err := trace.NewLogger(config)\n\n// Log events\nlogger.LogWorkflowStart(\"Build API\", \"default\")\nlogger.LogStepStart(\"step-1\", \"Generate Specification\")\nlogger.LogStepComplete(\"step-1\", \"Generate Specification\", duration, 0.50)\n\n// Access events in memory\nevents := logger.GetEvents()\nfor _, event := range events {\n    fmt.Printf(\"%s: %s\\n\", event.Type, event.Message)\n}\n\n// Close logger (flushes to disk)\nlogger.Close()\n```\n\n### Trace vs Other Outputs\n\n| Feature | Trace Logging | JSON Output | TUI Mode |\n|---------|---------------|-------------|----------|\n| **Format** | NDJSON events | Single JSON doc | Interactive UI |\n| **Granularity** | All events with timestamps | Final results only | Real-time status |\n| **Use Case** | Debugging, auditing | CI/CD integration | Interactive dev |\n| **File Output** | `~/.specular/logs/` | stdout or file | Terminal only |\n| **Readability** | Machine (jq required) | Machine + Human | Human-friendly |\n| **Performance** | Minimal overhead | No overhead | Minimal overhead |\n\n## JSON Output Format\n\nSpecular's autonomous mode supports structured JSON output for CI/CD integration and programmatic result processing. The JSON format captures complete execution state including steps, artifacts, metrics, and audit trail.\n\n### Enabling JSON Output\n\nEnable JSON output with the `--json` flag:\n\n```bash\n# Output to stdout\nspecular auto --json \"Create REST API\" \u003e result.json\n\n# Use in CI/CD pipeline\nspecular auto --json --profile ci \"Deploy to staging\"\n```\n\n### JSON Schema\n\nThe JSON output follows the `specular.auto.output/v1` schema:\n\n```json\n{\n  \"schema\": \"specular.auto.output/v1\",\n  \"goal\": \"Create REST API\",\n  \"status\": \"completed\",\n  \"steps\": [\n    {\n      \"id\": \"step-1\",\n      \"type\": \"spec:update\",\n      \"status\": \"completed\",\n      \"startedAt\": \"2024-01-15T10:00:00Z\",\n      \"completedAt\": \"2024-01-15T10:00:05Z\",\n      \"duration\": 5000000000,\n      \"costUSD\": 0.50,\n      \"warnings\": []\n    }\n  ],\n  \"artifacts\": [\n    {\n      \"path\": \"spec.yaml\",\n      \"type\": \"spec\",\n      \"size\": 2048,\n      \"hash\": \"sha256:abc123...\",\n      \"createdAt\": \"2024-01-15T10:00:05Z\"\n    }\n  ],\n  \"metrics\": {\n    \"totalDuration\": 19000000000,\n    \"totalCost\": 1.81,\n    \"stepsExecuted\": 4,\n    \"stepsFailed\": 0,\n    \"stepsSkipped\": 0,\n    \"policyViolations\": 0\n  },\n  \"audit\": {\n    \"checkpointId\": \"auto-1705315200\",\n    \"profile\": \"default\",\n    \"startedAt\": \"2024-01-15T10:00:00Z\",\n    \"completedAt\": \"2024-01-15T10:00:19Z\",\n    \"approvals\": [],\n    \"policies\": [\n      {\n        \"stepId\": \"step-1\",\n        \"timestamp\": \"2024-01-15T10:00:00Z\",\n        \"checkerName\": \"cost_limit\",\n        \"allowed\": true,\n        \"warnings\": [\"approaching 50% of budget\"]\n      }\n    ],\n    \"version\": \"v1.4.0\"\n  }\n}\n```\n\n### Schema Fields\n\n**Top-Level Structure:**\n- `schema` (string) - Format version identifier (`specular.auto.output/v1`)\n- `goal` (string) - User's original objective\n- `status` (string) - Execution outcome: `completed`, `failed`, or `partial`\n- `steps` (array) - Results for each executed step\n- `artifacts` (array) - Generated files and outputs\n- `metrics` (object) - Execution statistics\n- `audit` (object) - Provenance and compliance information\n\n**Step Result:**\n- `id` (string) - Unique step identifier (`step-1`, `step-2`, etc.)\n- `type` (string) - Step category: `spec:update`, `spec:lock`, `plan:gen`, `build:run`\n- `status` (string) - Step outcome: `pending`, `in_progress`, `completed`, `failed`, `skipped`\n- `startedAt` (timestamp) - When step execution began\n- `completedAt` (timestamp) - When step execution finished\n- `duration` (nanoseconds) - Time taken to execute the step\n- `costUSD` (float) - Estimated cost for this step in USD\n- `error` (string, optional) - Error message if step failed\n- `warnings` (array, optional) - Non-fatal issues encountered\n- `metadata` (object, optional) - Step-specific additional information\n\n**Artifact Info:**\n- `path` (string) - File path relative to project root\n- `type` (string) - Artifact category: `spec`, `lock`, `plan`, `code`, `test`, etc.\n- `size` (int64) - File size in bytes\n- `hash` (string) - Content verification hash (SHA256)\n- `createdAt` (timestamp) - When artifact was created\n\n**Execution Metrics:**\n- `totalDuration` (nanoseconds) - Complete workflow execution time\n- `totalCost` (float) - Sum of all step costs in USD\n- `stepsExecuted` (int) - Count of steps that ran\n- `stepsFailed` (int) - Count of steps that failed\n- `stepsSkipped` (int) - Count of steps that were skipped\n- `policyViolations` (int) - Count of policy check failures\n- `tokensUsed` (int, optional) - Total token consumption\n- `retriesPerformed` (int, optional) - Total retry attempts\n\n**Audit Trail:**\n- `checkpointId` (string) - Execution checkpoint identifier\n- `profile` (string) - Profile used for execution\n- `startedAt` (timestamp) - Workflow start time\n- `completedAt` (timestamp) - Workflow completion time\n- `user` (string, optional) - User who initiated the workflow\n- `hostname` (string, optional) - Hostname where execution occurred\n- `approvals` (array) - Approval events during execution\n- `policies` (array) - Policy check events\n- `version` (string, optional) - Specular version used\n\n**Policy Event:**\n- `stepId` (string) - Step that was checked\n- `timestamp` (timestamp) - When check occurred\n- `checkerName` (string) - Which policy checker ran\n- `allowed` (boolean) - Whether policy check passed\n- `reason` (string, optional) - Policy decision explanation\n- `warnings` (array, optional) - Non-blocking policy warnings\n- `metadata` (object, optional) - Policy-specific additional information\n\n**Approval Event:**\n- `stepId` (string) - Step that required approval\n- `timestamp` (timestamp) - When approval occurred\n- `approved` (boolean) - Whether step was approved\n- `reason` (string, optional) - Why approval was required\n- `user` (string, optional) - Who approved\n\n### Status Values\n\nThe `status` field indicates the overall execution outcome:\n\n- **`completed`**: All steps executed successfully\n- **`failed`**: One or more steps failed\n- **`partial`**: Execution stopped due to policy violation or user interruption\n\n### CI/CD Integration Examples\n\n**GitHub Actions:**\n\n```yaml\nname: Auto Deploy\non: [push]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n\n      - name: Run Specular Auto\n        id: auto\n        run: |\n          specular auto --json --profile ci \"Deploy to staging\" \u003e result.json\n          echo \"status=$(jq -r .status result.json)\" \u003e\u003e $GITHUB_OUTPUT\n          echo \"cost=$(jq -r .metrics.totalCost result.json)\" \u003e\u003e $GITHUB_OUTPUT\n\n      - name: Check Status\n        if: steps.auto.outputs.status != 'completed'\n        run: |\n          echo \"Deployment failed or partial\"\n          jq '.steps[] | select(.status == \"failed\")' result.json\n          exit 1\n\n      - name: Report Metrics\n        run: |\n          echo \"Total cost: ${{ steps.auto.outputs.cost }}\"\n          echo \"Steps: $(jq .metrics.stepsExecuted result.json)\"\n          echo \"Duration: $(jq .metrics.totalDuration result.json | awk '{print $1/1000000000}')s\"\n```\n\n**GitLab CI:**\n\n```yaml\ndeploy:\n  script:\n    - specular auto --json --profile ci \"Deploy to production\" \u003e result.json\n    - |\n      STATUS=$(jq -r .status result.json)\n      if [ \"$STATUS\" != \"completed\" ]; then\n        echo \"Deployment $STATUS\"\n        jq '.steps[] | select(.status == \"failed\")' result.json\n        exit 1\n      fi\n    - |\n      COST=$(jq -r .metrics.totalCost result.json)\n      echo \"Deployment cost: \\$$COST\"\n  artifacts:\n    paths:\n      - result.json\n    reports:\n      junit: result.json\n```\n\n**Budget Monitoring:**\n\n```bash\n#!/bin/bash\n# Monitor and alert on costs\n\nspecular auto --json --profile ci \"$GOAL\" \u003e result.json\n\nCOST=$(jq -r .metrics.totalCost result.json)\nVIOLATIONS=$(jq -r .metrics.policyViolations result.json)\n\nif (( $(echo \"$COST \u003e 5.0\" | bc -l) )); then\n  echo \"⚠️  Cost $COST exceeds budget threshold\"\n  # Send alert to Slack/PagerDuty\nfi\n\nif [ \"$VIOLATIONS\" -gt 0 ]; then\n  echo \"🚫 Policy violations detected: $VIOLATIONS\"\n  jq '.audit.policies[] | select(.allowed == false)' result.json\nfi\n```\n\n**Progressive Deployment:**\n\n```bash\n#!/bin/bash\n# Progressive deployment with rollback on failure\n\nspecular auto --json --profile prod \"Deploy v2.0\" \u003e result.json\n\nSTATUS=$(jq -r .status result.json)\nFAILED_STEPS=$(jq -r .metrics.stepsFailed result.json)\n\nif [ \"$STATUS\" = \"completed\" ]; then\n  echo \"✅ Deployment successful\"\n  # Promote to 100% traffic\nelif [ \"$STATUS\" = \"partial\" ] \u0026\u0026 [ \"$FAILED_STEPS\" -eq 0 ]; then\n  echo \"⚠️  Partial deployment (policy stop)\"\n  # Keep at current traffic level\nelse\n  echo \"❌ Deployment failed\"\n  # Rollback to previous version\n  jq '.steps[] | select(.status == \"failed\")' result.json\n  exit 1\nfi\n```\n\n### Parsing JSON Output\n\n**Python:**\n\n```python\nimport json\nimport sys\n\nwith open('result.json') as f:\n    result = json.load(f)\n\nif result['status'] != 'completed':\n    print(f\"Execution {result['status']}\")\n    failed = [s for s in result['steps'] if s['status'] == 'failed']\n    for step in failed:\n        print(f\"  {step['id']}: {step.get('error', 'unknown error')}\")\n    sys.exit(1)\n\nprint(f\"Cost: ${result['metrics']['totalCost']:.2f}\")\nprint(f\"Duration: {result['metrics']['totalDuration'] / 1e9:.1f}s\")\nprint(f\"Steps: {result['metrics']['stepsExecuted']}\")\n```\n\n**jq Examples:**\n\n```bash\n# Get total cost\njq -r '.metrics.totalCost' result.json\n\n# List failed steps\njq '.steps[] | select(.status == \"failed\") | .id' result.json\n\n# Get policy violations\njq '.audit.policies[] | select(.allowed == false)' result.json\n\n# Calculate success rate\njq '.metrics.stepsExecuted / (.metrics.stepsExecuted + .metrics.stepsFailed)' result.json\n\n# Extract all artifacts\njq -r '.artifacts[].path' result.json\n\n# Get warnings from all steps\njq '.steps[].warnings[]?' result.json\n\n# Find most expensive step\njq '.steps | sort_by(-.costUSD) | .[0]' result.json\n```\n\n### Testing JSON Output\n\n```go\nfunc TestJSONOutputIntegration(t *testing.T) {\n    // Run with JSON output\n    cmd := exec.Command(\"specular\", \"auto\", \"--json\", \"--dry-run\", \"Test goal\")\n    output, err := cmd.Output()\n    if err != nil {\n        t.Fatalf(\"command failed: %v\", err)\n    }\n\n    // Parse JSON\n    var result auto.AutoOutput\n    if err := json.Unmarshal(output, \u0026result); err != nil {\n        t.Fatalf(\"invalid JSON: %v\", err)\n    }\n\n    // Verify schema\n    if result.Schema != \"specular.auto.output/v1\" {\n        t.Errorf(\"unexpected schema: %s\", result.Schema)\n    }\n\n    // Verify required fields\n    if result.Goal == \"\" {\n        t.Error(\"goal is empty\")\n    }\n    if result.Status == \"\" {\n        t.Error(\"status is empty\")\n    }\n\n    // Verify metrics\n    if result.Metrics.StepsExecuted != len(result.Steps) {\n        t.Errorf(\"metrics mismatch: executed=%d, steps=%d\",\n            result.Metrics.StepsExecuted, len(result.Steps))\n    }\n}\n```\n\n## Patch Generation and Rollback\n\nSpecular can generate patches for every step executed in auto mode, allowing you to safely rollback changes if something goes wrong. This provides an additional safety layer beyond git, enabling step-by-step recovery even during complex workflows.\n\n### What are Patches?\n\nA patch is a JSON file containing:\n- **File changes**: Unified diffs showing what changed\n- **Metadata**: Step ID, type, timestamp, workflow ID\n- **Content snapshots**: Full before/after file contents for reliable rollback\n- **Statistics**: Files changed, insertions, deletions\n\nPatches are saved to `~/.specular/patches/` with the naming format: `{workflow-id}_{step-id}.patch.json`\n\n### Enabling Patch Generation\n\nGenerate patches with the `--save-patches` flag:\n\n```bash\n# Generate patches during execution\nspecular auto --save-patches \"Migrate database schema\"\n\n# Patches are saved automatically after each step\n# 💾 Patch generation enabled: /Users/you/.specular/patches\n```\n\n### Patch File Format\n\nEach patch file contains detailed change information:\n\n```json\n{\n  \"stepId\": \"step-2\",\n  \"stepType\": \"exec:task\",\n  \"timestamp\": \"2025-01-11T14:30:00Z\",\n  \"workflowId\": \"auto-1762811730\",\n  \"description\": \"Update database schema\",\n  \"filesChanged\": 2,\n  \"insertions\": 15,\n  \"deletions\": 8,\n  \"files\": [\n    {\n      \"path\": \"migrations/001_users.sql\",\n      \"status\": \"modified\",\n      \"oldContent\": \"...\",\n      \"newContent\": \"...\",\n      \"diff\": \"--- a/migrations/001_users.sql\\n+++ b/migrations/001_users.sql\\n...\",\n      \"insertions\": 10,\n      \"deletions\": 5\n    },\n    {\n      \"path\": \"migrations/002_posts.sql\",\n      \"status\": \"added\",\n      \"newContent\": \"...\",\n      \"diff\": \"--- /dev/null\\n+++ b/migrations/002_posts.sql\\n...\",\n      \"insertions\": 5,\n      \"deletions\": 0\n    }\n  ]\n}\n```\n\n### File Statuses\n\nPatches track four types of file changes:\n\n| Status | Description | Rollback Action |\n|--------|-------------|----------------|\n| `added` | New file created | Delete the file |\n| `modified` | Existing file changed | Restore old content |\n| `deleted` | File removed | Recreate the file |\n| `renamed` | File moved/renamed | Rename back to original |\n\n### Rollback Commands\n\nThe `specular auto rollback` command provides several rollback options:\n\n#### List Available Patches\n\n```bash\n# See all patches for a workflow\nspecular auto rollback auto-1762811730 --list\n\n# Output:\n# 📋 Patches for workflow auto-1762811730:\n#\n#   step-1 (spec:generate)\n#     Generated product specification\n#     Files: 1, Changes: +50 -0\n#     Created: 2025-01-11 14:25:30\n#\n#   step-2 (exec:task)\n#     Update database schema\n#     Files: 2, Changes: +15 -8\n#     Created: 2025-01-11 14:30:00\n```\n\n#### Rollback a Single Step\n\n```bash\n# Rollback one specific step\nspecular auto rollback auto-1762811730 step-2\n\n# Output:\n# 🔄 Rolling back step: step-2\n# ✅ Successfully rolled back step: step-2\n```\n\n#### Rollback to a Specific Step\n\n```bash\n# Rollback all steps AFTER step-1 (keeping step-1's changes)\nspecular auto rollback auto-1762811730 --to step-1\n\n# Output:\n# 🔄 Rolling back to step: step-1\n#    (This will revert all steps after this one)\n#\n# 📊 Rollback Summary:\n#    Steps reverted: 3\n#\n# ✅ Rollback completed successfully\n```\n\n#### Rollback All Steps\n\n```bash\n# Rollback entire workflow (revert all changes)\nspecular auto rollback auto-1762811730 --all\n\n# Requires confirmation:\n# 🔄 Rolling back all steps for workflow: auto-1762811730\n#    ⚠️  This will revert all changes made by this workflow\n#\n# Are you sure? [y/N]: y\n```\n\n#### Dry-Run Mode\n\n```bash\n# Verify rollback safety without applying changes\nspecular auto rollback auto-1762811730 step-2 --dry-run\n\n# Output:\n# 🔄 Rolling back step: step-2\n#\n# ⚠️  Warnings:\n#    - file migrations/002_posts.sql has been modified since patch was created\n#\n# ✅ Dry-run complete. Use without --dry-run to apply rollback\n```\n\n### Rollback Safety Verification\n\nBefore applying a rollback, Specular verifies safety by checking:\n\n1. **File existence**: Are files still present (for modified/deleted files)?\n2. **Content drift**: Has the file been modified since the patch was created?\n3. **Conflicts**: Will the rollback cause data loss or conflicts?\n\nIf warnings are detected, you'll be prompted to confirm:\n\n```bash\nspecular auto rollback auto-1762811730 step-2\n\n# Output:\n# ⚠️  Warnings:\n#    - file database.sql has been modified since patch was created\n#\n# ⚠️  Rollback may not be safe due to conflicts\n# Use --dry-run to see details without applying changes\n#\n# Continue anyway? [y/N]:\n```\n\n### Use Cases\n\n**1. Incremental Recovery**\n\nRoll back specific failed steps without losing good changes:\n\n```bash\n# Step 3 failed, but steps 1-2 were successful\nspecular auto rollback auto-1762811730 step-3\n\n# Now you can fix the issue and re-run from step 3\n```\n\n**2. Testing Changes**\n\nTry changes in auto mode, then roll back if they don't work:\n\n```bash\n# Try changes\nspecular auto --save-patches \"Refactor authentication\"\n\n# Check if it works\nnpm test\n\n# Roll back if tests fail\nspecular auto rollback auto-1762811730 --all\n```\n\n**3. Partial Deployment**\n\nDeploy changes step-by-step, rolling back if issues arise:\n\n```bash\n# Deploy with patches enabled\nspecular auto --save-patches \"Deploy new API endpoints\"\n\n# If monitoring shows issues after deployment\nspecular auto rollback auto-1762811730 --to step-5  # Keep first 5 steps\n```\n\n**4. Development Iteration**\n\nExperiment with AI-generated changes safely:\n\n```bash\n# Generate changes\nspecular auto --save-patches \"Add user profiles feature\"\n\n# Review changes\ngit diff\n\n# Keep or rollback\nspecular auto rollback auto-1762811730 --all  # or keep with git commit\n```\n\n### Programmatic Patch Access\n\nRead and analyze patches programmatically:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"os\"\n    \"path/filepath\"\n\n    \"github.com/felixgeelhaar/specular/internal/patch\"\n)\n\nfunc main() {\n    homeDir, _ := os.UserHomeDir()\n    patchDir := filepath.Join(homeDir, \".specular\", \"patches\")\n\n    writer := patch.NewWriter(patchDir)\n\n    // List all patches for a workflow\n    patches, err := writer.ListPatches(\"auto-1762811730\")\n    if err != nil {\n        fmt.Printf(\"Error: %v\\n\", err)\n        return\n    }\n\n    // Analyze patches\n    totalFiles := 0\n    totalInsertions := 0\n    totalDeletions := 0\n\n    for _, p := range patches {\n        totalFiles += p.FilesChanged\n        totalInsertions += p.Insertions\n        totalDeletions += p.Deletions\n\n        fmt.Printf(\"%s: %d files, +%d -%d\\n\",\n            p.StepID, p.FilesChanged, p.Insertions, p.Deletions)\n    }\n\n    fmt.Printf(\"\\nTotal impact: %d files, +%d -%d\\n\",\n        totalFiles, totalInsertions, totalDeletions)\n}\n```\n\n### Patches vs Git\n\n| Feature | Patches | Git |\n|---------|---------|-----|\n| Granularity | Per-step recovery | Per-commit recovery |\n| Speed | Instant rollback | Requires git operations |\n| Scope | Auto mode only | Entire repository |\n| History | Temporary (per workflow) | Permanent version control |\n| Use Case | Quick recovery during development | Long-term version management |\n\n**Best Practices:**\n\n1. **Use both**: Patches for immediate recovery, Git for permanent history\n2. **Enable in CI/CD**: Always use `--save-patches` in automated environments\n3. **Clean up old patches**: Patches accumulate in `~/.specular/patches/`, clean periodically\n4. **Test rollback**: Use `--dry-run` to verify safety before rolling back\n5. **Document decisions**: If you roll back, document why in commit messages\n6. **Combine with checkpoints**: Use `--resume` to restart after rollback\n\n### Troubleshooting\n\n**Patches not being generated?**\n\n```bash\n# Verify --save-patches flag is set\nspecular auto --save-patches --verbose \"your goal\"\n\n# Check patch directory exists\nls ~/.specular/patches/\n\n# Verify disk space\ndf -h ~/.specular/\n```\n\n**Rollback warnings about modified files?**\n\nThis means files changed after the patch was created. Options:\n\n1. Use `--dry-run` to see what would change\n2. Manually merge changes if needed\n3. Use git to save current state before rollback\n4. Proceed anyway if you understand the risks\n\n**Can't find workflow ID?**\n\n```bash\n# List recent workflows\nls ~/.specular/patches/ | grep \"^auto-\" | cut -d_ -f1-2 | sort -u\n\n# Or check checkpoint logs\nspecular checkpoint list\n```\n\n## Cryptographic Attestations\n\nSpecular can generate cryptographic attestations of workflow executions, providing verifiable proof of what was executed, by whom, and with what results. Attestations enable compliance, auditability, and trust in AI-assisted development workflows.\n\n### What are Attestations?\n\nAn attestation is a cryptographically signed document that captures:\n- **Workflow metadata**: Goal, status, duration, timestamps\n- **Provenance data**: Who ran it, where, with which version, git context\n- **Execution proof**: Hashes of the plan and output for tamper detection\n- **Digital signature**: ECDSA signature proving authenticity\n\nAttestations follow SLSA (Supply Chain Levels for Software Artifacts) principles for software supply chain security.\n\n### Generating Attestations\n\nEnable attestation generation with the `--attest` flag:\n\n```bash\n# Generate attestation for workflow\nspecular auto --attest --json \"Deploy API v2.0\"\n\n# Attestation saved to: ~/.specular/attestations/auto-1705315200.attestation.json\n```\n\nAttestations are saved to:\n- `\u003coutput-dir\u003e/\u003cworkflow-id\u003e.attestation.json` if `--output` is specified\n- `~/.specular/attestations/\u003cworkflow-id\u003e.attestation.json` otherwise\n\n### Attestation Format\n\n```json\n{\n  \"version\": \"1.0\",\n  \"workflowId\": \"auto-1705315200\",\n  \"goal\": \"Deploy API v2.0\",\n  \"startTime\": \"2024-01-15T10:00:00Z\",\n  \"endTime\": \"2024-01-15T10:19:00Z\",\n  \"duration\": \"19m0s\",\n  \"status\": \"completed\",\n  \"provenance\": {\n    \"hostname\": \"ci-runner-01\",\n    \"platform\": \"linux\",\n    \"arch\": \"amd64\",\n    \"gitRepo\": \"https://github.com/org/project.git\",\n    \"gitCommit\": \"abc123def456...\",\n    \"gitBranch\": \"main\",\n    \"gitDirty\": false,\n    \"specularVersion\": \"v1.5.0\",\n    \"profile\": \"ci\",\n    \"models\": [],\n    \"totalCost\": 2.45,\n    \"tasksExecuted\": 12,\n    \"tasksFailed\": 0\n  },\n  \"planHash\": \"sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\",\n  \"outputHash\": \"sha256:60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752\",\n  \"signedAt\": \"2024-01-15T10:19:05Z\",\n  \"signedBy\": \"ci-bot@example.com\",\n  \"signature\": \"MEUCIQDXvW...\",\n  \"publicKey\": \"MFkwEwYHKoZ...\"\n}\n```\n\n### Verifying Attestations\n\nVerify attestation signature and provenance:\n\n```bash\n# Basic verification\nspecular auto verify ~/.specular/attestations/auto-1705315200.attestation.json\n\n# Strict verification with options\nspecular auto verify attestation.json \\\n  --max-age 24h \\\n  --require-clean-git \\\n  --allowed-identity ci-bot@example.com\n\n# Verify with hash checking\nspecular auto verify attestation.json \\\n  --verify-hashes \\\n  --plan plan.json \\\n  --output output.json\n```\n\n**Verification Output:**\n\n```\n🔍 Verifying attestation: attestation.json\n\n📋 Attestation Information:\n   Version:     1.0\n   Workflow ID: auto-1705315200\n   Goal:        Deploy API v2.0\n   Status:      completed\n   Duration:    19m0s\n   Signed by:   ci-bot@example.com\n   Signed at:   2024-01-15T10:19:05Z\n\n🖥️  Provenance:\n   Hostname: ci-runner-01\n   Platform: linux/amd64\n   Specular: v1.5.0\n   Profile:  ci\n   Git:      https://github.com/org/project.git@abc123de\n   Cost:     $2.4500\n   Tasks:    12 executed, 0 failed\n\n🔐 Verifying signature...\n✅ Signature valid\n\n📊 Verifying provenance...\n✅ Provenance valid\n\n🎉 Attestation verified successfully!\n```\n\n### Verification Options\n\n**`--max-age \u003cduration\u003e`**: Reject attestations older than specified duration\n```bash\nspecular auto verify attestation.json --max-age 24h\n```\n\n**`--require-clean-git`**: Require clean git working tree (no uncommitted changes)\n```bash\nspecular auto verify attestation.json --require-clean-git\n```\n\n**`--allowed-identity \u003cemail\u003e`**: Restrict to specific signer identities\n```bash\nspecular auto verify attestation.json \\\n  --allowed-identity ci-bot@example.com \\\n  --allowed-identity alice@example.com\n```\n\n**`--verify-hashes`**: Verify plan and output hashes match\n```bash\nspecular auto verify attestation.json \\\n  --verify-hashes \\\n  --plan spec-plan.json \\\n  --output auto-output.json\n```\n\n### CI/CD Integration\n\n**GitHub Actions - Generate Attestation:**\n\n```yaml\nname: Deploy with Attestation\non: [push]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n\n      - name: Run Specular Auto with Attestation\n        run: |\n          specular auto --attest --json --profile ci \"Deploy to production\" \u003e output.json\n\n      - name: Upload Attestation\n        uses: actions/upload-artifact@v3\n        with:\n          name: attestation\n          path: ~/.specular/attestations/*.attestation.json\n          retention-days: 90\n```\n\n**GitHub Actions - Verify Attestation:**\n\n```yaml\nname: Verify Deployment\non: [workflow_dispatch]\n\njobs:\n  verify:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Download Attestation\n        uses: actions/download-artifact@v3\n        with:\n          name: attestation\n\n      - name: Verify Attestation\n        run: |\n          specular auto verify *.attestation.json \\\n            --max-age 7d \\\n            --require-clean-git \\\n            --allowed-identity ci-bot\n```\n\n**GitLab CI - Attestation Pipeline:**\n\n```yaml\nstages:\n  - deploy\n  - verify\n\ndeploy:\n  stage: deploy\n  script:\n    - specular auto --attest --json --profile ci \"Deploy application\"\n  artifacts:\n    paths:\n      - ~/.specular/attestations/*.attestation.json\n    expire_in: 3 months\n\nverify:\n  stage: verify\n  script:\n    - specular auto verify ~/.specular/attestations/*.attestation.json --max-age 1h\n  dependencies:\n    - deploy\n```\n\n### Compliance Use Cases\n\n**1. Audit Trail for Regulatory Compliance**\n\nAttestations provide immutable proof of:\n- Who executed the workflow (identity)\n- What was executed (goal, plan hash)\n- When it was executed (timestamps)\n- Where it was executed (hostname, platform)\n- What the results were (output hash, status)\n\n**2. Supply Chain Security (SLSA)**\n\nAttestations enable SLSA Level 2+ compliance by providing:\n- Build provenance tracking\n- Cryptographic verification of artifacts\n- Tamper-evident execution logs\n- Git commit linkage for source tracking\n\n**3. Change Control Gates**\n\nRequire attestation verification before production deployment:\n\n```bash\n#!/bin/bash\n# Pre-deployment verification script\n\nATTESTATION=$(ls -t ~/.specular/attestations/*.attestation.json | head -1)\n\nif ! specular auto verify \"$ATTESTATION\" \\\n     --max-age 1h \\\n     --require-clean-git \\\n     --allowed-identity deploy-bot; then\n  echo \"❌ Attestation verification failed - blocking deployment\"\n  exit 1\nfi\n\necho \"✅ Attestation verified - proceeding with deployment\"\n# ... deployment steps ...\n```\n\n**4. Security Incident Response**\n\nAfter a security incident, attestations provide forensic evidence:\n- Which workflows were affected\n- What changes were made\n- Who initiated the changes\n- Whether any unauthorized modifications occurred\n\n### Attestation Security Model\n\n**Signing:**\n- Uses ECDSA (Elliptic Curve Digital Signature Algorithm) with P-256 curve\n- Ephemeral key pairs generated per workflow execution\n- Signature covers all attestation fields except signature itself\n- Base64-encoded signature and public key included in attestation\n\n**Verification:**\n- Verifies ECDSA signature using embedded public key\n- Checks attestation age (optional)\n- Validates signer identity (optional)\n- Verifies provenance data integrity\n- Optionally verifies plan and output hashes\n\n**Threat Model:**\n- **Protects against**: Tampering with attestation data, unauthorized workflow execution claims, post-execution data modification\n- **Does not protect against**: Compromised signing keys, malicious code in the workflow itself, infrastructure compromise during execution\n\n**Future Enhancements:**\n- Sigstore integration for keyless signing with OIDC\n- Rekor transparency log for public attestation storage\n- Hardware security module (HSM) support for signing\n- Certificate-based identity verification\n\n### Programmatic Attestation Verification\n\n**Go:**\n\n```go\nimport \"github.com/felixgeelhaar/specular/internal/attestation\"\n\n// Read attestation\ndata, _ := os.ReadFile(\"attestation.json\")\natt, _ := attestation.FromJSON(data)\n\n// Create verifier with options\nverifier := attestation.NewStandardVerifier(\n    attestation.WithMaxAge(24 * time.Hour),\n    attestation.WithRequireGitClean(true),\n    attestation.WithAllowedIdentities([]string{\"ci-bot@example.com\"}),\n)\n\n// Verify signature\nif err := verifier.Verify(att); err != nil {\n    log.Fatalf(\"Signature verification failed: %v\", err)\n}\n\n// Verify provenance\nif err := verifier.VerifyProvenance(att); err != nil {\n    log.Fatalf(\"Provenance verification failed: %v\", err)\n}\n\n// Verify hashes (if plan and output available)\nplanJSON, _ := os.ReadFile(\"plan.json\")\noutputJSON, _ := os.ReadFile(\"output.json\")\nif err := verifier.VerifyHashes(att, planJSON, outputJSON); err != nil {\n    log.Fatalf(\"Hash verification failed: %v\", err)\n}\n\nfmt.Println(\"✅ Attestation verified successfully!\")\n```\n\n**Python:**\n\n```python\nimport json\nimport subprocess\nimport sys\n\n# Verify using CLI\nresult = subprocess.run(\n    [\"specular\", \"auto\", \"verify\", \"attestation.json\",\n     \"--max-age\", \"24h\",\n     \"--require-clean-git\"],\n    capture_output=True,\n    text=True\n)\n\nif result.returncode != 0:\n    print(f\"❌ Verification failed: {result.stderr}\")\n    sys.exit(1)\n\n# Parse attestation for metadata\nwith open(\"attestation.json\") as f:\n    attestation = json.load(f)\n\nprint(f\"✅ Verified workflow: {attestation['goal']}\")\nprint(f\"   Executed by: {attestation['signedBy']}\")\nprint(f\"   Status: {attestation['status']}\")\nprint(f\"   Cost: ${attestation['provenance']['totalCost']:.4f}\")\n```\n\n### Best Practices\n\n1. **Always verify attestations** before trusting execution results in production\n2. **Set max-age limits** appropriate for your workflow cadence (e.g., 1h for deployments)\n3. **Require clean git** for production workflows to ensure reproducibility\n4. **Restrict signer identities** to known service accounts or authorized users\n5. **Verify hashes** when you have the original plan and output files\n6. **Store attestations securely** with appropriate retention policies\n7. **Archive attestations** for compliance and audit trail requirements\n8. **Monitor attestation generation failures** as they may indicate security issues\n\n## Routing Explanation\n\nThe `specular explain` command provides detailed insights into routing decisions made during workflow execution. This helps you understand why specific models and providers were selected, optimize your routing strategy, and debug unexpected behavior.\n\n### What does Explain show?\n\nThe explain command analyzes completed workflows and provides:\n- **Provider and model selection** for each step\n- **Cost breakdown** by provider and model\n- **Routing rationale** - why specific selections were made\n- **Budget utilization** - how much of your budget was consumed\n- **Performance metrics** - latency and duration per step\n- **Alternative candidates** - what other options were considered\n\n### Basic Usage\n\n```bash\n# Explain routing for a completed workflow\nspecular explain auto-1762811730\n\n# Output:\n# 🔍 Analyzing routing decisions for workflow: auto-1762811730\n#\n# 🔍 Routing Explanation\n# ========================================================================\n#\n# Workflow ID: auto-1762811730\n# Goal:        Deploy API service\n# Profile:     production\n# Completed:   2025-01-11 14:30:00\n#\n# 📋 Routing Strategy\n# ------------------------------------------------------------------------\n#   Budget Limit:      $10.00\n#   Prefer Cheap:      true\n#   Max Latency:       5000ms\n#   Fallback Enabled:  true\n#   Provider Order:    anthropic → openai → google\n```\n\n### Output Formats\n\nThe explain command supports multiple output formats:\n\n#### Text Format (default)\n\nHuman-readable format with colored output:\n\n```bash\nspecular explain auto-1762811730 --format text\n```\n\n#### JSON Format\n\nMachine-readable JSON for programmatic analysis:\n\n```bash\nspecular explain auto-1762811730 --format json\n\n# Output:\n# {\n#   \"workflowId\": \"auto-1762811730\",\n#   \"goal\": \"Deploy API service\",\n#   \"profile\": \"production\",\n#   \"strategy\": {\n#     \"budgetLimit\": 10.0,\n#     \"preferCheap\": true,\n#     \"maxLatency\": 5000,\n#     \"fallbackEnabled\": true,\n#     \"providerPreferences\": [\"anthropic\", \"openai\", \"google\"]\n#   },\n#   \"steps\": [...]\n# }\n```\n\n#### Markdown Format\n\nDocumentation-friendly Markdown:\n\n```bash\nspecular explain auto-1762811730 --format markdown \u003e routing-report.md\n```\n\n#### Compact Format\n\nBrief summary for quick overview:\n\n```bash\nspecular explain auto-1762811730 --format compact\n\n# Output:\n# Workflow auto-1762811730 (production)\n# Goal: Deploy API service\n# Cost: $2.4500 | Steps: 8 | Budget: 24.5%\n#\n# Step Routing:\n#   1. spec:generate → anthropic/claude-3-5-sonnet ($0.1200)\n#   2. plan:create → anthropic/claude-3-5-sonnet ($0.0800)\n#   3. exec:task → anthropic/claude-3-5-sonnet ($0.3400)\n#   ...\n```\n\n### Step-by-Step Analysis\n\nEach step shows detailed routing information:\n\n```\n📍 Step-by-Step Routing Decisions\n------------------------------------------------------------------------\n\n1. step-1 (spec:generate)\n   Selected: anthropic/claude-3-5-sonnet\n   Cost:     $0.1200\n   Duration: 2.3s\n   Reason:   Selected based on profile preference and cost optimization\n   Candidates: openai/gpt-4-turbo, google/gemini-pro\n   Signals:\n     - complexity: medium\n     - prefer_provider: anthropic\n     - budget_remaining: $9.88\n\n2. step-2 (plan:create)\n   Selected: anthropic/claude-3-5-sonnet\n   Cost:     $0.0800\n   Duration: 1.8s\n   Reason:   Continued with same provider for consistency\n   ...\n```\n\n### Summary Statistics\n\nThe summary provides aggregate metrics:\n\n```\n📊 Summary\n------------------------------------------------------------------------\n  Total Cost:         $2.4500\n  Steps Executed:     8\n  Avg Latency:        2.1s\n  Budget Utilization: 24.5%\n\n  Provider Breakdown:\n    anthropic:\n      Requests: 6\n      Cost:     $2.1000\n      Models:   claude-3-5-sonnet, claude-3-haiku\n\n    openai:\n      Requests: 2\n      Cost:     $0.3500\n      Models:   gpt-4-turbo\n```\n\n### Use Cases\n\n**1. Cost Optimization**\n\nUnderstand which steps consume the most budget:\n\n```bash\n# Analyze cost distribution\nspecular explain auto-1762811730 --format json | \\\n  jq '.steps[] | {step: .stepId, cost: .cost, provider: .selectedProvider}'\n\n# Find expensive steps\nspecular explain auto-1762811730 --format json | \\\n  jq '.steps[] | select(.cost \u003e 0.5)'\n```\n\n**2. Debugging Routing Behavior**\n\nUnderstand why a specific model was or wasn't selected:\n\n```bash\n# See all routing decisions\nspecular explain auto-1762811730 | grep \"Reason:\"\n\n# Check what alternatives were considered\nspecular explain auto-1762811730 | grep \"Candidates:\"\n```\n\n**3. Profile Tuning**\n\nAnalyze routing patterns to improve profile configuration:\n\n```bash\n# Generate report for multiple workflows\nfor workflow in auto-*; do\n  specular explain $workflow --format compact \u003e\u003e routing-analysis.txt\ndone\n\n# Analyze provider distribution\ngrep \"Provider Breakdown\" -A 10 routing-analysis.txt\n```\n\n**4. Audit and Compliance**\n\nDocument model usage for compliance:\n\n```bash\n# Generate Markdown report for audit trail\nspecular explain auto-1762811730 --format markdown \\\n  --output reports/routing-$(date +%Y%m%d).md\n```\n\n### Programmatic Analysis\n\n**Python Example:**\n\n```python\nimport json\nimport subprocess\n\n# Get routing explanation as JSON\nresult = subprocess.run(\n    [\"specular\", \"explain\", \"auto-1762811730\", \"--format\", \"json\"],\n    capture_output=True,\n    text=True\n)\n\nexplanation = json.loads(result.stdout)\n\n# Analyze cost by provider\nprovider_costs = {}\nfor step in explanation['steps']:\n    provider = step['selectedProvider']\n    cost = step['cost']\n    provider_costs[provider] = provider_costs.get(provider, 0) + cost\n\nprint(\"Cost by Provider:\")\nfor provider, cost in sorted(provider_costs.items(), key=lambda x: x[1], reverse=True):\n    print(f\"  {provider}: ${cost:.4f}\")\n\n# Find steps that exceeded latency threshold\nhigh_latency_steps = [\n    step for step in explanation['steps']\n    if float(step['duration'].rstrip('s')) \u003e 3.0\n]\n\nif high_latency_steps:\n    print(f\"\\n⚠️  {len(high_latency_steps)} steps exceeded 3s latency\")\n```\n\n**Go Example:**\n\n```go\npackage main\n\nimport (\n    \"encoding/json\"\n    \"fmt\"\n    \"os\"\n    \"os/exec\"\n\n    \"github.com/felixgeelhaar/specular/internal/explain\"\n)\n\nfunc main() {\n    // Run explain command\n    cmd := exec.Command(\"specular\", \"explain\", \"auto-1762811730\", \"--format\", \"json\")\n    output, err := cmd.Output()\n    if err != nil {\n        panic(err)\n    }\n\n    // Parse explanation\n    var explanation explain.RoutingExplanation\n    if err := json.Unmarshal(output, \u0026explanation); err != nil {\n        panic(err)\n    }\n\n    // Analyze budget efficiency\n    efficiency := explanation.Summary.TotalCost / float64(explanation.Summary.StepsExecuted)\n    fmt.Printf(\"Average cost per step: $%.4f\\n\", efficiency)\n\n    // Find most expensive step\n    var maxCost float64\n    var maxStep string\n    for _, step := range explanation.Steps {\n        if step.Cost \u003e maxCost {\n            maxCost = step.Cost\n            maxStep = step.StepID\n        }\n    }\n    fmt.Printf(\"Most expensive step: %s ($%.4f)\\n\", maxStep, maxCost)\n}\n```\n\n### Integration with CI/CD\n\n**GitHub Actions - Routing Analysis:**\n\n```yaml\nname: Analyze Routing\non:\n  workflow_run:\n    workflows: [\"Deploy with Specular\"]\n    types: [completed]\n\njobs:\n  analyze:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Get Latest Workflow ID\n        id: workflow\n        run: |\n          WORKFLOW_ID=$(ls -t ~/.specular/checkpoints/ | head -1)\n          echo \"id=$WORKFLOW_ID\" \u003e\u003e $GITHUB_OUTPUT\n\n      - name: Generate Routing Report\n        run: |\n          specular explain ${{ steps.workflow.outputs.id }} \\\n            --format markdown \\\n            --output routing-report.md\n\n      - name: Analyze Costs\n        run: |\n          COST=$(specular explain ${{ steps.workflow.outputs.id }} --format json | \\\n                 jq -r '.summary.totalCost')\n\n          if (( $(echo \"$COST \u003e 5.0\" | bc -l) )); then\n            echo \"⚠️ High cost detected: \\$$COST\"\n            exit 1\n          fi\n\n      - name: Upload Report\n        uses: actions/upload-artifact@v3\n        with:\n          name: routing-report\n          path: routing-report.md\n```\n\n**Cost Monitoring Script:**\n\n```bash\n#!/bin/bash\n# monitor-routing-costs.sh\n\nTHRESHOLD=5.0\n\n# Get latest completed workflow\nWORKFLOW_ID=$(ls -t ~/.specular/checkpoints/ | grep \"^auto-\" | head -1)\n\nif [ -z \"$WORKFLOW_ID\" ]; then\n  echo \"No workflows found\"\n  exit 0\nfi\n\n# Get cost from explanation\nCOST=$(specular explain \"$WORKFLOW_ID\" --format json | \\\n       jq -r '.summary.totalCost')\n\necho \"Workflow: $WORKFLOW_ID\"\necho \"Total Cost: \\$$COST\"\n\n# Check threshold\nif (( $(echo \"$COST \u003e $THRESHOLD\" | bc -l) )); then\n  echo \"⚠️  Cost exceeds threshold of \\$$THRESHOLD\"\n\n  # Generate detailed report\n  specular explain \"$WORKFLOW_ID\" --format text \u003e cost-alert-$WORKFLOW_ID.txt\n\n  # Send alert (example with Slack)\n  curl -X POST \"$SLACK_WEBHOOK_URL\" \\\n    -H 'Content-Type: application/json' \\\n    -d \"{\n      \\\"text\\\": \\\"🚨 High routing cost detected\\\",\n      \\\"attachments\\\": [{\n        \\\"text\\\": \\\"Workflow $WORKFLOW_ID cost \\$$COST (threshold: \\$$THRESHOLD)\\\"\n      }]\n    }\"\n\n  exit 1\nfi\n\necho \"✅ Cost within threshold\"\n```\n\n### Best Practices\n\n1. **Analyze after every workflow** - Generate explanations to understand routing patterns\n2. **Set cost thresholds** - Monitor for unexpected cost increases\n3. **Compare routing strategies** - Test different profiles and compare results\n4. **Document routing decisions** - Use Markdown format for audit trails\n5. **Automate cost monitoring** - Integrate with CI/CD for continuous monitoring\n6. **Review provider distribution** - Ensure routing matches your strategy\n7. **Optimize based on insights** - Use explanation data to improve profiles\n\n### Troubleshooting\n\n**Command not found?**\n\n```bash\n# Verify specular is installed\nspecular --version\n\n# Check if explain command exists\nspecular explain --help\n```\n\n**Checkpoint not found?**\n\n```bash\n# List available checkpoints\nls ~/.specular/checkpoints/\n\n# Verify checkpoint ID format\nspecular checkpoint list\n```\n\n**Empty or incomplete explanation?**\n\nThe explain command requires completed workflows with routing metadata. Ensure:\n- Workflow completed successfully\n- Checkpoint data was saved\n- Router was configured with tracking enabled\n\n## Hooks System\n\nThe hooks system enables lifecycle notifications and integrations with external services. Hooks execute automatically at workflow events, allowing you to integrate Specular with notification systems, webhooks, logging platforms, and custom automation.\n\n### What are Hooks?\n\nHooks are event-driven callbacks that trigger at specific points during workflow execution:\n\n- **Workflow Events** - Start, completion, failure\n- **Plan Events** - Plan creation, approval, rejection\n- **Step Events** - Before/after step execution, step failures\n- **Policy Events** - Policy violations\n- **Drift Events** - Configuration drift detection\n\n### Built-in Hook Types\n\nSpecular provides three built-in hook types:\n\n#### 1. Script Hooks\n\nExecute shell scripts with event data passed as environment variables.\n\n```yaml\nhooks:\n  on_workflow_complete:\n    - type: script\n      config:\n        script: /path/to/notify.sh\n        shell: /bin/bash\n        args: [\"--verbose\"]\n```\n\nEnvironment variables provided to scripts:\n- `HOOK_EVENT_TYPE` - Event type (e.g., `on_workflow_complete`)\n- `HOOK_WORKFLOW_ID` - Workflow identifier\n- `HOOK_\u003cKEY\u003e` - Event-specific data (uppercase)\n\nExample script (`notify.sh`):\n```bash\n#!/bin/bash\necho \"Workflow $HOOK_WORKFLOW_ID completed\"\necho \"Event: $HOOK_EVENT_TYPE\"\necho \"Duration: $HOOK_DURATION\"\necho \"Cost: $HOOK_COST\"\n```\n\n#### 2. Webhook Hooks\n\nSend HTTP POST requests to external APIs with JSON event payloads.\n\n```yaml\nhooks:\n  on_step_after:\n    - type: webhook\n      config:\n        url: https://api.example.com/webhooks/specular\n        headers:\n          Authorization: Bearer ${WEBHOOK_TOKEN}\n          X-Source: specular\n```\n\nWebhook payload format:\n```json\n{\n  \"type\": \"on_step_after\",\n  \"timestamp\": \"2025-01-15T10:30:00Z\",\n  \"workflowId\": \"workflow-123\",\n  \"data\": {\n    \"stepId\": \"step-001\",\n    \"stepType\": \"build\",\n    \"cost\": 0.05,\n    \"duration\": \"2m15s\"\n  }\n}\n```\n\n#### 3. Slack Hooks\n\nSend formatted notifications to Slack channels.\n\n```yaml\nhooks:\n  on_workflow_failed:\n    - type: slack\n      config:\n        webhookUrl: https://hooks.slack.com/services/YOUR/WEBHOOK/URL\n        channel: \"#deployments\"\n        username: \"Specular Bot\"\n        iconEmoji: \":robot_face:\"\n```\n\nSlack messages are automatically formatted based on event type:\n- **Workflow Start** - 🚀 Workflow started notification\n- **Workflow Complete** - ✅ Success with duration and cost\n- **Workflow Failed** - ❌ Failure with error details\n- **Step Events** - ▶️ Step execution status updates\n- **Policy Violations** - 🚫 Policy violation alerts\n\n### Configuring Hooks in Profiles\n\nAdd hooks to your profile configuration (`~/.specular/profiles.yaml`):\n\n```yaml\nprofiles:\n  production:\n    description: Production deployment profile\n    hooks:\n      # Notify on workflow start\n      on_workflow_start:\n        - type: slack\n          config:\n            webhookUrl: ${SLACK_WEBHOOK_URL}\n            channel: \"#deployments\"\n\n      # Log all steps to webhook\n      on_step_after:\n        - type: webhook\n          config:\n            url: https://logs.example.com/api/events\n            headers:\n              Authorization: Bearer ${LOG_API_TOKEN}\n\n      # Alert on failures\n      on_workflow_failed:\n        - type: slack\n          config:\n            webhookUrl: ${SLACK_WEBHOOK_URL}\n            channel: \"#alerts\"\n        - type: script\n          config:\n            script: /path/to/alert-oncall.sh\n\n      # Success notification with metrics\n      on_workflow_complete:\n        - type: slack\n          config:\n            webhookUrl: ${SLACK_WEBHOOK_URL}\n            channel: \"#deployments\"\n```\n\n### Using Environment Variables\n\nUse environment variables for sensitive configuration:\n\n```bash\n# Set webhook URLs and tokens\nexport SLACK_WEBHOOK_URL=\"https://hooks.slack.com/services/YOUR/WEBHOOK/URL\"\nexport LOG_API_TOKEN=\"your-api-token\"\nexport WEBHOOK_TOKEN=\"your-webhook-token\"\n\n# Run with profile that uses these variables\nspecular auto --profile production \"deploy to staging\"\n```\n\n### Hook Execution Behavior\n\n**Concurrency**: Hooks execute concurrently with a default limit of 10 concurrent executions. This ensures fast notification delivery without overwhelming external services.\n\n**Timeouts**: Each hook has a default timeout of 30 seconds. Hooks that exceed this timeout are terminated.\n\n**Failure Modes**: Configure how hook failures are handled:\n\n```yaml\nhooks:\n  on_step_after:\n    - type: webhook\n      config:\n        url: https://api.example.com/webhooks\n        failureMode: ignore  # Options: ignore, warn, fail\n```\n\n- **ignore** - Log failure at debug level, continue workflow\n- **warn** - Log warning, continue workflow\n- **fail** - Abort workflow on hook failure (default for critical hooks)\n\n### Event Data Reference\n\nDifferent event types provide different data:\n\n**Workflow Events** (`on_workflow_start`, `on_workflow_complete`, `on_workflow_failed`):\n```json\n{\n  \"workflowId\": \"workflow-123\",\n  \"goal\": \"Deploy application\",\n  \"duration\": \"15m30s\",\n  \"cost\": 2.45,\n  \"success\": true,\n  \"error\": \"error message if failed\"\n}\n```\n\n**Plan Events** (`on_plan_created`, `on_plan_approved`, `on_plan_rejected`):\n```json\n{\n  \"workflowId\": \"workflow-123\",\n  \"planId\": \"plan-456\",\n  \"steps\": 12,\n  \"estimatedCost\": 1.50,\n  \"estimatedDuration\": \"10m\"\n}\n```\n\n**Step Events** (`on_step_before`, `on_step_after`, `on_step_failed`):\n```json\n{\n  \"workflowId\": \"workflow-123\",\n  \"stepId\": \"step-001\",\n  \"stepName\": \"Build application\",\n  \"stepType\": \"build\",\n  \"stepIndex\": 0,\n  \"cost\": 0.15,\n  \"duration\": \"2m15s\",\n  \"total_cost\": 2.45,\n  \"error\": \"error message if failed\"\n}\n```\n\n**Policy Events** (`on_policy_violation`):\n```json\n{\n  \"workflowId\": \"workflow-123\",\n  \"policy\": \"max_cost_per_step\",\n  \"reason\": \"Step cost $5.00 exceeds limit $2.00\",\n  \"stepId\": \"step-003\",\n  \"severity\": \"critical\"\n}\n```\n\n### Use Cases\n\n#### 1. CI/CD Integration\n\nIntegrate Specular workflows with CI/CD pipelines:\n\n```yaml\n# GitHub Actions webhook integration\nhooks:\n  on_workflow_complete:\n    - type: webhook\n      config:\n        url: https://api.github.com/repos/owner/repo/statuses/${GIT_COMMIT}\n        headers:\n          Authorization: token ${GITHUB_TOKEN}\n          Accept: application/vnd.github.v3+json\n```\n\n#### 2. Monitoring and Alerting\n\nSend metrics to monitoring systems:\n\n```yaml\nhooks:\n  on_step_after:\n    - type: webhook\n      config:\n        url: https://metrics.example.com/api/v1/metrics\n        headers:\n          X-API-Key: ${METRICS_API_KEY}\n\n  on_workflow_failed:\n    - type: slack\n      config:\n        webhookUrl: ${PAGERDUTY_SLACK_WEBHOOK}\n        channel: \"#incidents\"\n```\n\n#### 3. Cost Tracking\n\nTrack and report workflow costs:\n\n```bash\n#!/bin/bash\n# cost-tracker.sh\necho \"Recording workflow cost: $HOOK_COST USD\"\ncurl -X POST \"https://billing.example.com/api/costs\" \\\n  -H \"Authorization: Bearer $BILLING_TOKEN\" \\\n  -d \"{\\\"workflow\\\": \\\"$HOOK_WORKFLOW_ID\\\", \\\"cost\\\": $HOOK_COST}\"\n```\n\n```yaml\nhooks:\n  on_workflow_complete:\n    - type: script\n      config:\n        script: /path/to/cost-tracker.sh\n```\n\n#### 4. Audit Logging\n\nMaintain comprehensive audit logs:\n\n```yaml\nhooks:\n  on_workflow_start:\n    - type: webhook\n      config:\n        url: https://audit.example.com/api/events\n\n  on_step_before:\n    - type: webhook\n      config:\n        url: https://audit.example.com/api/events\n\n  on_step_after:\n    - type: webhook\n      config:\n        url: https://audit.example.com/api/events\n\n  on_workflow_complete:\n    - type: webhook\n      config:\n        url: https://audit.example.com/api/events\n```\n\n### Programmatic Hook Usage\n\nUse hooks programmatically in Go:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"github.com/felixgeelhaar/specular/internal/hooks\"\n)\n\nfunc main() {\n    // Create registry\n    registry := hooks.NewRegistry()\n\n    // Register built-in hook factories\n    hooks.RegisterBuiltinHooks(registry)\n\n    // Create hook configuration\n    config := \u0026hooks.HookConfig{\n        Name:    \"slack-notifications\",\n        Type:    \"slack\",\n        Events:  []hooks.EventType{hooks.EventWorkflowComplete},\n        Enabled: true,\n        Config: map[string]interface{}{\n            \"webhookUrl\": \"https://hooks.slack.com/services/YOUR/WEBHOOK/URL\",\n            \"channel\":    \"#deployments\",\n        },\n    }\n\n    // Register hook from configuration\n    if err := registry.RegisterFromConfig(config); err != nil {\n        panic(err)\n    }\n\n    // Trigger hook on event\n    event := hooks.NewEvent(\n        hooks.EventWorkflowComplete,\n        \"workflow-123\",\n        map[string]interface{}{\n            \"duration\": \"15m30s\",\n            \"cost\":     2.45,\n        },\n    )\n\n    results := registry.Trigger(context.Background(), event)\n\n    // Check results\n    for _, result := range results {\n        if !result.Success {\n            log.Printf(\"Hook %s failed: %s\", result.HookName, result.Error)\n        }\n    }\n}\n```\n\n### Custom Hook Implementation\n\nImplement custom hooks by satisfying the `Hook` interface:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"github.com/felixgeelhaar/specular/internal/hooks\"\n)\n\n// CustomHook sends notifications via custom protocol\ntype CustomHook struct {\n    name       string\n    eventTypes []hooks.EventType\n    enabled    bool\n    apiKey     string\n}\n\nfunc (h *CustomHook) Name() string {\n    return h.name\n}\n\nfunc (h *CustomHook) EventTypes() []hooks.EventType {\n    return h.eventTypes\n}\n\nfunc (h *CustomHook) Enabled() bool {\n    return h.enabled\n}\n\nfunc (h *CustomHook) Execute(ctx context.Context, event *hooks.Event) error {\n    // Implement custom notification logic\n    fmt.Printf(\"Sending notification for %s\\n\", event.Type)\n\n    // Extract event data\n    workflowID := event.WorkflowID\n    eventType := event.Type\n\n    // Send to custom API\n    // ... implementation ...\n\n    return nil\n}\n\n// Factory function\nfunc NewCustomHook(config *hooks.HookConfig) (hooks.Hook, error) {\n    apiKey, ok := config.Config[\"apiKey\"].(string)\n    if !ok {\n        return nil, fmt.Errorf(\"apiKey required\")\n    }\n\n    return \u0026CustomHook{\n        name:       config.Name,\n        eventTypes: config.Events,\n        enabled:    config.Enabled,\n        apiKey:     apiKey,\n    }, nil\n}\n\nfunc main() {\n    // Register custom hook factory\n    registry := hooks.NewRegistry()\n    registry.RegisterFactory(\"custom\", NewCustomHook)\n\n    // Use in configuration\n    config := \u0026hooks.HookConfig{\n        Name:   \"custom-notifier\",\n        Type:   \"custom\",\n        Events: []hooks.EventType{hooks.EventWorkflowComplete},\n        Config: map[string]interface{}{\n            \"apiKey\": \"your-api-key\",\n        },\n    }\n\n    registry.RegisterFromConfig(config)\n}\n```\n\n### Best Practices\n\n1. **Use Environment Variables for Secrets**\n   - Never commit webhook URLs or API tokens to version control\n   - Use `${VAR}` syntax in YAML configurations\n   - Set environment variables before running workflows\n\n2. **Choose Appropriate Failure Modes**\n   - Use `ignore` for non-critical notifications\n   - Use `warn` for important but non-blocking hooks\n   - Use `fail` only for critical integrations\n\n3. **Minimize Hook Latency**\n   - Keep script execution under 5 seconds\n   - Use asynchronous webhooks where possible\n   - Avoid complex processing in hook handlers\n\n4. **Test Hooks Independently**\n   - Test webhook URLs with curl before configuration\n   - Verify script execution with sample data\n   - Check Slack webhook formatting\n\n5. **Monitor Hook Performance**\n   - Review hook execution durations in logs\n   - Set appropriate timeouts for external services\n   - Use failure modes to prevent workflow delays\n\n6. **Organize Hooks by Environment**\n   - Create separate profiles for dev/staging/production\n   - Use different notification channels per environment\n   - Adjust verbosity based on environment criticality\n\n7. **Document Hook Configurations**\n   - Comment webhook URLs with their purpose\n   - Document expected environment variables\n   - Include examples of event data structure\n\n### Troubleshooting\n\n**Hook not executing?**\n\nCheck the hook configuration and event type:\n\n```bash\n# Verify hooks are registered for the event\n# Look for hook execution in logs\nspecular auto --verbose \"your goal\"\n\n# Check profile configuration\ncat ~/.specular/profiles.yaml\n```\n\n**Webhook timing out?**\n\nIncrease the timeout in hook configuration:\n\n```yaml\nhooks:\n  on_workflow_complete:\n    - type: webhook\n      config:\n        url: https://slow-api.example.com/webhooks\n        timeout: 60s  # Increase from default 30s\n```\n\n**Script failing silently?**\n\nAdd error output and logging:\n\n```bash\n#!/bin/bash\nset -e  # Exit on error\nset -x  # Print commands\n\necho \"Hook executing: $HOOK_EVENT_TYPE\" \u003e\u00262\n# ... rest of script ...\n```\n\n**Slack messages not formatted?**\n\nVerify webhook URL and test with curl:\n\n```bash\ncurl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"text\": \"Test message from Specular\"}'\n```\n\n**Missing event data?**\n\nCheck available data for your event type in the Event Data Reference section. Not all events provide the same data fields.\n\n## Advanced Security\n\nSpecular provides enterprise-grade security features including secure credential management, comprehensive audit logging, and automatic secret scanning. These features help maintain security compliance, prevent credential leaks, and provide audit trails for regulatory requirements.\n\n### Credential Management\n\nThe credential store provides secure, encrypted storage for sensitive credentials with automatic rotation support.\n\n#### Features\n\n- **AES-GCM Encryption** - Military-grade encryption using AES-256-GCM\n- **PBKDF2 Key Derivation** - Secure master key derivation from passphrase\n- **Automatic Rotation** - Policy-based credential rotation with tracking\n- **Expiration Support** - Set expiration dates for temporary credentials\n- **Thread-Safe Operations** - Concurrent-safe credential access\n- **Metadata Tracking** - Additional context for each credential\n\n#### Basic Usage\n\n```go\npackage main\n\nimport (\n    \"time\"\n    \"github.com/felixgeelhaar/specular/internal/security\"\n)\n\nfunc main() {\n    // Create credential store\n    store, err := security.NewCredentialStore(\n        \"/path/to/credentials.json\",\n        \"your-secure-passphrase\",\n    )\n    if err != nil {\n        panic(err)\n    }\n\n    // Store a credential\n    expiresAt := time.Now().Add(90 * 24 * time.Hour) // 90 days\n    rotationPolicy := \u0026security.RotationPolicy{\n        Enabled:      true,\n        IntervalDays: 30,\n        LastRotated:  time.Now(),\n    }\n\n    err = store.Store(\"github-token\", \"ghp_abc123...\", \u0026expiresAt, rotationPolicy)\n    if err != nil {\n        panic(err)\n    }\n\n    // Retrieve a credential\n    token, err := store.Get(\"github-token\")\n    if err != nil {\n        panic(err)\n    }\n\n    // Use the credential...\n    _ = token\n\n    // Check which credentials need rotation\n    needsRotation := store.CheckRotation()\n    for _, credName := range needsRotation {\n        // Rotate credential...\n        store.MarkRotated(credName)\n    }\n\n    // List all credentials\n    credentials := store.List()\n    for _, name := range credentials {\n        info, _ := store.GetInfo(name)\n        fmt.Printf(\"Credential: %s (created: %s)\\n\", name, info.CreatedAt)\n    }\n\n    // Delete a credential\n    store.Delete(\"old-credential\")\n}\n```\n\n#### Credential Rotation\n\nImplement automatic credential rotation:\n\n```go\n// Define rotation policy\nrotationPolicy := \u0026security.RotationPolicy{\n    Enabled:      true,\n    IntervalDays: 30,  // Rotate every 30 days\n    LastRotated:  time.Now(),\n}\n\n// Store credential with rotation policy\nstore.Store(\"api-key\", \"your-api-key\", nil, rotationPolicy)\n\n// Periodically check for credentials needing rotation\nfunc checkCredentialRotation(store *security.CredentialStore) {\n    needsRotation := store.CheckRotation()\n\n    for _, credName := range needsRotation {\n        fmt.Printf(\"Credential %s needs rotation\\n\", credName)\n\n        // 1. Generate new credential value\n        newValue := generateNewCredential(credName)\n\n        // 2. Update external service with new credential\n        updateExternalService(credName, newValue)\n\n        // 3. Store new credential value\n        info, _ := store.GetInfo(credName)\n        store.Store(credName, newValue, info.ExpiresAt, info.RotationPolicy)\n\n        // 4. Mark as rotated\n        store.MarkRotated(credName)\n\n        fmt.Printf(\"Credential %s rotated successfully\\n\", credName)\n    }\n}\n```\n\n#### Credential Expiration\n\nSet expiration dates for temporary credentials:\n\n```go\n// Create temporary credential valid for 7 days\nexpiresAt := time.Now().Add(7 * 24 * time.Hour)\nstore.Store(\"temp-token\", \"token-value\", \u0026expiresAt, nil)\n\n// Attempt to retrieve expired credential\ntoken, err := store.Get(\"temp-token\")\nif err != nil {\n    // Will fail if credential has expired\n    fmt.Println(\"Credential has expired\")\n}\n```\n\n### Audit Logging\n\nComprehensive audit logging tracks all security-relevant events with structured JSON logs and daily rotation.\n\n#### Audit Event Types\n\n- **Workflow Events** - Start, completion, failure tracking\n- **Credential Events** - Creation, access, updates, deletion, rotation\n- **Policy Events** - Violations and enforcement actions\n- **Secret Scanning** - Detection and blocking of secrets\n- **Access Events** - Granted and denied access attempts\n\n#### Basic Usage\n\n```go\npackage main\n\nimport (\n    \"time\"\n    \"github.com/felixgeelhaar/specular/internal/security\"\n)\n\nfunc main() {\n    // Create audit logger\n    logger, err := security.NewAuditLogger(\n        \"/var/log/specular/audit\",\n        true, // Enable console logging\n    )\n    if err != nil {\n        panic(err)\n    }\n\n    // Log workflow events\n    logger.LogWorkflowStart(\n        \"workflow-123\",\n        \"Deploy application\",\n        \"production\",\n        \"user@example.com\",\n    )\n\n    // Simulate workflow execution...\n    time.Sleep(2 * time.Second)\n\n    logger.LogWorkflowComplete(\n        \"workflow-123\",\n        \"user@example.com\",\n        2*time.Second,\n        0.45, // Cost in USD\n    )\n\n    // Log credential access\n    logger.LogCredentialAccess(\n        \"github-token\",\n        \"user@example.com\",\n        true, // Success\n    )\n\n    // Log policy violation\n    logger.LogPolicyViolation(\n        \"max_cost_per_step\",\n        \"step-003\",\n        \"system\",\n        \"Step cost $5.00 exceeds limit $2.00\",\n    )\n\n    // Log secret detection\n    logger.LogSecretDetected(\n        \"aws_access_key\",\n        \"src/config.ts:42\",\n        \"user@example.com\",\n        true, // Blocked\n    )\n\n    // Log custom audit event\n    logger.Log(\u0026security.AuditEvent{\n        Type:     security.AuditAccessGranted,\n        Severity: security.SeverityInfo,\n        Actor:    \"user@example.com\",\n        Resource: \"admin-","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelixgeelhaar%2Fspecular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffelixgeelhaar%2Fspecular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelixgeelhaar%2Fspecular/lists"}